@@ -2,7 +2,9 @@ import { RoleType } from "~/constants/enums";
22import { HTTP_STATUS } from "~/constants/httpStatus" ;
33import teamRepository from "~/repositories/team.repository" ;
44import { ErrorWithStatus } from "~/rules/error" ;
5-
5+ interface TimeSlots {
6+ [ date : string ] : string [ ] ;
7+ }
68class TeamService {
79 async getAll ( {
810 page,
@@ -154,6 +156,24 @@ class TeamService {
154156 message : "Chỉ trưởng nhóm mới có quyền đăng ký lịch trình thuyết trình." ,
155157 } ) ;
156158 }
159+ // 1 nhóm chỉ dăng ký 1 lần
160+ const existingSchedule = await teamRepository . findSchedulePresentationByTeamId ( teamId ) ;
161+ if ( existingSchedule ) {
162+ throw new ErrorWithStatus ( {
163+ status : HTTP_STATUS . BAD_REQUEST ,
164+ message : "Nhóm đã đăng ký lịch trình thuyết trình, không thể đăng ký lại." ,
165+ } ) ;
166+ }
167+ // present thử đủ 10 slot thì k cho đăng ký nữa (nếu dữ liệu cột trial_date có data và đủ 10 cái thì k cho đăng ký)
168+ const schedules = await teamRepository . findAllPresentationSchedules ( ) ;
169+ const countOnTrialDate = schedules . filter ( ( s ) => s . trialDate . length > 0 ) . length ;
170+ if ( countOnTrialDate >= 10 ) {
171+ throw new ErrorWithStatus ( {
172+ status : HTTP_STATUS . BAD_REQUEST ,
173+ message : "Ngày thuyết trình thử đã đủ số nhóm đăng ký. Bạn không thể đăng ký thêm." ,
174+ } ) ;
175+ }
176+
157177 const created = await teamRepository . createPresentationSchedule ( {
158178 teamId,
159179 trialDate,
@@ -179,6 +199,57 @@ class TeamService {
179199 }
180200 return schedule ;
181201 }
202+
203+ async getSchedulePresentationAll ( ) {
204+ const trialTimeSlots : TimeSlots = {
205+ "17/01/2026" : [ "10h05 - 10h50" , "16h05 - 16h50" , "19h05 - 19h50" , "20h05 - 20h50" ] ,
206+ "18/01/2026" : [ "15h05 - 15h50" , "16h05 - 16h50" , "19h05 - 19h50" , "20h05 - 20h50" ] ,
207+ "19/01/2026" : [ "09h05 - 09h50" , "10h05 - 10h50" , "19h05 - 19h50" , "20h05 - 20h50" ] ,
208+ "20/01/2026" : [ "19h05 - 19h50" , "20h05 - 20h50" ] ,
209+ "21/01/2026" : [ "19h05 - 19h50" , "20h05 - 20h50" ] ,
210+ } ;
211+
212+ const officialTimeSlots : TimeSlots = {
213+ "24/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
214+ "26/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
215+ "27/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
216+ "28/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
217+ "29/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
218+ "30/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
219+ "31/01/2026" : [ "18h - 19h" , "19h15 - 20h15" ] ,
220+ } ;
221+
222+ const schedules = await teamRepository . findAllPresentationSchedules ( ) ;
223+
224+ // Tách trialDate thành date và time slot
225+ const bookedTrialSlots = schedules
226+ . filter ( ( s ) => s . trialDate )
227+ . map ( ( s ) => {
228+ const [ date , timeSlot ] = s . trialDate . split ( "|" ) ;
229+ return { date, timeSlot } ;
230+ } ) ;
231+
232+ const availableTrialSchedules = Object . entries ( trialTimeSlots ) . map ( ( [ date , slots ] ) => ( {
233+ date,
234+ slots : slots . map ( ( slot ) => ( {
235+ time : slot ,
236+ disabled : bookedTrialSlots . some ( ( booked ) => booked . date === date && booked . timeSlot === slot ) ,
237+ } ) ) ,
238+ } ) ) ;
239+
240+ const availableOfficialSchedules = Object . entries ( officialTimeSlots ) . map ( ( [ date , slots ] ) => ( {
241+ date,
242+ slots : slots . map ( ( slot ) => ( {
243+ time : slot ,
244+ // disabled: bookedOfficialDates.includes(date),
245+ } ) ) ,
246+ } ) ) ;
247+
248+ return {
249+ trialSchedules : availableTrialSchedules ,
250+ officialSchedules : availableOfficialSchedules ,
251+ } ;
252+ }
182253}
183254
184255const teamService = new TeamService ( ) ;
0 commit comments