package Ġcore . ems . service . mood le Ċ Ċ import Ġcom . fasterxml . jackson . annotation . JsonProperty Ċ import Ġcom . fasterxml . jackson . module . kotlin . jackson ObjectMapper Ċ import Ġcore . db .* Ċ import Ġcore . ems . service . select Latest Sub missions For Exercise Ċ import Ġcore . exception . Invalid RequestException Ċ import Ġcore . exception . Req Error Ċ import Ġcore . exception . Resource Locked Exception Ċ import Ġcore . util . DB Back ed Lock Ċ import Ġmu . Kotlin Logging Ċ import Ġorg . jetbrains . ex posed . sql . SortOrder Ċ import Ġorg . jetbrains . ex posed . sql . and Ċ import Ġorg . jetbrains . ex posed . sql . select Ċ import Ġorg . jetbrains . ex posed . sql . transactions . transaction Ċ import Ġorg . springframework . beans . factory . annotation . Value Ċ import Ġorg . springframework . http . Http Entity Ċ import Ġorg . springframework . http . HttpHeaders Ċ import Ġorg . springframework . http . MediaType Ċ import Ġorg . springframework . http . Response Entity Ċ import Ġorg . springframework . scheduling . annotation . Async Ċ import Ġorg . springframework . stereotype . Service Ċ import Ġorg . springframework . util . Linked Multi Value Map Ċ import Ġorg . springframework . util . Multi Value Map Ċ import Ġorg . springframework . web . client . Rest Template Ċ Ċ private Ġval Ġlog Ġ= ĠKotlin Logging . logger Ġ{} ĊĊ Ċ @ Service Ċ class ĠM ood le Gr ades Sync Service Ġ{ ĊĊĠĠĠ Ġ@ Value ("\ ${ easy . core . mood le - sync . grade s . url }") ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm ood le Grade Url : ĠString ĊĊĠĠĠ Ġval Ġsync Gr ades Lock Ġ= ĠDB Back ed Lock ( Course , ĠCourse . mood le Sync Gr ades InProgress ) ĊĊĊĠĠĠ Ġdata Ġclass ĠM ood le Req (@ JsonProperty (" short name ") Ġval Ġshort name : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ JsonProperty (" exercises ") Ġval Ġexercises : ĠList < Mood le Req Exercise >) ĊĊĠĠĠ Ġdata Ġclass ĠM ood le Req Exercise (@ JsonProperty (" id number ") Ġval Ġid number : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ JsonProperty (" title ") Ġval Ġtitle : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ JsonProperty (" grade s ") Ġval Ġgr ades : ĠList < Mood le Req Grade >) ĊĊĊĠĠĠ Ġdata Ġclass ĠM ood le Req Grade (@ JsonProperty (" username ") Ġval Ġusername : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ JsonProperty (" grade ") Ġval Ġgrade : ĠInt ) ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSync Ġsingle Ġsubmission Ġgrade Ġto ĠM ood le . ĠIf Ġthe Ġsubmission Ġhas Ġno Ġlink Ġwith Ġthe ĠM ood le , Ġthen Ġnothing Ġis Ġdone . ĠIs Ġasynchronous . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Async ĊĠĠĠ Ġfun Ġsync Single Grade To Mood le ( submission Id : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( Submission Ġinner Join ĠCourse Exercise Ġinner Join ĠCourse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Course . id , ĠCourse Exercise . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠSubmission . id Ġeq Ġsubmission Id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. single () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshort name Ġ= Ġselect Course ShortName ( this [ Course . id ]. value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġrespect ĠCourse . sync Gr ades ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! short name . isNull Or Blank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsingle Exercise Ġ= Ġselect Single Course Exercise Submission ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [ Course . id ]. value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [ Course Exercise . id ]. value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubmission Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( single Exercise . grade s . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Mood le Grade Request ( Mood le Req ( short name , ĠlistOf ( single Exercise ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgrade Ġ= Ġsingle Exercise . grade s [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug Ġ{ Ġ" Mood le Ġsynced Ġgrade Ġ${ grade . grade } Ġfor Ġ${ grade . username } Ġto Ġexercise Ġ${ single Exercise . id number } Ġon Ġcourse Ġ$ short name " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn Ġ{ Ġ" Skipping ĠM ood le Ġgrade Ġsync Ġdue Ġto Ġno Ġexisting Ġgr ades Ġto Ġsync ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSync Ġall Ġgr ades Ġon Ġa Ġsingle Ġcourse Ġto ĠM ood le . ĠRes pect s Ġgrade Ġsync Ġlocking . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ throws ĠResource Locked Exception Ġif Ġgr ades Ġsync Ġis Ġalready Ġin Ġprogress ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsync Course Gr ades To Mood le ( course Id : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsync Gr ades Lock . with ( course Id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshort name Ġ= Ġselect Course ShortName ( course Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( short name . isNull Or Blank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn Ġ{ Ġ" Course Ġ$ course Id Ġis Ġnot Ġsynced Ġdue Ġto Ġno Ġlink Ġwith ĠM ood le ." Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSend Ġgr ades Ġin Ġbatches Ġof Ġ 2 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexercises Ġ= Ġselect Ex ercises On Course ( course Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbatches Ġ= Ġbatch Gr ades ( short name , Ġexercises ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbatches . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug Ġ{ Ġ" Sending Ġgrade Ġbatch : Ġ$ it " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Mood le Grade Request ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSend Ġgrade Ġrequest Ġto ĠM ood le . ĠExcept s Ġresponse Ġbody Ġfrom ĠM ood le Ġto Ġcontain Ġ' done '. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsend Mood le Grade Request ( req : ĠM ood le Req ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġheaders Ġ= ĠHttp Headers () ĊĠĠĠĠĠĠĠ Ġheaders . contentType Ġ= ĠMediaType . APPLICATION _ FORM _ URL ENCODE D ĊĠĠĠĠĠĠĠ Ġval Ġmap : ĠMulti Value Map < String , ĠString > Ġ= ĠLinked Multi Value Map () ĊĠĠĠĠĠĠĠ Ġmap . add (" data ", Ġj ack son ObjectMapper (). writeValue AsString ( req )) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠHttp Entity ( map , Ġheaders ) ĊĊĠĠĠĠĠĠĠ Ġval Ġresponse Entity : ĠResponseEntity < String > Ġ= ĠRest Template (). post For Entity ( mood le Grade Url , Ġrequest , ĠString :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( response Entity . statusCode . value () Ġ!= Ġ 2 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error Ġ{ Ġ" Mood le Ġgrade Ġsync ing Ġerror Ġ${ response Entity . statusCode Value } Ġwith Ġdata Ġ$ req " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid RequestException (" Grade Ġsync ing Ġwith ĠM ood le Ġfailed Ġdue Ġto Ġerror Ġcode Ġin Ġresponse .", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠReq Error . MO OD LE _ GR ADE _ SYNC _ ERROR , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġresponse Entity . body ĊĠĠĠĠĠĠĠ Ġif Ġ( body Ġ== Ġnull Ġ|| Ġ! body . contains (" done ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error Ġ{ Ġ" Mood le Ġgrade Ġsync ing Ġerror . ĠGr ade Ġsync ing Ġwith ĠM ood le Ġfailed Ġdue Ġto Ġresponse Ġbody Ġfrom ĠM ood le Ġdid Ġnot Ġcontain Ġ' done ': Ġ${ response Entity . body }. ĠData : Ġ$ req " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid RequestException (" Grade Ġsync ing Ġwith ĠM ood le Ġfailed Ġdue Ġto Ġresponse Ġbody Ġfrom ĠM ood le Ġdid Ġnot Ġcontain Ġ' done '. ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠReq Error . MO OD LE _ GR ADE _ SYNC _ ERROR , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHelper Ġfunction Ġto Ġgenerate Ġgrade Ġbatches Ġof Ġ 2 0 0 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġbatch Gr ades ( course ShortName : ĠString , Ġexercises : ĠList < Mood le Req Exercise >): ĠList < Mood le Req > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġexercises . flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunks Ġ= Ġit . grade s . chunk ed ( 2 0 0 ) Ġ{ Ġgr ades Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠM ood le Req ( course ShortName , ĠlistOf ( Mood le Req Exercise ( it . id number , Ġit . title , Ġgr ades ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chunks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunks ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSync Ġexercises Ġwith Ġno Ġgr ades ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Mood le Req ( course ShortName , ĠlistOf ( Mood le Req Exercise ( it . id number , Ġit . title , Ġempty List ())) )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġselect Single Course Exercise Submission ( course Id : ĠLong , Ġcourse Ex Id : ĠLong , Ġsubmission Id : ĠLong ): ĠM ood le Req Exercise Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( Course Exercise Ġinner Join ĠExercise Ġinner Join ĠExercise Ver ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Course Exercise . id , ĠExercise Ver . title , ĠCourse Exercise . title Alias , ĠCourse Exercise . mood le Ex Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠCourse Exercise . course Ġeq Ġcourse Id Ġand ĠExercise Ver . valid To . isNull () Ġand Ġ( Course Exercise . id Ġeq Ġcourse Ex Id ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠM ood le Req Exercise ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex [ Course Exercise . mood le Ex Id ] Ġ?: Ġex [ Course Exercise . id ]. value . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex [ Course Exercise . title Alias ] Ġ?: Ġex [ Exercise Ver . title ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf NotNull ( select Latest Grade For Submission ( submission Id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. single () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġselect Ex ercises On Course ( course Id : ĠLong ): ĠList < Mood le Req Exercise > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( Course Exercise Ġinner Join ĠExercise Ġinner Join ĠExercise Ver ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Course Exercise . id , ĠExercise Ver . title , ĠCourse Exercise . title Alias , ĠCourse Exercise . mood le Ex Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCourse Exercise . order Idx ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠCourse Exercise . course Ġeq Ġcourse Id Ġand ĠExercise Ver . valid To . isNull () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orderBy ( Course Exercise . order Idx , ĠSort Order . ASC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġex Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgr ades Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselect Latest Sub missions For Exercise ( ex [ Course Exercise . id ]. value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselect Latest Grade For Submission ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠM ood le Req Exercise ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex [ Course Exercise . mood le Ex Id ] Ġ?: Ġex [ Course Exercise . id ]. value . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex [ Course Exercise . title Alias ] Ġ?: Ġex [ Exercise Ver . title ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgr ades ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġselect Latest Grade For Submission ( submission Id : ĠLong ): ĠM ood le Req Grade ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġm ood le Username Ġ= Ġ( Submission Ġinner Join ĠStudent Ġinner Join ĠAccount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Account . mood le Username , ĠAccount . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠSubmission . id Ġeq Ġsubmission Id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm ood le Username Ġ= Ġit [ Account . mood le Username ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mood le Username Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm ood le Username ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn Ġ{ Ġ" Unable Ġto Ġsync Ġgr ades Ġto ĠM ood le Ġfor Ġstudent Ġ${ it [ Account . id ]} Ġbecause Ġthey Ġhave Ġno ĠM ood le Ġusername " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ select Latest Grade For Submission Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. single () ĊĊĠĠĠĠĠĠĠ Ġval Ġteacher Grade Ġ= ĠTe acher Assessment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Teacher Assessment . grade ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠTe acher Assessment . submission Ġeq Ġsubmission Id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orderBy ( Teacher Assessment . createdAt Ġto ĠSort Order . DESC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. limit ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġassessment Ġ-> ĠM ood le Req Grade ( mood le Username , Ġassessment [ Teacher Assessment . grade ]) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( teacher Grade Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġteacher Grade ĊĊĠĠĠĠĠĠĠ Ġreturn ĠAutomatic Assessment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Automatic Assessment . grade ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠAutomatic Assessment . submission Ġeq Ġsubmission Id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. orderBy ( Automatic Assessment . createdAt Ġto ĠSort Order . DESC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. limit ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġassessment Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠM ood le Req Grade ( mood le Username , Ġassessment [ Automatic Assessment . grade ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĠĠĠ Ġ} Ċ } Ċ