const { DEFAULT_TRIAL_DAYS } = require('../helpers/constants'); const mongoose = require('mongoose'), Schema = mongoose.Schema; const schema = new Schema({ userId: { type: Schema.Types.ObjectId, ref: 'User' }, // Global measureUnit, whether isUS measurement unit measureUnit: { type: Boolean, default: false }, jobsByPilot: { type: Boolean, default: false }, matType: { type: Number, default: 0 }, // 0: Liquid, 1: Dry // Spray Path options for spray lines drawing or making Application reports sprayPath: { overlap: { type: Number, min: 10, max: 200, default: 120 }, // Percentage: 10 - 200 dataOp: { type: Number, default: 0 } }, upload: { updateOp: String }, colors: { type: Schema.Types.Mixed }, obstacles: { type: Schema.Types.Mixed }, mapOps: { type: Schema.Types.Mixed }, track: { type: Schema.Types.Mixed }, noPopup: { type: Boolean, default: false }, // Nunber of trial days for Agmission's applicators trialDays: { type: [Number] }, // Subscription promotion rules - controls discounts and coupons by type/price subscriptionPromos: [{ // Matching criteria type: { type: String, enum: ['package', 'addon'] }, // Subscription type to match (null = any) priceKey: { type: String }, // Price lookup key e.g., 'addon_1', 'ess_1' (null = any) // Promo status enabled: { type: Boolean, default: false }, validUntil: { type: Date }, // Last date new/changing subscriptions can apply this promo (eligibility) discountEndsAt: { type: Date }, // When the applied discount expires for existing subscribers (schedule phase end_date). Falls back to validUntil if not set. couponId: { type: String }, // Stripe coupon ID to apply // Precedence and chaining priority: { type: Number, default: 0 }, // Higher number = higher priority in matching chainable: { type: Boolean, default: false }, // Can chain to next promo when expired // Coupon duration support durationInMonths: { type: Number }, // null/undefined = forever, number = repeating X months // Customer eligibility eligibility: { type: String, enum: Object.values(require('../helpers/constants').PromoEligibility), default: require('../helpers/constants').PromoEligibility.ALL }, // Display (fallback) name: { type: String }, // Fallback display name // i18n support (SCREAMING_SNAKE keys) nameKey: { type: String }, // Translation key e.g., 'PROMO_ADDON_FREE' descriptionKey: { type: String }, // Translation key e.g., 'PROMO_ADDON_FREE_DESC' // Discount info (for UI display) discountType: { type: String, enum: ['free', 'percent', 'fixed'] }, // Type of discount discountValue: { type: Number }, // 100 for free, 50 for 50%, 500 for $5 off (cents) // Usage tracking usageCount: { type: Number, default: 0 }, // Number of subscriptions using this promo createdAt: { type: Date, default: Date.now } }] }); schema.post('save', function (doc) { if (!this.trialDays || this.trialDays.length) this.trialDays = DEFAULT_TRIAL_DAYS; }); module.exports = mongoose.model('Setting', schema);