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`)
 | |
|   }
 | |
| }
 | 
