Skip to content

Instantly share code, notes, and snippets.

@dominwong4
Last active May 24, 2025 05:02
Show Gist options
  • Save dominwong4/48971232e2141b51552ef6fdd26fd6a9 to your computer and use it in GitHub Desktop.
Save dominwong4/48971232e2141b51552ef6fdd26fd6a9 to your computer and use it in GitHub Desktop.
// The following schema is auto-generated.
// This file contains FSL for FQL10-compatible schema items.
collection GeneralSetting {
history_days 30
}
collection Student {
history_days 30
index byEmailAndSub {
terms [.email, .sub]
}
index byPhoneNumber {
terms [.phone_number]
}
index byVip {
terms [.vip]
}
index byVvip {
terms [.vvip]
}
}
collection Course {
history_days 30
index byTerm {
terms [.term]
}
}
collection Class {
history_days 30
index byCourse {
terms [.course]
}
}
collection Classroom {
history_days 30
}
collection course_students {
history_days 30
index byStudent {
terms [.studentID]
values [desc(.ts)]
}
index byStudentAndTerm {
terms [.studentID, .termID]
values [desc(.ts)]
}
index byCourse {
terms [.courseID]
values [desc(.ts)]
}
}
collection Term {
history_days 30
index byStatus {
terms [.status]
}
}
collection class_attendees {
history_days 30
}
collection Teacher {
history_days 30
}
collection DiscountGroup {
history_days 30
}
collection Order {
history_days 30
index byStudent {
terms [.student]
values [.student]
}
}
collection Log {
history_days 30
index all_logs_by_source {
terms [.from]
values [desc(.date)]
}
index all_logs_by_target {
terms [.to]
values [desc(.date)]
}
}
collection AttendanceTicket {
history_days 30
index AttendanceTicketByStudent {
terms [.student]
values [desc(.date)]
}
index ByStudentAndClass {
terms [.student, .session]
values [desc(.date)]
}
index ByClass {
terms [.session]
values [desc(.date)]
}
}
collection Notification {
history_days 0
}
collection Notication {
history_days 0
}
collection PerformanceTerm {
history_days 0
}
collection Performance {
history_days 0
index byDeleted {
terms [.deleted]
}
}
collection PerformanceDay {
history_days 0
}
collection performance_performers {
history_days 0
index byStudent {
terms [.studentID]
}
index byStudentAndPerformance {
terms [.studentID, .performanceID]
}
}
function insertStudentToPerformance(performanceId) {
let p = Performance(performanceId)
let student = Student(Query.identity()!.id)
let term = p!.performance_term
let joined = performance_performers.byStudent(student).where(.performance_day == p!.performance_day && p!.deleted == false)
let numberOfJoined = joined.count()
let price = {
if(numberOfJoined>=1){
0.0
} else {
50.0
}
}
let withInPeriod = (Time.now() >= term.application_start_date && Time.now() <= term.application_end_date)
if (!withInPeriod) {
abort("Not in Application Period")
}
if (p!.quote <= 0) {
abort("Performance quota is 0")
}
if (numberOfJoined >= 3) {
abort("One Student can only apply at most 3 performances in one day")
}
let existed = !performance_performers.byStudentAndPerformance(student, p).isEmpty()
if(existed) {
abort(("Student already in performance"))
}
if (price > student!.credit){
abort("Not Enough credit")
}
performance_performers.create(
{
performance_term: p!.performance_term,
performance_day: p!.performance_day,
performanceID: p,
studentID: student,
paid: price
}
)
p!.updateData({
quota: p!.quota - 1
})
student!.updateData({
credit: student!.credit - price
})
Log.create({
from: student,
to: p,
action: "Paid $#{price}",
date: Time.now()
})
{
status: "success",
message: "Paid $#{price}"
}
}
role StudentV10 {
privileges insertStudentToPerformance {
call
}
membership Student
privileges getFinalCoursePrice {
call
}
privileges applyCourse {
call
}
}
function getFinalCoursePrice(courseId) {
let period = GeneralSetting.all().take(1).first()
let applied_courses = course_students.byStudent(Student(Query.identity()!.id)).where(.ts >= period!.vip_apply_start_date && .ts <= period!.vip_apply_end_date)
let applied_courses_discount_groups = applied_courses {id : .courseID.discount_group.id}
let flated_applied_courses_discount_groups = applied_courses_discount_groups.toArray().map(x=> x.id)
let target_course = Course.byId(courseId)
let numberOfSameDg = flated_applied_courses_discount_groups.filter(arg0 => arg0 == target_course!.discount_group!.id)
let finalIndex = Math.min(numberOfSameDg.length, target_course!.discount_group!.discount_series.length - 1)
let discount = target_course!.discount_group!.discount_series[finalIndex]
let early_discount = {
if (Time.now() <= period!.vip_apply_start_date.add(11, "day").add(3, "hour")){
0.95
} else {
1.0
}
}
let adjusted_price = (target_course!.price - discount) * early_discount
adjusted_price
}
function applyCourse(courseId) {
let student = Student(Query.identity()!.id)
let course = Course(courseId)
let period = GeneralSetting.all().take(1).first()
let adjusted_price = getFinalCoursePrice(courseId)
let withInVipPeriod = Time.now() >= period!.vip_apply_start_date && Time.now() <= period!.vip_apply_end_date
let withInNormalPeriod = Time.now() >= period!.normal_apply_start_date && Time.now() <= period!.normal_apply_end_date
if ((student!.vip == true && withInVipPeriod == false) || (student!.vip == false && withInNormalPeriod == false)){
abort("Not in Application period")
}
if (course!.quota <= 0) {
abort("Course sold out!")
}
if (adjusted_price > student!.credit){
abort("Not enough credit")
}
course!.updateData({
quota: course!.quota - 1
})
student!.updateData({
credit: student!.credit - adjusted_price
})
course_students.create({
courseID: course,
studentID: student,
termID: course!.term
})
let numberOfCoursesJoined = course_students.byStudent(student, {from: period!.vip_apply_end_date, to:period!.vip_apply_start_date }).count()
if(student!.vip == false && numberOfCoursesJoined >= 2) {
student!.updateData({
vip: true
})
}
Log.create({
from: student,
to: course,
action: "Paid $#{adjusted_price} to join",
date: Time.now()
})
Class.byCourse(course).forEach(c => {
AttendanceTicket.create({
course: course,
session: c,
student: student,
date: c.date,
attended: false,
catchup: false
})
})
Order.create({
student: student,
course: course,
term: course!.term,
price: adjusted_price,
date: Time.now()
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment