forked from UKSOURCE/cms.hailearning.edu.vn
200 lines
4.2 KiB
JavaScript
200 lines
4.2 KiB
JavaScript
const mongoose = require("mongoose");
|
|
|
|
// Clear cache
|
|
if (mongoose.models.BookingSubmission) {
|
|
delete mongoose.models.BookingSubmission;
|
|
}
|
|
if (mongoose.connection.models.BookingSubmission) {
|
|
delete mongoose.connection.models.BookingSubmission;
|
|
}
|
|
|
|
const bookingSubmissionSchema = new mongoose.Schema(
|
|
{
|
|
// Liên kết với activity và session
|
|
activityId: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Activity',
|
|
required: true
|
|
},
|
|
sessionId: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
|
|
// Thông tin người đăng ký
|
|
parentFirstName: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
parentLastName: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
email: {
|
|
type: String,
|
|
required: true,
|
|
trim: true,
|
|
lowercase: true
|
|
},
|
|
phone: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
|
|
// Thông tin địa chỉ
|
|
address: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
city: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
country: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
postalCode: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
|
|
// Thông tin người tham gia
|
|
participantFirstName: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
participantLastName: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
participantBirthDate: {
|
|
type: Date,
|
|
required: true
|
|
},
|
|
participantGender: {
|
|
type: String,
|
|
enum: ['male', 'female', 'other'],
|
|
required: true
|
|
},
|
|
numberOfParticipants: {
|
|
type: Number,
|
|
required: true,
|
|
min: 1
|
|
},
|
|
|
|
// Thông tin y tế và đặc biệt
|
|
medicalConditions: {
|
|
type: String,
|
|
trim: true,
|
|
default: ''
|
|
},
|
|
dietaryRestrictions: {
|
|
type: String,
|
|
enum: ['none', 'vegetarian', 'vegan', 'halal', 'kosher', 'gluten-free', 'other'],
|
|
default: 'none'
|
|
},
|
|
specialRequests: {
|
|
type: String,
|
|
trim: true,
|
|
default: ''
|
|
},
|
|
|
|
// Thông tin liên hệ khẩn cấp
|
|
emergencyContact: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
emergencyPhone: {
|
|
type: String,
|
|
required: true,
|
|
trim: true
|
|
},
|
|
|
|
// Điều khoản và thông báo
|
|
agreeTerms: {
|
|
type: Boolean,
|
|
required: true,
|
|
default: false
|
|
},
|
|
agreeNewsletter: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
|
|
// Trạng thái đăng ký
|
|
status: {
|
|
type: String,
|
|
enum: ['pending', 'confirmed', 'cancelled', 'completed'],
|
|
default: 'pending'
|
|
},
|
|
|
|
// Ghi chú admin
|
|
adminNotes: {
|
|
type: String,
|
|
trim: true,
|
|
default: ''
|
|
},
|
|
|
|
// Thông tin thanh toán
|
|
paymentStatus: {
|
|
type: String,
|
|
enum: ['pending', 'partial', 'paid', 'refunded'],
|
|
default: 'pending'
|
|
},
|
|
totalAmount: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
paidAmount: {
|
|
type: Number,
|
|
default: 0
|
|
}
|
|
},
|
|
{
|
|
timestamps: true,
|
|
toJSON: { virtuals: true },
|
|
toObject: { virtuals: true }
|
|
}
|
|
);
|
|
|
|
// Virtual để tính tuổi của participant
|
|
bookingSubmissionSchema.virtual('participantAge').get(function() {
|
|
if (this.participantBirthDate) {
|
|
const today = new Date();
|
|
const birthDate = new Date(this.participantBirthDate);
|
|
let age = today.getFullYear() - birthDate.getFullYear();
|
|
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
|
age--;
|
|
}
|
|
return age;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
// Virtual để lấy thông tin activity
|
|
bookingSubmissionSchema.virtual('activity', {
|
|
ref: 'Activity',
|
|
localField: 'activityId',
|
|
foreignField: '_id',
|
|
justOne: true
|
|
});
|
|
|
|
// Index for better performance
|
|
bookingSubmissionSchema.index({ activityId: 1, sessionId: 1 });
|
|
bookingSubmissionSchema.index({ email: 1 });
|
|
bookingSubmissionSchema.index({ status: 1 });
|
|
bookingSubmissionSchema.index({ createdAt: -1 });
|
|
|
|
module.exports = mongoose.model("BookingSubmission", bookingSubmissionSchema); |