package Ġcom . pat lo ew . o eff itr acker . ui . ticket . create Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Bundle Ċ import Ġandroidx . activity . compose . setContent Ċ import Ġandroidx . activity . result . contract . Activity Result Contract Ċ import Ġandroidx . annotation . String Res Ċ import Ġandroidx . fragment . app . Fragment Activity Ċ import Ġandroidx . lifecycle . Lifecycle Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . flow With Lifecycle Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġcom . pat lo ew . o eff itr acker . R Ċ import Ġcom . pat lo ew . o eff itr acker . data . model . Ticket Ċ import Ġcom . pat lo ew . o eff itr acker . data . repository . Ticket Dao Ċ import Ġcom . pat lo ew . o eff itr acker . ui . check AndSet Amount Ċ import Ġcom . pat lo ew . o eff itr acker . ui . date Format Ċ import Ġcom . pat lo ew . o eff itr acker . ui . format Amount Ċ import Ġcom . pat lo ew . o eff itr acker . ui . show DatePicker Ċ import Ġcom . pat lo ew . o eff itr acker . ui . theme . O eff i Tracker Theme Ċ import Ġcom . pat lo ew . o eff itr acker . ui . viewModel Factory Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . Mutable State Flow Ċ import Ġkotlinx . coroutines . flow . collect Ċ import Ġkotlinx . coroutines . flow . combine Ċ import Ġkotlinx . coroutines . flow . map Ċ import Ġkotlinx . coroutines . flow . receive As Flow Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . k oin . android . ext . android . inject Ċ import Ġjava . time . LocalDate Ċ Ċ /* ĠCopyright Ġ 2 0 2 1 ĠPat rick ĠL Ã¶ wen stein Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ġ*/ Ċ Ċ private Ġconst Ġval ĠEX TRA _ EDIT _ TICK ET Ġ= Ġ" edit Ticket " Ċ Ċ class ĠCreate Ticket Activity Ġ: ĠFragment Activity () Ġ{ ĊĊĠĠĠ Ġobject ĠCreate Contract Ġ: ĠActivity Result Contract < Unit , ĠBoolean >() Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcreate Intent ( context : ĠContext , Ġinput : ĠUnit ): ĠIntent Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( context , ĠCreate Ticket Activity :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġparse Result ( result Code : ĠInt , Ġintent : ĠIntent ?): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠresultCode Ġ== ĠActivity . RESULT _ OK ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġobject ĠEdit Contract Ġ: ĠActivity Result Contract < Ticket , ĠBoolean >() Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcreate Intent ( context : ĠContext , Ġinput : ĠTicket ): ĠIntent Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( context , ĠCreate Ticket Activity :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Extra ( EXTRA _ EDIT _ TICK ET , Ġinput ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġparse Result ( result Code : ĠInt , Ġintent : ĠIntent ?): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠresultCode Ġ== ĠActivity . RESULT _ OK ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠviewModel Factory : ĠCreate Ticket ViewModel . Factory Ġby Ġinject () ĊĠĠĠ Ġprivate Ġval ĠviewModel : ĠCreate Ticket ViewModel Ġby ĠviewModel Factory Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġedit Ticket : ĠTicket ? Ġ= Ġintent . get Parcelable Extra ( EXTRA _ EDIT _ TICK ET ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġedit Ticket Ġ!= Ġnull Ġ-> ĠviewModel Factory . edit ( edit Ticket ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠviewModel Factory . create () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĊĠĠĠĠĠĠĠ Ġset Content Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠO eff i Tracker Theme Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCreate Ticket Screen ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnavigation Action Ġ= Ġ{ Ġfinish () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon StartDate Click Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow DatePicker ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpre Selected Ġ= ĠviewModel . startDate . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsupport FragmentManager ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ Ġselected Date Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . startDate . value Ġ= Ġselected Date ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon EndDate Click Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow DatePicker ( pre Selected Ġ= ĠviewModel . endDate . value , Ġsupport FragmentManager ) Ġ{ Ġselected Date Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . endDate . value Ġ= Ġselected Date ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonCreate Click Ġ= Ġ{ ĠviewModel . onCreate () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . finish Event . flow With Lifecycle ( lifecycle , ĠLifecycle . State . STARTED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Result ( Activity . RESULT _ OK ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠCreate Ticket ViewModel ( ĊĠĠĠ Ġprivate Ġval Ġticket Dao : ĠTicket Dao , ĊĠĠĠ Ġprivate Ġval Ġedit Ticket : ĠTicket ?, Ċ ) Ġ: ĠViewModel () Ġ{ ĊĊĠĠĠ Ġ@ String Res ĊĠĠĠ Ġval Ġtoolbar Title Res : ĠInt Ġ= Ġif Ġ( edit Ticket Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ ĠR . string . toolbar _ title _ create _ ticket ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠR . string . toolbar _ title _ edit _ ticket ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ String Res ĊĠĠĠ Ġval Ġbutton Text Res : ĠInt Ġ= Ġif Ġ( edit Ticket Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ ĠR . string . button _ add ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠR . string . button _ edit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġname : ĠMutable State Flow < String > Ġ= ĠMutable State Flow ( edit Ticket ?. name Ġ?: Ġ"") ĊĊĠĠĠ Ġval ĠstartDate : ĠMutable State Flow < LocalDate > Ġ= ĠMutable State Flow ( edit Ticket ?. startDate Ġ?: ĠLocalDate . now ()) ĊĠĠĠ Ġval ĠstartDate String : ĠFlow < String > Ġ= ĠstartDate . map Ġ{ ĠdateFormat . format ( it ) Ġ} ĊĊĠĠĠ Ġval ĠendDate : ĠMutable State Flow < LocalDate > Ġ= ĊĠĠĠĠĠĠĠ ĠMutable State Flow ( edit Ticket ?. endDate Ġ?: ĠLocalDate . now (). plus Years ( 1 ). minus Days ( 1 )) ĊĠĠĠ Ġval ĠendDate String : ĠFlow < String > Ġ= ĠendDate . map Ġ{ ĠdateFormat . format ( it ) Ġ} ĊĊĠĠĠ Ġval Ġoverlapping Ticket : ĠFlow < Ticket ?> Ġ= Ġcombine ( startDate , ĠendDate ) Ġ{ ĠstartDate , ĠendDate Ġ-> ĊĠĠĠĠĠĠĠ Ġticket Dao . getFirst Two Over lapping Validity Tickets ( startDate , ĠendDate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull Ġ{ Ġit . id Ġ!= Ġedit Ticket ?. id Ġ} Ġ// ĠDon 't Ġcheck Ġoverlapping Ġof Ġself Ġwhen Ġediting ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval ĠendDate Before StartDate : ĠFlow < Boolean > Ġ= ĊĠĠĠĠĠĠĠ Ġcombine ( startDate , ĠendDate ) Ġ{ ĠstartDate , ĠendDate Ġ-> ĠendDate Ġ<= ĠstartDate Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġprice : ĠMutable State Flow < Long ?> Ġ= ĠMutable State Flow ( edit Ticket ?. price ) ĊĠĠĠ Ġval Ġinitial Price Ġ= Ġedit Ticket ?. price . format Amount () Ġ?: Ġ"" ĊĊĠĠĠ Ġprivate Ġval Ġde duction : ĠMutable State Flow < Long ?> Ġ= ĠMutable State Flow ( edit Ticket ?. ded uction ) ĊĠĠĠ Ġval Ġinitial Ded uction Ġ= Ġedit Ticket ?. ded uction . format Amount () Ġ?: Ġ"" ĊĊĠĠĠ Ġval Ġsave Enabled : ĠFlow < Boolean > Ġ= Ġcombine ( ĊĠĠĠĠĠĠĠ Ġname , ĊĠĠĠĠĠĠĠ Ġprice , ĊĠĠĠĠĠĠĠ ĠstartDate , ĊĠĠĠĠĠĠĠ ĠendDate , ĊĠĠĠĠĠĠĠ Ġoverlapping Ticket ĊĠĠĠ Ġ) Ġ{ Ġname , Ġprice , ĠstartDate , ĠendDate , Ġoverlapping Ticket Ġ-> ĊĠĠĠĠĠĠĠ Ġname . isNotEmpty () Ġ&& Ġprice Ġ!= Ġnull Ġ&& Ġprice Ġ> Ġ 0 Ġ&& ĠstartDate Ġ< ĠendDate Ġ&& Ġoverlapping Ticket Ġ== Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġfinish Channel : ĠChannel < Unit > Ġ= ĠChannel ( Channel . CON FL ATED ) ĊĠĠĠ Ġval Ġfinish Event : ĠFlow < Unit > Ġ= Ġfinish Channel . receive As Flow () ĊĊĠĠĠ Ġfun ĠonCreate () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( edit Ticket Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġticket Dao . update ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedit Ticket . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġname . value . trim (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprice Ġ= Ġprice . value !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġde duction Ġ= Ġde duction . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate Ġ= ĠstartDate . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate Ġ= ĠendDate . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġticket Dao . insert ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTicket ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġname . value . trim (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprice Ġ= Ġprice . value !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġde duction Ġ= Ġde duction . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartDate Ġ= ĠstartDate . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠendDate Ġ= ĠendDate . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreated Timestamp Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish Channel . send ( Unit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġand Ġvalidates Ġprice Ġand Ġsets Ġit Ġif Ġvalid . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġprice Ġis Ġvalid ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Price ( price String : ĠString ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġcheck AndSet Amount ( price String ) Ġ{ Ġnew Price Ġ-> Ġprice . value Ġ= Ġnew Price Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġand Ġvalidates Ġde duction Ġand Ġsets Ġit Ġif Ġvalid . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġde duction Ġis Ġvalid ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Ded uction ( ded uction String : ĠString ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġcheck AndSet Amount ( ded uction String ) Ġ{ Ġnew Ded uction Ġ-> Ġde duction . value Ġ= Ġnew Ded uction Ġ} ĊĊĠĠĠ Ġclass ĠFactory ( private Ġval Ġticket Dao : ĠTicket Dao ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġcreate () Ġ= ĠCreate Ticket ViewModel ( ticket Dao , Ġedit Ticket Ġ= Ġnull ) ĊĠĠĠĠĠĠĠ Ġfun Ġedit ( ticket : ĠTicket ) Ġ= ĠCreate Ticket ViewModel ( ticket Dao , Ġedit Ticket Ġ= Ġticket ) ĊĠĠĠ Ġ} Ċ }