77using HwProj . APIGateway . API . Models . Solutions ;
88using HwProj . AuthService . Client ;
99using HwProj . CoursesService . Client ;
10+ using HwProj . Models . AuthService . DTO ;
1011using HwProj . Models . CoursesService . ViewModels ;
1112using HwProj . Models . Roles ;
1213using HwProj . Models . SolutionsService ;
@@ -33,14 +34,6 @@ public SolutionsController(ISolutionsServiceClient solutionsClient, IAuthService
3334 _coursesServiceClient = coursesServiceClient ;
3435 }
3536
36- [ HttpGet ]
37- [ ProducesResponseType ( typeof ( Solution [ ] ) , ( int ) HttpStatusCode . OK ) ]
38- public async Task < IActionResult > GetAllSolutions ( )
39- {
40- var result = await _solutionsClient . GetAllSolutions ( ) ;
41- return Ok ( result ) ;
42- }
43-
4437 [ HttpGet ( "{solutionId}" ) ]
4538 [ ProducesResponseType ( typeof ( Solution ) , ( int ) HttpStatusCode . OK ) ]
4639 public async Task < IActionResult > GetSolutionById ( long solutionId )
@@ -53,19 +46,94 @@ public async Task<IActionResult> GetSolutionById(long solutionId)
5346
5447 [ HttpGet ( "taskSolution/{taskId}/{studentId}" ) ]
5548 [ Authorize ]
56- public async Task < UserTaskSolutions > GetStudentSolution ( long taskId , string studentId )
49+ [ ProducesResponseType ( typeof ( UserTaskSolutions ) , ( int ) HttpStatusCode . OK ) ]
50+ public async Task < IActionResult > GetStudentSolution ( long taskId , string studentId )
51+ {
52+ var course = await _coursesServiceClient . GetCourseByTask ( taskId ) ;
53+ if ( course == null ) return NotFound ( ) ;
54+
55+ var courseMate = course . CourseMates . FirstOrDefault ( t => t . StudentId == studentId ) ;
56+ if ( courseMate == null || ! courseMate . IsAccepted )
57+ return NotFound ( ) ;
58+
59+ var student = await AuthServiceClient . GetAccountData ( studentId ) ;
60+ var studentSolutions = await _solutionsClient . GetUserSolutions ( taskId , studentId ) ;
61+
62+ var solutionsGroupsIds = studentSolutions
63+ . Select ( s => s . GroupId )
64+ . Distinct ( ) ;
65+ var solutionsGroups = course . Groups
66+ . Where ( g => solutionsGroupsIds . Contains ( g . Id ) )
67+ . ToDictionary ( t => t . Id ) ;
68+
69+ var groupMatesIds = course . Groups
70+ . Where ( g => solutionsGroupsIds . Contains ( g . Id ) )
71+ . SelectMany ( g => g . StudentsIds )
72+ . Distinct ( )
73+ . ToArray ( ) ;
74+ var groupMates = groupMatesIds . Any ( )
75+ ? await AuthServiceClient . GetAccountsData ( groupMatesIds )
76+ : Array . Empty < AccountDataDto > ( ) ;
77+
78+ var solutions = studentSolutions
79+ . Select ( s =>
80+ new GetSolutionModel ( s ,
81+ s . GroupId is { } groupId
82+ ? groupMates
83+ . Where ( t => solutionsGroups [ groupId ] . StudentsIds . Contains ( t . UserId ) )
84+ . ToArray ( )
85+ : null ) )
86+ . ToArray ( ) ;
87+
88+ return Ok ( new UserTaskSolutions ( )
89+ {
90+ User = student ,
91+ Solutions = solutions
92+ } ) ;
93+ }
94+
95+ [ Authorize ]
96+ [ HttpGet ( "tasks/{taskId}" ) ]
97+ [ ProducesResponseType ( typeof ( TaskSolutionStatisticsPageData ) , ( int ) HttpStatusCode . OK ) ]
98+ public async Task < IActionResult > GetTaskSolutionsPageData ( long taskId )
5799 {
58- var getSolutionsTask = _solutionsClient . GetUserSolutions ( taskId , studentId ) ;
59- var getUserTask = AuthServiceClient . GetAccountData ( studentId ) ;
100+ var course = await _coursesServiceClient . GetCourseByTask ( taskId ) ;
101+ //TODO: CourseMentorOnlyAttribute
102+ if ( course == null || ! course . MentorIds . Contains ( UserId ) ) return Forbid ( ) ;
60103
61- await Task . WhenAll ( getSolutionsTask , getUserTask ) ;
104+ var studentIds = course . CourseMates
105+ . Where ( t => t . IsAccepted )
106+ . Select ( t => t . StudentId )
107+ . ToArray ( ) ;
108+
109+ var getStudentsDataTask = AuthServiceClient . GetAccountsData ( studentIds ) ;
110+ var getStatisticsTask = _solutionsClient . GetTaskSolutionStatistics ( course . Id , taskId ) ;
111+
112+ await Task . WhenAll ( getStudentsDataTask , getStatisticsTask ) ;
62113
63- var result = new UserTaskSolutions
114+ var usersData = getStudentsDataTask . Result . ToDictionary ( t => t . UserId ) ;
115+ var statistics = getStatisticsTask . Result . ToDictionary ( t => t . StudentId ) ;
116+ var groups = course . Groups . ToDictionary (
117+ t => t . Id ,
118+ t => t . StudentsIds . Select ( s => usersData [ s ] ) . ToArray ( ) ) ;
119+
120+ var result = new TaskSolutionStatisticsPageData ( )
64121 {
65- User = getUserTask . Result ,
66- Solutions = getSolutionsTask . Result ,
122+ CourseId = course . Id ,
123+ StudentsSolutions = studentIds . Select ( studentId => new UserTaskSolutions
124+ {
125+ Solutions = statistics . TryGetValue ( studentId , out var studentSolutions )
126+ ? studentSolutions . Solutions . Select ( t => new GetSolutionModel ( t ,
127+ t . GroupId is { } groupId ? groups [ groupId ] : null ) ) . ToArray ( )
128+ : Array . Empty < GetSolutionModel > ( ) ,
129+ User = usersData [ studentId ]
130+ } )
131+ . OrderBy ( t => t . User . Surname )
132+ . ThenBy ( t => t . User . Name )
133+ . ToArray ( )
67134 } ;
68- return result ;
135+
136+ return Ok ( result ) ;
69137 }
70138
71139 [ Authorize ]
@@ -110,13 +178,58 @@ public async Task<IActionResult> GetTaskSolutionsPageData(long taskId)
110178 }
111179
112180 [ HttpPost ( "{taskId}" ) ]
113- [ Authorize ]
181+ [ Authorize ( Roles = Roles . StudentRole ) ]
114182 [ ProducesResponseType ( typeof ( long ) , ( int ) HttpStatusCode . OK ) ]
115183 public async Task < IActionResult > PostSolution ( SolutionViewModel model , long taskId )
116184 {
117- model . StudentId = UserId ;
118- var result = await _solutionsClient . PostSolution ( model , taskId ) ;
119- return Ok ( result ) ;
185+ var solutionModel = new PostSolutionModel ( model )
186+ {
187+ StudentId = UserId
188+ } ;
189+
190+ var course = await _coursesServiceClient . GetCourseByTask ( taskId ) ;
191+ if ( course is null ) return BadRequest ( ) ;
192+
193+ var courseMate = course . CourseMates . FirstOrDefault ( t => t . StudentId == solutionModel . StudentId ) ;
194+ if ( courseMate == null || ! courseMate . IsAccepted )
195+ return BadRequest ( $ "Студента с id { solutionModel . StudentId } не существует") ;
196+
197+ if ( model . GroupMateIds == null || model . GroupMateIds . Length == 0 )
198+ {
199+ var result = await _solutionsClient . PostSolution ( taskId , solutionModel ) ;
200+ return Ok ( result ) ;
201+ }
202+
203+ var fullStudentsGroup = model . GroupMateIds . ToList ( ) ;
204+ fullStudentsGroup . Add ( solutionModel . StudentId ) ;
205+ var arrFullStudentsGroup = fullStudentsGroup . Distinct ( ) . ToArray ( ) ;
206+
207+ if ( arrFullStudentsGroup . Intersect ( course . CourseMates . Select ( x =>
208+ x . StudentId ) ) . Count ( ) != arrFullStudentsGroup . Length ) return BadRequest ( ) ;
209+
210+ var existedGroup = course . Groups . SingleOrDefault ( x =>
211+ x . StudentsIds . Intersect ( arrFullStudentsGroup ) . Count ( ) == arrFullStudentsGroup . Length ) ;
212+
213+ solutionModel . GroupId =
214+ existedGroup ? . Id ??
215+ await _coursesServiceClient . CreateCourseGroup ( new CreateGroupViewModel ( arrFullStudentsGroup , course . Id ) ,
216+ taskId ) ;
217+
218+ await _solutionsClient . PostSolution ( taskId , solutionModel ) ;
219+ return Ok ( solutionModel ) ;
220+ }
221+
222+ [ HttpPost ( "rateEmptySolution/{taskId}" ) ]
223+ [ Authorize ( Roles = Roles . LecturerRole ) ]
224+ public async Task < IActionResult > PostEmptySolutionWithRate ( long taskId , SolutionViewModel model )
225+ {
226+ var course = await _coursesServiceClient . GetCourseByTask ( taskId ) ;
227+ if ( course == null || ! course . MentorIds . Contains ( UserId ) ) return Forbid ( ) ;
228+ if ( course . CourseMates . All ( t => t . StudentId != model . StudentId ) )
229+ return BadRequest ( $ "Студента с id { model . StudentId } не существует") ;
230+
231+ await _solutionsClient . PostEmptySolutionWithRate ( taskId , model ) ;
232+ return Ok ( ) ;
120233 }
121234
122235 [ HttpPost ( "rateEmptySolution/{taskId}" ) ]
@@ -157,26 +270,6 @@ public async Task<IActionResult> DeleteSolution(long solutionId)
157270 return Ok ( ) ;
158271 }
159272
160- [ HttpPost ( "{groupId}/{taskId}" ) ]
161- [ Authorize ]
162- [ ProducesResponseType ( typeof ( long ) , ( int ) HttpStatusCode . OK ) ]
163- public async Task < IActionResult > PostGroupSolution ( SolutionViewModel model , long taskId , long groupId )
164- {
165- var result = await _solutionsClient . PostGroupSolution ( model , taskId , groupId ) ;
166- return Ok ( result ) ;
167- }
168-
169- [ HttpGet ( "{groupId}/taskSolutions/{taskId}" ) ]
170- [ Authorize ]
171- [ ProducesResponseType ( typeof ( Solution [ ] ) , ( int ) HttpStatusCode . OK ) ]
172- public async Task < IActionResult > GetGroupSolutions ( long groupId , long taskId )
173- {
174- var result = await _solutionsClient . GetTaskSolutions ( groupId , taskId ) ;
175- return result == null
176- ? NotFound ( ) as IActionResult
177- : Ok ( result ) ;
178- }
179-
180273 [ HttpGet ( "unratedSolutions" ) ]
181274 [ Authorize ( Roles = Roles . LecturerRole ) ]
182275 public async Task < UnratedSolutionPreviews > GetUnratedSolutions ( long ? taskId )
0 commit comments