180 lines
5.6 KiB
TypeScript
180 lines
5.6 KiB
TypeScript
import Colle from '#models/colle'
|
|
import { ColleService } from '#services/colle_service'
|
|
import { createColleValidator, createUpcomingCollesValidator } from '#validators/colle'
|
|
import { inject } from '@adonisjs/core'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
import { DateTime } from 'luxon'
|
|
|
|
@inject()
|
|
export default class CollesController {
|
|
constructor(private service: ColleService) {}
|
|
|
|
async index({ request, response, auth }: HttpContext) {
|
|
const { startDate: rawStartDate } = request.qs()
|
|
|
|
// Validate startDate
|
|
const startDate = rawStartDate ? DateTime.fromISO(rawStartDate, { zone: 'local' }) : null
|
|
if (!rawStartDate || !startDate || !startDate.isValid) {
|
|
return response.badRequest({ message: 'Invalid start date format' })
|
|
}
|
|
const endDate = startDate.plus({ days: 6 }) // Sunday
|
|
|
|
// Retrieve colles for the authenticated user
|
|
const data = await this.service.getColles(auth.user!, startDate.toISO(), endDate.toISO())
|
|
return {
|
|
success: true,
|
|
data,
|
|
}
|
|
}
|
|
|
|
async show({ params, response, auth }: HttpContext) {
|
|
const colleId = parseInt(params.colleId)
|
|
if (isNaN(colleId)) {
|
|
return response.badRequest({ message: 'Invalid colle ID' })
|
|
}
|
|
// Retrieve the colle by ID
|
|
const colle = await Colle.query()
|
|
.where('id', colleId)
|
|
.whereHas('student', (query) => {
|
|
query.where('className', auth.user!.className)
|
|
})
|
|
.preload('student')
|
|
.preload('examiner')
|
|
.preload('subject')
|
|
.preload('room')
|
|
.first()
|
|
if (!colle) {
|
|
return response.notFound({ message: 'Colle not found' })
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
...colle.serialize(),
|
|
bjid: colle.bjid,
|
|
bjsecret: colle.bjsecret,
|
|
},
|
|
}
|
|
}
|
|
|
|
async create({ request, response }: HttpContext) {
|
|
const { colle: payload, className } = await request.validateUsing(createColleValidator)
|
|
|
|
// TODO: Use Redis cache to avoid multiple queries
|
|
// Retrieve or create the necessary entities (relations)
|
|
const student = await this.service.getStudent(payload.student, className)
|
|
const examiner = await this.service.getExaminer(payload.examiner)
|
|
const subject = await this.service.getSubject(payload.subject)
|
|
const room = await this.service.getRoom(payload.room)
|
|
const date = DateTime.fromJSDate(payload.date)
|
|
if (!date.isValid) {
|
|
return response.badRequest({ message: 'Invalid date format' })
|
|
}
|
|
|
|
// Prepare the content and comment for rendering
|
|
if (payload.comment) {
|
|
payload.comment = this.service.prepareHtmlForRendering(payload.comment)
|
|
}
|
|
if (payload.content) {
|
|
payload.content = this.service.prepareHtmlForRendering(payload.content)
|
|
}
|
|
|
|
const colleData = {
|
|
studentId: student.id,
|
|
examinerId: examiner.id,
|
|
subjectId: subject.id,
|
|
roomId: room.id,
|
|
bjsecret: payload.bjsecret,
|
|
bjid: payload.bjid,
|
|
grade: payload.grade,
|
|
content: payload.content,
|
|
comment: payload.comment,
|
|
date,
|
|
}
|
|
|
|
// Check if the colle already exists
|
|
const colle = await Colle.query()
|
|
.where('studentId', student.id)
|
|
.where('subjectId', subject.id)
|
|
.where('date', date.toISO())
|
|
.first()
|
|
|
|
// If it exists, update the existing colle
|
|
if (colle) {
|
|
Object.assign(colle, colleData)
|
|
return colle.save()
|
|
}
|
|
// Create the colle
|
|
return Colle.create(colleData)
|
|
}
|
|
|
|
async createUpcoming({ request }: HttpContext) {
|
|
const payload = await request.validateUsing(createUpcomingCollesValidator)
|
|
// ONLY UPCOMING COLLES
|
|
const now = DateTime.now()
|
|
const colles = payload.colles.filter(
|
|
(colle) => colle.date && DateTime.fromJSDate(colle.date) > now
|
|
)
|
|
|
|
// Retrieve all upcoming colles for the class
|
|
const upcomingColles = await Colle.query()
|
|
.whereHas('student', (query) => {
|
|
query.where('className', payload.className)
|
|
})
|
|
.where('date', '>=', now.toISO())
|
|
.orderBy('date', 'asc')
|
|
// Store the upcoming colles ids
|
|
const upcomingCollesIds = new Set(upcomingColles.map((colle) => colle.id))
|
|
|
|
for await (const colle of colles) {
|
|
// Find the updated data for the colle
|
|
const student = await this.service.getStudent(colle.student, payload.className)
|
|
const examiner = await this.service.getExaminer(colle.examiner)
|
|
const subject = await this.service.getSubject(colle.subject)
|
|
const room = await this.service.getRoom(colle.room)
|
|
const date = DateTime.fromJSDate(colle.date)
|
|
|
|
const oldColle = upcomingColles.find(
|
|
(c) =>
|
|
c.studentId === student.id &&
|
|
c.subjectId === subject.id &&
|
|
c.date.toISO() === date.toISO()
|
|
)
|
|
|
|
const updatedColle = {
|
|
studentId: student.id,
|
|
examinerId: examiner.id,
|
|
subjectId: subject.id,
|
|
roomId: room.id,
|
|
bjsecret: colle.bjsecret,
|
|
bjid: colle.bjid,
|
|
grade: colle.grade,
|
|
content: colle.content,
|
|
comment: colle.comment,
|
|
date,
|
|
}
|
|
|
|
// Create a new colle if it doesn't exist
|
|
if (!oldColle) {
|
|
await Colle.create(updatedColle)
|
|
continue
|
|
}
|
|
|
|
// Update the colle with the new data
|
|
// and remove it from the list
|
|
Object.assign(oldColle, updatedColle)
|
|
await oldColle.save()
|
|
upcomingCollesIds.delete(oldColle.id)
|
|
}
|
|
|
|
// Delete the colles that were not updated
|
|
const deleted = await Colle.query()
|
|
.whereHas('student', (query) => {
|
|
query.where('className', payload.className)
|
|
})
|
|
.whereIn('id', Array.from(upcomingCollesIds))
|
|
.delete()
|
|
|
|
console.log(`Deleted ${deleted} upcoming colles that were not updated`)
|
|
}
|
|
}
|