diff --git a/ApiDto/Requests/ScheduleRequest.cs b/ApiDto/Requests/ScheduleRequest.cs new file mode 100644 index 0000000..476d8f3 --- /dev/null +++ b/ApiDto/Requests/ScheduleRequest.cs @@ -0,0 +1,37 @@ +namespace Mirea.Api.Dto.Requests; + +/// +/// Represents a request object for retrieving schedules based on various filters. +/// +public class ScheduleRequest +{ + /// + /// Gets or sets an array of group IDs. + /// + /// This array can contain null values. + public int[]? Groups { get; set; } = null; + + /// + /// Gets or sets a value indicating whether to retrieve schedules for even weeks. + /// + /// This property can contain null. + public bool? IsEven { get; set; } = null; + + /// + /// Gets or sets an array of discipline IDs. + /// + /// This array can contain null values. + public int[]? Disciplines { get; set; } = null; + + /// + /// Gets or sets an array of professor IDs. + /// + /// This array can contain null values. + public int[]? Professors { get; set; } = null; + + /// + /// Gets or sets an array of lecture hall IDs. + /// + /// This array can contain null values. + public int[]? LectureHalls { get; set; } = null; +} diff --git a/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs b/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs new file mode 100644 index 0000000..bf4a337 --- /dev/null +++ b/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a professor. +/// +public class DisciplineScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a professor. +/// +public class DisciplineScheduleResponse +{ + /// + /// Gets or sets the name of the discipline. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the schedules for the professor. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/GroupScheduleResponse.cs b/ApiDto/Responses/Schedule/GroupScheduleResponse.cs new file mode 100644 index 0000000..7fa13d1 --- /dev/null +++ b/ApiDto/Responses/Schedule/GroupScheduleResponse.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a group. +/// +public class GroupScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a group. +/// +public class GroupScheduleResponse +{ + /// + /// Gets or sets the name of the group. + /// + [Required] + public required string Group { get; set; } + + /// + /// Gets or sets the ID of the group. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the schedules for the group. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs b/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs new file mode 100644 index 0000000..369a8f5 --- /dev/null +++ b/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a lecture hall. +/// +public class LectureHallScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a lecture hall. +/// +public class LectureHallScheduleResponse +{ + /// + /// Gets or sets the names of the lecture halls. + /// + public required string LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls. + /// + public required int LectureHallsId { get; set; } + + /// + /// Gets or sets the schedules for the lecture hall. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs b/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs new file mode 100644 index 0000000..3a53ebf --- /dev/null +++ b/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a professor. +/// +public class ProfessorScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a professor. +/// +public class ProfessorScheduleResponse +{ + /// + /// Gets or sets the name of the professor. + /// + [Required] + public required string Professor { get; set; } + + /// + /// Gets or sets the ID of the professor. + /// + [Required] + public required int ProfessorId { get; set; } + + /// + /// Gets or sets the schedules for the professor. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/ScheduleResponse.cs b/ApiDto/Responses/Schedule/ScheduleResponse.cs new file mode 100644 index 0000000..2a03178 --- /dev/null +++ b/ApiDto/Responses/Schedule/ScheduleResponse.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents a response object containing schedule information. +/// +public class ScheduleResponse +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the name of the group for the schedule entry. + /// + [Required] + public required string Group { get; set; } + + /// + /// Gets or sets the ID of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} diff --git a/Endpoint/Controllers/V1/ScheduleController.cs b/Endpoint/Controllers/V1/ScheduleController.cs new file mode 100644 index 0000000..43b47ad --- /dev/null +++ b/Endpoint/Controllers/V1/ScheduleController.cs @@ -0,0 +1,304 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; +using Mirea.Api.Dto.Requests; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Dto.Responses.Schedule; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +public class ScheduleController(IMediator mediator) : BaseControllerV1 +{ + /// + /// Retrieves schedules based on various filters. + /// + /// The request object containing filter criteria. + /// A list of schedules matching the filter criteria. + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task>> Get([FromBody] ScheduleRequest request) + + { + if ((request.Groups == null || !request.Groups.Any()) && + (request.Disciplines == null || !request.Disciplines.Any()) && + (request.Professors == null || !request.Professors.Any()) && + (request.LectureHalls == null || !request.LectureHalls.Any())) + { + return BadRequest(new ErrorResponse() + { + Error = "At least one of the arguments must be selected." + + (request.IsEven.HasValue + ? $" \"{nameof(request.IsEven)}\" is not a strong argument" + : string.Empty), + Code = StatusCodes.Status400BadRequest + }); + } + + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = request.IsEven, + DisciplineIds = request.Disciplines, + GroupIds = request.Groups, + LectureHallIds = request.LectureHalls, + ProfessorIds = request.Professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(result.Select(s => new ScheduleResponse() + { + DayOfWeek = s.DayOfWeek, + PairNumber = s.PairNumber, + IsEven = s.IsEven, + Discipline = s.Discipline, + DisciplineId = s.DisciplineId, + TypeOfOccupation = s.TypeOfOccupation, + Group = s.Group, + GroupId = s.GroupId, + LectureHalls = s.LectureHalls, + LectureHallsId = s.LectureHallsId, + Professors = s.Professors, + ProfessorsId = s.ProfessorsId, + Campus = s.Campus, + CampusId = s.CampusId, + LinkToMeet = s.LinkToMeet + })); + + } + + /// + /// Retrieves schedules for a specific group based on various filters. + /// + /// The ID of the group. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of professor IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified group. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByGroup(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? professors = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = [id], + LectureHallIds = lectureHalls, + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new GroupScheduleResponse() + { + Group = result[0].Group, + GroupId = result[0].GroupId, + Schedules = result.Select(g => new GroupScheduleInfo() + { + DayOfWeek = g.DayOfWeek, + PairNumber = g.PairNumber, + IsEven = g.IsEven, + Discipline = g.Discipline, + DisciplineId = g.DisciplineId, + TypeOfOccupation = g.TypeOfOccupation, + LectureHalls = g.LectureHalls, + LectureHallsId = g.LectureHallsId, + Professors = g.Professors, + ProfessorsId = g.ProfessorsId, + Campus = g.Campus, + CampusId = g.CampusId, + LinkToMeet = g.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific professor based on various filters. + /// + /// The ID of the professor. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of group IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified professor. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByProfessor(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = groups, + LectureHallIds = lectureHalls, + ProfessorIds = [id] + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new ProfessorScheduleResponse() + { + Professor = result.Select(professor => + professor.Professors.FirstOrDefault(x => !string.IsNullOrEmpty(x)) + ).First()!, + ProfessorId = result.Select(professor => + professor.ProfessorsId.FirstOrDefault(x => x != null) + ).First()!.Value, + Schedules = result.Select(p => new ProfessorScheduleInfo() + { + DayOfWeek = p.DayOfWeek, + PairNumber = p.PairNumber, + IsEven = p.IsEven, + Discipline = p.Discipline, + DisciplineId = p.DisciplineId, + TypeOfOccupation = p.TypeOfOccupation, + Group = p.Group, + GroupId = p.GroupId, + LectureHalls = p.LectureHalls, + LectureHallsId = p.LectureHallsId, + Campus = p.Campus, + CampusId = p.CampusId, + LinkToMeet = p.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific lecture hall based on various filters. + /// + /// The ID of the lecture hall. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of professor IDs. + /// An array of group IDs. + /// A response containing schedules for the specified lecture hall. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByLectureHall(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? professors = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = groups, + LectureHallIds = [id], + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new LectureHallScheduleResponse() + { + LectureHalls = result.Select(lectureHall => + lectureHall.LectureHalls.FirstOrDefault(x => !string.IsNullOrEmpty(x)) + ).First()!, + LectureHallsId = result.Select(lectureHall => + lectureHall.LectureHallsId.FirstOrDefault(x => x != null) + ).First()!.Value, + Schedules = result.Select(l => new LectureHallScheduleInfo() + { + DayOfWeek = l.DayOfWeek, + PairNumber = l.PairNumber, + IsEven = l.IsEven, + Discipline = l.Discipline, + DisciplineId = l.DisciplineId, + TypeOfOccupation = l.TypeOfOccupation, + Group = l.Group, + GroupId = l.GroupId, + Professors = l.Professors, + ProfessorsId = l.ProfessorsId, + Campus = l.Campus, + CampusId = l.CampusId, + LinkToMeet = l.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific discipline based on various filters. + /// + /// The ID of the discipline. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of group IDs. + /// An array of professor IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified discipline. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByDiscipline(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? professors = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = [id], + GroupIds = groups, + LectureHallIds = [id], + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new DisciplineScheduleResponse() + { + Discipline = result[0].Discipline, + DisciplineId = result[0].DisciplineId, + Schedules = result.Select(d => new DisciplineScheduleInfo() + { + DayOfWeek = d.DayOfWeek, + PairNumber = d.PairNumber, + IsEven = d.IsEven, + TypeOfOccupation = d.TypeOfOccupation, + Group = d.Group, + GroupId = d.GroupId, + LectureHalls = d.LectureHalls, + LectureHallsId = d.LectureHallsId, + Professors = d.Professors, + ProfessorsId = d.ProfessorsId, + Campus = d.Campus, + CampusId = d.CampusId, + LinkToMeet = d.LinkToMeet + }) + }); + } +} \ No newline at end of file