package Ġuk . gov . just ice . digital . h mp ps . deli us api . service . contact Ċ Ċ import Ġorg . springframework . stereotype . Service Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . dto . v 1 . contact . Create OrUpdate Contact Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Contact Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Contact Outcome Type Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Contact Type Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . En forcement Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Event Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . N si Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Off ender Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Office Location Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Requirement Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Team Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . entity . Yes No Both Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . exception . BadRequest Exception Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . exception . Conflict Exception Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . repository . Contact Repository Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . repository . En forcement Action Repository Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . service . extensions . get Duration Ċ import Ġuk . gov . just ice . digital . h mp ps . deli us api . service . extensions . is Per miss ible Abs ence Ċ import Ġjava . math . BigDecimal Ċ import Ġjava . math . Round ingMode Ċ import Ġjava . time . LocalDate Ċ import Ġjava . time . Local Time Ċ Ċ @ Service Ċ class ĠContact Validation Service ( ĊĠ Ġprivate Ġval Ġcontact Repository : ĠContact Repository , ĊĠ Ġprivate Ġval Ġenforce ment Action Repository : ĠEn forcement Action Repository Ċ ) Ġ{ ĊĠ Ġfun Ġvalidate Contact Type ( request : ĠCreate OrUpdate Contact , Ġtype : ĠContact Type ) Ġ{ ĊĠĠĠ Ġif Ġ( request . alert Ġ&& Ġ! type . alert Flag ) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġdoes Ġnot Ġsupport Ġalert ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( type . re corded Hours Credit ed Ġ&& Ġrequest . endTime Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġrequires Ġan Ġend Ġtime ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġvalidate Outcome Type ( request : ĠCreate OrUpdate Contact , Ġtype : ĠContact Type ): ĠContact Outcome Type ? Ġ{ ĊĠĠĠ Ġfun Ġget () Ġ= Ġtype . outcome Types ?. find Ġ{ Ġit . code Ġ== Ġrequest . outcome Ġ} ĊĠĠĠĠĠ Ġ?: Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġwith Ġcode Ġ'${ type . code }' Ġdoes Ġnot Ġsupport Ġoutcome Ġcode Ġ'${ request . outcome }' ") ĊĊĠĠĠ Ġ// ĠThe Ġcases Ġhere Ġseem Ġodd Ġbut Ġlogic Ġhas Ġbeen Ġport ed Ġfrom ĠDel ius Ġwhere : ĊĠĠĠ Ġ// ĠY Ġ-> ĠOut come ĠMandatory Ġ( if Ġcontact Ġdate Ġis Ġin Ġthe Ġpast ) ĊĠĠĠ Ġ// ĠN Ġ-> ĠOut come ĠOptional ĊĠĠĠ Ġ// ĠB Ġ-> ĠOut come ĠNot ĠAllowed ĊĠĠĠ Ġval Ġoutcome Ġ= Ġwhen Ġ( type . outcome Flag ) Ġ{ ĊĠĠĠĠĠ ĠYes No Both . Y Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( request . outcome Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( request . date . is Before ( LocalDate . now ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġrequires Ġan Ġoutcome Ġtype Ġas Ġthe Ġcontact Ġdate Ġis Ġin Ġthe Ġpast Ġ'${ request . date }' ") ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġget () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ ĠYes No Both . N Ġ-> Ġif Ġ( request . outcome Ġ== Ġnull ) Ġnull Ġelse Ġget () ĊĠĠĠĠĠ ĠYes No Both . B Ġ-> Ġif Ġ( request . outcome Ġ== Ġnull ) Ġnull ĊĠĠĠĠĠ Ġelse Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġdoes Ġnot Ġsupport Ġan Ġoutcome Ġtype ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( outcome ?. is Per miss ible Abs ence () Ġ== Ġfalse Ġ&& Ġrequest . date . is After ( LocalDate . now ())) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Outcome Ġcode Ġ'${ outcome . code }' Ġnot Ġa Ġper miss ible Ġabsence Ġ- Ġonly Ġper miss ible Ġabs ences Ġcan Ġbe Ġrecorded Ġfor Ġa Ġfuture Ġatt endance ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġoutcome ĊĠ Ġ} ĊĊĠ Ġfun Ġset Outcome Meta ( contact : ĠContact ) Ġ{ ĊĠĠĠ Ġcontact . at tended Ġ= Ġcontact . outcome ?. attendance ĊĠĠĠ Ġcontact . comp lied Ġ= Ġcontact . outcome ?. comp liant Accept able ĊĊĠĠĠ Ġ// ĠIf Ġoff ender Ġhas Ġcomp lied Ġand Ġat tended Ġ( outcome Ġis Ġacceptable ) Ġthen Ġset Ġany Ġhours Ġcredit ed ĊĠĠĠ Ġif Ġ( contact . type . re corded Hours Credit ed Ġ&& Ġcontact . at tended Ġ== Ġtrue Ġ&& Ġcontact . comp lied Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠ Ġcontact . hours Credit ed Ġ= ĠBigDecimal . valueOf ( contact . get Duration (). to Minutes ()) ĊĠĠĠĠĠĠĠ Ġ. divide ( BigDecimal ( 6 0 )) ĊĠĠĠĠĠĠĠ Ġ. set Scale ( 2 , ĠRound ingMode . HALF _ UP ) ĊĠĠĠĠĠĠĠ Ġ. toDouble () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġcontact . hours Credit ed Ġ= Ġnull ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġvalidate En forcement ( request : ĠCreate OrUpdate Contact , Ġoutcome : ĠContact Outcome Type ?): ĠEn forcement ? Ġ{ ĊĠĠĠ Ġif Ġ( outcome Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġif Ġ( request . en forcement Ġ== Ġnull ) Ġnull ĊĠĠĠĠĠ Ġelse Ġthrow ĠBadRequest Exception (" En forcement Ġcannot Ġbe Ġprovided Ġwithout Ġan Ġoutcome ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( outcome . comp liant Accept able Ġ!= Ġfalse Ġ|| Ġoutcome . enforce able Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġif Ġ( request . en forcement Ġ== Ġnull ) Ġnull ĊĠĠĠĠĠ Ġelse Ġthrow ĠBadRequest Exception (" Outcome Ġ'${ outcome . code }' Ġis Ġnot Ġnon - comp liant Ġ& Ġenforce able , Ġenforce ment Ġaction Ġis Ġnot Ġsupported ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġenforce ment Ġ= ĠEn forcement ( ĊĠĠĠĠĠ Ġaction Taken Date Ġ= ĠLocalDate . now (), ĊĠĠĠĠĠ Ġaction Taken Time Ġ= ĠLocal Time . now (), ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġif Ġ( outcome . action Required ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( request . en forcement Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Outcome Ġ'${ outcome . code }' Ġrequires Ġan Ġenforce ment Ġaction ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġaction Ġ= Ġenforce ment Action Repository . findBy Code ( request . en forcement !! ) ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠBadRequest Exception (" En forcement Ġaction Ġ'${ request . en forcement }' Ġdoes Ġnot Ġexist ") ĊĠĠĠĠĠ Ġenforce ment . action Ġ= Ġaction ĊĠĠĠĠĠ Ġif Ġ( action . response By Period Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġenforce ment . response Date Ġ= ĠLocalDate . now (). plus Days ( action . response By Period !! ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġenforce ment ĊĠ Ġ} ĊĊĠ Ġfun Ġvalidate Office Location ( request : ĠCreate OrUpdate Contact , Ġtype : ĠContact Type , Ġteam : ĠTeam ): ĠOffice Location ? Ġ{ ĊĠĠĠ Ġfun Ġget () Ġ= Ġteam . office Locations ?. find Ġ{ Ġit . code Ġ== Ġrequest . office Location Ġ} ĊĠĠĠĠĠ Ġ?: Ġthrow ĠBadRequest Exception (" Team Ġwith Ġcode Ġ'${ request . team }' Ġdoes Ġnot Ġexist Ġat Ġoffice Ġlocation Ġ'${ request . office Location }' ") ĊĊĠĠĠ Ġreturn Ġwhen Ġ( type . location Flag ) Ġ{ ĊĠĠĠĠĠ ĠYes No Both . Y Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( request . office Location Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Location Ġis Ġrequired Ġfor Ġcontact Ġtype Ġ'${ type . code }' ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġget () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ ĠYes No Both . N Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( request . office Location Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġdoes Ġnot Ġsupport Ġa Ġlocation ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ ĠYes No Both . B Ġ-> Ġif Ġ( request . office Location Ġ== Ġnull ) Ġnull Ġelse Ġget () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġvalidate Future Appointment Cl ashes ( request : ĠCreate OrUpdate Contact , Ġtype : ĠContact Type , Ġoff ender : ĠOff ender , Ġexisting Id : ĠLong ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġif Ġ(! type . attendance Contact Ġ|| Ġrequest . endTime Ġ== Ġnull Ġ|| Ġ! request . date . is After ( LocalDate . now ())) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġcl ashes Ġ= Ġcontact Repository . find Cl ashing Attendance Contacts ( ĊĠĠĠĠĠ Ġoff ender . id , ĊĠĠĠĠĠ Ġrequest . date , ĊĠĠĠĠĠ Ġrequest . startTime , ĊĠĠĠĠĠ Ġrequest . endTime Ġas ĠLocal Time , ĊĠĠĠ Ġ). filter Ġ{ Ġit . id Ġ!= Ġexisting Id Ġ} ĊĊĠĠĠ Ġif Ġ( cl ashes . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġval Ġids Ġ= Ġcl ashes . join ToString (", Ġ") Ġ{ Ġ"' ${ it . id } '" Ġ} ĊĠĠĠĠĠ Ġthrow ĠConflict Exception ( ĊĠĠĠĠĠĠĠ Ġ" Contact Ġtype Ġ'${ type . code }' Ġis Ġan Ġatt endance Ġtype Ġso Ġmust Ġnot Ġcl ash Ġwith Ġany Ġother Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠ Ġ" attendance Ġcontacts Ġbut Ġcl ashes Ġwith Ġcontacts Ġwith Ġids Ġ$ ids " ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġvalidate Associated Entity ( ĊĠĠĠ Ġtype : ĠContact Type , ĊĠĠĠ Ġrequirement : ĠRequirement ? Ġ= Ġnull , ĊĠĠĠ Ġevent : ĠEvent ? Ġ= Ġnull , ĊĠĠĠ Ġn si : ĠN si ? Ġ= Ġnull , ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġif Ġ( ns i Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠContact Ġis Ġat Ġn si Ġlevel Ġ- Ġcontact Ġtype Ġmust Ġsupport Ġn si Ġtype ĊĠĠĠĠĠ Ġif Ġ( type . ns i Types ?. any Ġ{ Ġit . id Ġ== Ġn si . type . id Ġ} Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġis Ġnot Ġappropriate Ġfor Ġan ĠN SI Ġwith Ġtype Ġ'${ ns i . type . code }' ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġif Ġ( requirement Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠContact Ġis Ġat Ġ" Whole ĠOrder " Ġlevel Ġ- Ġtype Ġmust Ġbe Ġwhole Ġorder Ġlevel ĠOR Ġhave Ġmatching Ġrequirement Ġtype Ġcategory . ĊĠĠĠĠĠ Ġif Ġ(! type . whole Order Level Ġ&& Ġtype . requirement Type Categories ?. any Ġ{ Ġit . id Ġ== Ġrequirement . type Category ?. id Ġ} Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġis Ġnot Ġappropriate Ġfor Ġa Ġrequirement Ġin Ġcategory Ġ'${ requirement . type Category ?. code }' ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġif Ġ( event Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠContact Ġis Ġat Ġevent Ġlevel Ġ- Ġtype Ġmust Ġsupport Ġrelevant Ġpre / post ĠC JA Ġ 2 0 0 3 Ġstatus Ġof Ġevent . ĊĠĠĠĠĠ Ġ// ĠIt Ġlooks Ġlike Ġin ĠDel ius Ġthat Ġthese Ġare Ġnot Ġmut ually Ġexclusive ! ĊĠĠĠĠĠ Ġval Ġis Legacy Ġ= Ġevent . dis posals ?. any Ġ{ Ġit . type ?. legacy Order Ġ== Ġtrue Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠ Ġif Ġ( is Legacy Ġ&& Ġ! type . legacy Order Level ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġis Ġnot Ġappropriate Ġfor Ġa Ġpre ĠC JA Ġ 2 0 0 3 Ġevent ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġis C ja Ġ= Ġevent . dis posals ?. any Ġ{ Ġit . type ?. c ja 2 0 0 3 Order Ġ== Ġtrue Ġ} Ġ?: Ġfalse ĊĠĠĠĠĠ Ġif Ġ( is C ja Ġ&& Ġ! type . c ja Order Level ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġis Ġnot Ġappropriate Ġfor Ġa ĠC JA Ġ 2 0 0 3 Ġevent ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġ// ĠContact Ġis Ġat Ġoff ender Ġlevel ĊĠĠĠĠĠ Ġif Ġ(! type . off ender Level ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠBadRequest Exception (" Contact Ġtype Ġ'${ type . code }' Ġis Ġnot Ġappropriate Ġat Ġoff ender Ġlevel ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ