package Ġde . st ark ling . shopping cart . managers Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . room . Room Ċ import Ġde . st ark ling . shopping cart . database . Cart Database Ċ import Ġde . st ark ling . shopping cart . models . Cart Item Ċ import Ġde . st ark ling . shopping cart . models . Sale able Ċ import Ġkotlinx . coroutines .* Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠZ o ha ib ĠAk ram Ġon Ġ 2 0 2 0 - 0 1 - 2 8 Ċ Ġ* ĠCopyright ĠÂ© Ġ 2 0 1 9 ĠSt ark ling . ĠAll Ġrights Ġreserved . Ċ Ġ*/ Ċ Ċ class ĠCart Manager Ġprivate Ġconstructor ( context : ĠContext ) Ġ{ ĊĊĊĠĠĠ Ġprivate Ġval Ġcart Total : ĠMutable LiveData < Cart Total > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ ĠMutable LiveData < Cart Total >() ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġitems Ġ= ĠArrayList < Cart Item >() ĊĊĊĠĠĠ Ġprivate Ġvar Ġdb : ĠCart Database ĊĊĠĠĠ Ġinit Ġ{ ĊĊĠĠĠĠĠĠĠ Ġdb Ġ= ĠRoom . database Builder ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCart Database :: class . java , ĠDB _ NAME ĊĠĠĠĠĠĠĠ Ġ). build () ĊĊĠĠĠĠĠĠĠ Ġupdate Totals () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġlist Ġof Ġcart Ġitem ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Cart Items (): ĠArrayList < Cart Item > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcart Item Ġ= ĠArrayList < Cart Item >() ĊĠĠĠĠĠĠĠ Ġcart Item . addAll ( items ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcart Item ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠNotify Ġtotals Ġitems Ġand Ġtheir Ġamounts Ġwhen Ġitem Ġadd Ġor Ġremove Ġfrom Ġcart ĊĠĠĠĠ Ġ* Ġby Ġcalling Ġ# update Item ( sale able : ĠSale able ) ĊĠĠĠĠ Ġ* Ġ@ return ĠLive Data < Cart Total > ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsubscribe Cart Total (): ĠLive Data < Cart Total > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcart Total ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRemove Ġitem Ġfrom Ġcart Ġdb ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġremove Item ( sale able : ĠSale able ): ĠInt Ġ= Ġcoroutine Scope Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġdelete Result Ġ= Ġasync Ġ{ Ġdb . cart Item Dao (). delete ( sale able . getId ()) Ġ} ĊĠĠĠĠĠĠĠ Ġupdate Totals () ĊĠĠĠĠĠĠĠ Ġreturn @ coroutine Scope Ġdelete Result . await () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġitem Ġin Ġcart Ġdb Ġand Ġupdate Ġthe Ġtotals Ġitems Ġand Ġamounts ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġupdate Item ( sale able : ĠSale able ) Ġ= Ġcoroutine Scope Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġread Result Ġ= Ġasync Ġ{ Ġdb . cart Item Dao (). get ( sale able . getId ()) Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcart Item Ġ= Ġread Result . await () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( cart Item Ġ!= Ġnull ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sale able . get Quantity () Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdb . cart Item Dao (). delete ( sale able . getId ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcart Item . item Quantity Ġ= Ġsale able . get Quantity () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Result Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ Ġdb . cart Item Dao (). update ( sale able . getId (), Ġsale able . get Quantity ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Result . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Totals () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sale able . get Quantity () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinsert Result Ġ= Ġasync Ġ{ Ġdb . cart Item Dao (). insert ( Cart Item ( sale able )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinsert Result . await () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Totals () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMap Ġyour Ġsale able Ġlist Ġquantity Ġwith Ġthe Ġcart Ġitem Ġquantity ĊĠĠĠĠ Ġ* Ġ@ return ĠM apped Ġsale able Ġlist ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġ< T Ġ: ĠSale able > Ġmap With Cart ( sale able : ĠArrayList < T >): ĠArrayList < T > Ġ= Ġcoroutine Scope Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġproducts Ġ= Ġsale able Ġas ĠArrayList < Sale able > ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġasync Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġproducts . forEach Indexed Ġ{ Ġindex , Ġproduct Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcart Item : Cart Item ? Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitems . first Ġ{ Ġcart Item Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproduct . getId (). equals ( cart Item . getId (), Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : Exception ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( cart Item Ġ!= Ġnull ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproducts [ index ]. item Quantity Ġ= Ġcart Item . get Quantity () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} else { ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproducts [ index ]. item Quantity Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġresult . await () ĊĊĠĠĠĠĠĠĠ Ġreturn @ coroutine Scope Ġproducts Ġas ĠArrayList < T > ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġupdate Totals () Ġ{ ĊĊĠĠĠĠĠĠĠ ĠCor outine Scope ( Dispatch ers . Default ). launch Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġitems . clear () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġread Result Ġ= Ġasync Ġ{ Ġitems . addAll ( db . cart Item Dao (). getAll ()) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Result . await () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġtotal Cost Ġ= Ġ 0 . 0 f ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġitems . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Cost Ġ+= Ġit . getTotal () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcart Total . post Value ( Cart Total ( total Cost , Ġitems . size )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ: ĠSingleton Holder < Cart Manager , ĠContext >( :: Cart Manager ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDB _ NAME Ġ= Ġ" Shopping Cart DB " ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠH older Ġmodel Ġclass Ġfor Ġcart Ġtotal Ġinfo Ċ Ġ*/ Ċ data Ġclass ĠCart Total ( var Ġtotal Amount : ĠFloat , Ġvar Ġtotal Items : ĠInt ) ĊĊ Ċ open Ġclass ĠSingleton Holder < out ĠT Ġ: ĠAny , Ġin ĠA >( creator : Ġ( A ) Ġ-> ĠT ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġcreator : Ġ(( A ) Ġ-> ĠT )? Ġ= Ġcreator ĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġprivate Ġvar Ġinstance : ĠT ? Ġ= Ġnull ĊĊĠĠĠ Ġfun ĠgetInstance ( arg : ĠA ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġi Ġ= Ġinstance ĊĠĠĠĠĠĠĠ Ġif Ġ( i Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġi ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġi 2 Ġ= Ġinstance ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( i 2 Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcreated Ġ= Ġcreator !! ( arg ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstance Ġ= Ġcreated ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreator Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreated ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }