package Ġfm . force . quiz . core . service Ċ Ċ import Ġam . ik . y avi . builder . Validator Builder Ċ import Ġam . ik . y avi . builder . kon straint Ċ import Ġam . ik . y avi . builder . kon straint On Group Ċ import Ġfm . force . quiz . common . Specification Builder Ċ import Ġfm . force . quiz . common . dto . Page DTO Ċ import Ġfm . force . quiz . common . dto . Quiz Session Full DTO Ċ import Ġfm . force . quiz . common . dto . Quiz Session Patch DTO Ċ import Ġfm . force . quiz . common . dto . Quiz Session Search DTO Ċ import Ġfm . force . quiz . common . mapper . to DTO Ċ import Ġfm . force . quiz . common . mapper . to Full DTO Ċ import Ġfm . force . quiz . core . entity . Quiz Question Ċ import Ġfm . force . quiz . core . entity . Quiz Session Ċ import Ġfm . force . quiz . core . entity . Quiz Session Question Ċ import Ġfm . force . quiz . core . entity . Quiz Session Question Answer Ċ import Ġfm . force . quiz . core . entity . Quiz Session _ Ċ import Ġfm . force . quiz . core . exception . ValidationError Ċ import Ġfm . force . quiz . core . repository . Difficulty Scale Repository Ċ import Ġfm . force . quiz . core . repository . Quiz Repository Ċ import Ġfm . force . quiz . core . repository . Quiz Session Question Answer Repository Ċ import Ġfm . force . quiz . core . repository . Quiz Session Question Repository Ċ import Ġfm . force . quiz . core . repository . Quiz Session Repository Ċ import Ġfm . force . quiz . core . validator . fk Constraint Ċ import Ġfm . force . quiz . core . validator . instant Constraint Ċ import Ġjava . time . Instant Ċ import Ġorg . springframework . data . domain . Page Ċ import Ġorg . springframework . data . jpa . domain . Specification Ċ import Ġorg . springframework . stereotype . Service Ċ import Ġorg . springframework . transaction . annotation . Transactional Ċ Ċ @ Service Ċ class ĠQu iz Session Service ( ĊĠĠĠ Ġprivate Ġval Ġquiz Repository : ĠQu iz Repository , ĊĠĠĠ Ġprivate Ġval Ġdifficulty Scale Repository : ĠDiff iculty Scale Repository , ĊĠĠĠ Ġprivate Ġval Ġquiz Session Question Answer Repository : ĠQu iz Session Question Answer Repository , ĊĠĠĠ Ġprivate Ġval Ġquiz Session Question Repository : ĠQu iz Session Question Repository , ĊĠĠĠ Ġquiz Session Repository : ĠQu iz Session Repository Ċ ) Ġ: ĠQu iz Session ServiceType ( quiz Session Repository ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġmsg Already Cancelled Ġ= Ġ" Session Ġhas Ġalready Ġbeen Ġcancelled " ĊĠĠĠ Ġprivate Ġval Ġmsg Already Completed Ġ= Ġ" Session Ġhas Ġalready Ġbeen Ġcompleted " ĊĠĠĠ Ġprivate Ġval Ġmsg Session Is Expired Ġ= Ġ" Session Ġis Ġexpired " ĊĊĠĠĠ Ġoverride Ġvar Ġdto Validator Ġ= ĠValidator Builder . of < Quiz Session Patch DTO >() ĊĠĠĠĠĠĠĠ Ġ. fk Constraint ( Quiz Session Patch DTO :: quiz , Ġquiz Repository ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġoverride Ġvar Ġentity Validator Ġ= ĠValidator Builder . of < Quiz Session >() ĊĠĠĠĠĠĠĠ Ġ. kon straint On Group ( Transition Constraint Group . CANCEL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkon straint ( Quiz Session :: is Cancelled ) Ġ{ Ġis False . message ( msg Already Cancelled ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkon straint ( Quiz Session :: is Completed ) Ġ{ Ġis False . message ( msg Already Completed ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. kon straint On Group ( Transition Constraint Group . COMPLETE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkon straint ( Quiz Session :: is Cancelled ) Ġ{ Ġis False . message ( msg Already Cancelled ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkon straint ( Quiz Session :: is Completed ) Ġ{ Ġis False . message ( msg Already Completed ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. instant Constraint ( Quiz Session :: valid T ill , Ġerror Template Ġ= Ġmsg Session Is Expired ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġoverride Ġfun Ġcreate ( create DTO : ĠQu iz Session Patch DTO ): ĠQu iz Session Ġ{ ĊĠĠĠĠĠĠĠ Ġvalidate Create ( create DTO ) ĊĊĠĠĠĠĠĠĠ Ġval Ġquiz Ġ= Ġquiz Repository . getEntity ( create DTO . quiz ) ĊĠĠĠĠĠĠĠ Ġvar Ġentity Ġ= ĠQu iz Session ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġowner Ġ= Ġauthentication Facade . user , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquiz Ġ= Ġquiz , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdifficulty Scale Ġ= Ġquiz . difficulty Scale , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Cancelled Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Completed Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġentity Ġ= Ġrepository . save ( entity ) ĊĠĠĠĠĠĠĠ Ġclone Quiz Questions ( entity ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġentity ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclone Quiz Questions ( entity : ĠQu iz Session ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcloned Questions Ġ= Ġmutable ListOf < Quiz Session Question >() ĊĠĠĠĠĠĠĠ Ġval Ġcloned Answers Ġ= Ġmutable ListOf < Quiz Session Question Answer >() ĊĊĠĠĠĠĠĠĠ Ġentity . quiz ?. quiz Questions ?. forEach Ġ{ Ġqq Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( quiz Session Question , Ġquiz Session Question Answers ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclone Quiz Question ( entity , Ġqq ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcloned Questions . add ( quiz Session Question ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcloned Answers . addAll ( quiz Session Question Answers ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġquiz Session Question Repository . save All ( cloned Questions ) ĊĠĠĠĠĠĠĠ Ġquiz Session Question Answer Repository . save All ( cloned Answers ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclone Quiz Question ( ĊĠĠĠĠĠĠĠ Ġentity : ĠQu iz Session , ĊĠĠĠĠĠĠĠ Ġquiz Question : ĠQu iz Question ĊĠĠĠ Ġ): ĠPair < Quiz Session Question , ĠList < Quiz Session Question Answer >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġowner Ġ= Ġauthentication Facade . user ĊĠĠĠĠĠĠĠ Ġval Ġquiz Session Question Ġ= ĠQu iz Session Question ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġowner Ġ= Ġowner , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquiz Session Ġ= Ġentity , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Question Ġ= Ġquiz Question . question , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġquiz Question . question . title , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġquiz Question . question . text , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhelp Ġ= Ġquiz Question . question . help , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseq Ġ= Ġquiz Question . seq , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdifficulty Ġ= Ġquiz Question . question . difficulty ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcorrect Answers Map Ġ= Ġquiz Question . question . correct Answers . map Ġ{ Ġit . id Ġto Ġit Ġ}. toMap () ĊĠĠĠĠĠĠĠ Ġval Ġanswers Ġ= Ġquiz Question . question . answers . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠQu iz Session Question Answer ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġowner Ġ= Ġowner , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquiz Session Ġ= Ġentity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquiz Session Question Ġ= Ġquiz Session Question , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Answer Ġ= Ġit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġit . text , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Correct Ġ= Ġcorrect Answers Map [ it . id ] Ġ!= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġquiz Session Question Ġto Ġanswers ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġbuild Search Spec ( search : ĠQu iz Session Search DTO ?): ĠSpecification < Quiz Session > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġowner Equals Ġ= ĠSpecification Builder . fk ( authentication Facade :: user , ĠQu iz Session _. owner ) ĊĠĠĠĠĠĠĠ Ġif Ġ( search Ġ== Ġnull ) Ġreturn Ġowner Equals ĊĊĠĠĠĠĠĠĠ Ġvar Ġspec Ġ= Ġowner Equals ĊĊĠĠĠĠĠĠĠ Ġwith ( Specification Builder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( search . quiz Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= Ġspec . and ( fk ( quiz Repository . getEntity (( search . quiz )), ĠQu iz Session _. quiz )) !! ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( search . difficulty Scale Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= Ġspec . and ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfk ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdifficulty Scale Repository . getEntity (( search . difficulty Scale )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠQu iz Session _. difficulty Scale ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) !! ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( search . is Cancelled Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= Ġspec . and ( equals ( search . is Cancelled , ĠQu iz Session _. is Cancelled )) !! ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( search . is Completed Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= Ġspec . and ( equals ( search . is Completed , ĠQu iz Session _. is Completed )) !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġspec ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Transactional ( readOnly Ġ= Ġtrue ) ĊĠĠĠ Ġoverride Ġfun Ġserialize Page ( page : ĠPage < Quiz Session >): ĠPage DTO Ġ= Ġpage . to DTO Ġ{ Ġit . to Full DTO () Ġ} ĊĊĠĠĠ Ġ@ Transactional ( readOnly Ġ= Ġtrue ) ĊĠĠĠ Ġoverride Ġfun Ġserialize Entity ( entity : ĠQu iz Session ): ĠQu iz Session Full DTO Ġ= ĊĠĠĠĠĠĠĠ Ġrepository . refresh ( entity ). to Full DTO () ĊĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġfun Ġcancel ( id : ĠLong ) Ġ= Ġget Owned Entity ( id ) ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentity Validator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. validate ( this , ĠTransition Constraint Group . CANCEL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. throw If Invalid Ġ{ ĠValidationError ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Cancelled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcancelled At Ġ= Ġnow ĊĠĠĠĠĠĠĠĠĠĠĠ ĠupdatedAt Ġ= Ġnow ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. let Ġ{ Ġrepository . save ( it ) Ġ} ĊĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġfun Ġcomplete ( id : ĠLong ) Ġ= Ġget Owned Entity ( id ) ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentity Validator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. validate ( this , ĠTransition Constraint Group . COMPLETE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. throw If Invalid Ġ{ ĠValidationError ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Completed Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompleted At Ġ= Ġnow ĊĠĠĠĠĠĠĠĠĠĠĠ ĠupdatedAt Ġ= Ġnow ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. let Ġ{ Ġrepository . save ( it ) Ġ} ĊĊĠĠĠ Ġ// ĠNothing Ġto Ġpatch ĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġoverride Ġfun Ġpatch ( id : ĠLong , Ġpatch DTO : ĠQu iz Session Patch DTO ): ĠQu iz Session Ġ= ĊĠĠĠĠĠĠĠ Ġget Owned Entity ( id ) ĊĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġfun Ġget Remaining Question Ids ( id : ĠLong ) Ġ= Ġget Owned Entity ( id ). let Ġ{ ĊĠĠĠĠĠĠĠ Ġquiz Session Question Repository . get Remaining Question Ids ( id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Transactional ĊĠĠĠ Ġfun Ġget Remaining Question Count ( id : ĠLong ) Ġ= Ġget Owned Entity ( id ). let Ġ{ ĊĠĠĠĠĠĠĠ Ġquiz Session Question Repository . get Remaining Question Count ( id ) ĊĠĠĠ Ġ} Ċ } Ċ