diff --git a/handler/api/rest/v3/course.go b/handler/api/rest/v3/course.go index 0c5ab8a..f71e0f2 100644 --- a/handler/api/rest/v3/course.go +++ b/handler/api/rest/v3/course.go @@ -470,21 +470,21 @@ func fromApiTimetableDay(q openapi.SearchCourseTimetableQueryDays, module timeta ret = append(ret, schedules...) } - if q.Intensive != nil { + if q.Intensive != nil && q.Intensive.N0 != nil && *q.Intensive.N0 { ret = append(ret, timetabledomain.Schedule{ Module: module, Day: timetabledomain.DayIntensive, }) } - if q.AnyTime != nil { + if q.AnyTime != nil && q.AnyTime.N0 != nil && *q.AnyTime.N0 { ret = append(ret, timetabledomain.Schedule{ Module: module, Day: timetabledomain.DayAnyTime, }) } - if q.Appointment != nil { + if q.Appointment != nil && q.Appointment.N0 != nil && *q.Appointment.N0 { ret = append(ret, timetabledomain.Schedule{ Module: module, Day: timetabledomain.DayAppointment, diff --git a/module/schoolcalendar/module.go b/module/schoolcalendar/module.go index 2ed6739..bfd7f44 100644 --- a/module/schoolcalendar/module.go +++ b/module/schoolcalendar/module.go @@ -26,4 +26,12 @@ type UseCase interface { // // [Authentication] not required GetModuleDetails(ctx context.Context, year shareddomain.AcademicYear) ([]*schoolcalendardomain.ModuleDetail, error) + + // GetModuleByDate returns the module corresponding to the given date. + // + // [Authentication] not required + // + // [Error Code] + // - shared.NotFound + GetModuleByDate(ctx context.Context, date civil.Date) (schoolcalendardomain.Module, error) } diff --git a/module/schoolcalendar/port/repository.go b/module/schoolcalendar/port/repository.go index f48b56f..fd43604 100644 --- a/module/schoolcalendar/port/repository.go +++ b/module/schoolcalendar/port/repository.go @@ -31,5 +31,7 @@ type ListEventsConds struct { // ModuleDetail type ListModuleDetailsConds struct { - Year *shareddomain.AcademicYear + Year *shareddomain.AcademicYear + StartBeforeOrEqual *civil.Date + EndAfterOrEqual *civil.Date } diff --git a/module/schoolcalendar/repository/module_detail.go b/module/schoolcalendar/repository/module_detail.go index 39c75ce..91f52ad 100644 --- a/module/schoolcalendar/repository/module_detail.go +++ b/module/schoolcalendar/repository/module_detail.go @@ -21,9 +21,19 @@ func (r *impl) ListModuleDetails(ctx context.Context, conds schoolcalendarport.L }) } - moduleDetails = base.Map(moduleDetails, func(moduleDetail *schoolcalendardomain.ModuleDetail) *schoolcalendardomain.ModuleDetail { - return moduleDetail.Clone() - }) + if conds.StartBeforeOrEqual != nil { + moduleDetails = lo.Filter(moduleDetails, func(moduleDetail *schoolcalendardomain.ModuleDetail, _ int) bool { + return moduleDetail.Start.Before(*conds.StartBeforeOrEqual) || moduleDetail.Start == *conds.StartBeforeOrEqual + }) + } + + if conds.EndAfterOrEqual != nil { + moduleDetails = lo.Filter(moduleDetails, func(moduleDetail *schoolcalendardomain.ModuleDetail, _ int) bool { + return moduleDetail.End.After(*conds.EndAfterOrEqual) || moduleDetail.End == *conds.EndAfterOrEqual + }) + } + + moduleDetails = base.MapByClone(moduleDetails) return moduleDetails, nil } diff --git a/module/schoolcalendar/usecase/module_detail.go b/module/schoolcalendar/usecase/module_detail.go index 66c8d4e..0161e59 100644 --- a/module/schoolcalendar/usecase/module_detail.go +++ b/module/schoolcalendar/usecase/module_detail.go @@ -2,10 +2,14 @@ package schoolcalendarusecase import ( "context" + "fmt" + "cloud.google.com/go/civil" + "github.com/twin-te/twinte-back/apperr" schoolcalendardomain "github.com/twin-te/twinte-back/module/schoolcalendar/domain" schoolcalendarport "github.com/twin-te/twinte-back/module/schoolcalendar/port" shareddomain "github.com/twin-te/twinte-back/module/shared/domain" + sharederr "github.com/twin-te/twinte-back/module/shared/err" sharedport "github.com/twin-te/twinte-back/module/shared/port" ) @@ -14,3 +18,19 @@ func (uc *impl) GetModuleDetails(ctx context.Context, year shareddomain.Academic Year: &year, }, sharedport.LockNone) } + +func (uc *impl) GetModuleByDate(ctx context.Context, date civil.Date) (schoolcalendardomain.Module, error) { + moduleDetails, err := uc.r.ListModuleDetails(ctx, schoolcalendarport.ListModuleDetailsConds{ + StartBeforeOrEqual: &date, + EndAfterOrEqual: &date, + }, sharedport.LockNone) + if err != nil { + return 0, err + } + + if len(moduleDetails) == 0 { + return 0, apperr.New(sharederr.CodeNotFound, fmt.Sprintf("not found module corresponding to the date %s", date)) + } + + return moduleDetails[0].Module, nil +} diff --git a/module/timetable/repository/search.go b/module/timetable/repository/search.go index 16963d6..db7b695 100644 --- a/module/timetable/repository/search.go +++ b/module/timetable/repository/search.go @@ -22,39 +22,49 @@ func (r *impl) SearchCourses(ctx context.Context, conds timetableport.SearchCour } // Filter by keywords - courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { - return lo.EveryBy(conds.Keywords, func(keyword string) bool { - return strings.Contains(course.Name.String(), keyword) + if len(conds.Keywords) != 0 { + courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { + return lo.EveryBy(conds.Keywords, func(keyword string) bool { + return strings.Contains(course.Name.String(), keyword) + }) }) - }) + } // Filter by code prefixes - courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { - return lo.EveryBy(conds.CodePrefixes.Included, func(code string) bool { - return strings.HasPrefix(course.Name.String(), code) + if len(conds.CodePrefixes.Included) != 0 { + courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { + return lo.EveryBy(conds.CodePrefixes.Included, func(code string) bool { + return strings.HasPrefix(course.Code.String(), code) + }) }) - }) - courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { - return lo.EveryBy(conds.CodePrefixes.Excluded, func(code string) bool { - return !strings.HasPrefix(course.Name.String(), code) + } + if len(conds.CodePrefixes.Excluded) != 0 { + courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { + return lo.EveryBy(conds.CodePrefixes.Excluded, func(code string) bool { + return !strings.HasPrefix(course.Code.String(), code) + }) }) - }) + } // Filter by schedules - courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { - return lo.EveryBy(conds.Schedules.FullyIncluded, func(s1 timetabledomain.Schedule) bool { - return lo.SomeBy(course.Schedules, func(s2 timetabledomain.Schedule) bool { - return s1.Module == s2.Module && s1.Day == s2.Day && s1.Period == s2.Period + if len(conds.Schedules.FullyIncluded) != 0 { + courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { + return lo.EveryBy(course.Schedules, func(s1 timetabledomain.Schedule) bool { + return lo.SomeBy(conds.Schedules.FullyIncluded, func(s2 timetabledomain.Schedule) bool { + return s1.Module == s2.Module && s1.Day == s2.Day && s1.Period == s2.Period + }) }) }) - }) - courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { - return lo.SomeBy(conds.Schedules.PartiallyOverlapped, func(s1 timetabledomain.Schedule) bool { - return lo.SomeBy(course.Schedules, func(s2 timetabledomain.Schedule) bool { - return s1.Module == s2.Module && s1.Day == s2.Day && s1.Period == s2.Period + } + if len(conds.Schedules.PartiallyOverlapped) != 0 { + courses = lo.Filter(courses, func(course *timetabledomain.Course, _ int) bool { + return lo.SomeBy(course.Schedules, func(s1 timetabledomain.Schedule) bool { + return lo.SomeBy(conds.Schedules.PartiallyOverlapped, func(s2 timetabledomain.Schedule) bool { + return s1.Module == s2.Module && s1.Day == s2.Day && s1.Period == s2.Period + }) }) }) - }) + } // Apply offset courses = courses[lo.Clamp(conds.Offset, 0, len(courses)):]