first commit

This commit is contained in:
r2xrzh9q2z-lab
2026-02-02 11:07:09 +07:00
commit d1b931d547
286 changed files with 53992 additions and 0 deletions

200
models/bookingSubmission.js Normal file
View File

@@ -0,0 +1,200 @@
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);