package Ġdev . well ing ton cost a . stock a Ċ Ċ import Ġkotlinx . datetime . LocalDate Ċ Ċ class ĠStock < out ĠT Ġ: ĠStock . Item > Ġ{ ĊĊĠĠĠ Ġsealed Ġinterface ĠItem ĊĊĠĠĠ Ġsealed Ġclass ĠEvent ( ĊĠĠĠĠĠĠĠ Ġval Ġtype : ĠType , ĊĠĠĠĠĠĠĠ Ġopen Ġval Ġamount : ĠInt , ĊĠĠĠĠĠĠĠ Ġopen Ġval Ġdate : ĠLocalDate ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġenum Ġclass ĠType Ġ{ ĠINPUT , ĠOUTPUT Ġ} ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠInput ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġamount : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġdate : ĠLocalDate , ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠEvent ( type Ġ= ĠType . INPUT , Ġamount , Ġdate ) ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠOutput ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġamount : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġdate : ĠLocalDate , ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠEvent ( type Ġ= ĠType . OUTPUT , Ġamount , Ġdate ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( item : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . id Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġthis . item Ġ= Ġitem ĊĠĠĠĠĠĠĠ Ġthis ._ events Ġ= Ġmutable ListOf < Event >() ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( id : ĠString , Ġitem : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . id Ġ= Ġid ĊĠĠĠĠĠĠĠ Ġthis . item Ġ= Ġitem ĊĠĠĠĠĠĠĠ Ġthis ._ events Ġ= Ġmutable ListOf < Event >() ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġconstructor ( id : ĠString , Ġitem : ĠT , Ġevents : ĠList < Event >) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . id Ġ= Ġid ĊĠĠĠĠĠĠĠ Ġthis . item Ġ= Ġitem ĊĠĠĠĠĠĠĠ Ġthis ._ events Ġ= Ġevents . to Mutable List () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġid : ĠString ? ĊĊĠĠĠ Ġval Ġitem : ĠT ĊĊĠĠĠ Ġprivate Ġval Ġ_ events : ĠMutable List < Event > ĊĊĠĠĠ Ġval Ġevents : ĠList < Event > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ_ events ĊĊĠĠĠ Ġval Ġavailable : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġaccumulator Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sorted By Descending Ġ{ Ġit . date Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Type . INPUT Ġ-> Ġaccumulator Ġ+= Ġit . amount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Type . OUTPUT Ġ-> Ġaccumulator Ġ-= Ġit . amount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġaccumulator ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġregister ( event : ĠEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Event Date ( event ) ĊĊĠĠĠĠĠĠĠ Ġcheck Amount Integr ity ( event ) ĊĊĠĠĠĠĠĠĠ Ġ_ events . add ( event ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Event Date ( event : ĠEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhas Previous Events Ġ= Ġevents . any Ġ{ Ġit . date Ġ> Ġevent . date Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( has Previous Events ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid Event Date Exception ( event . date ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Amount Integr ity ( event : ĠEvent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( event . type Ġ== ĠEvent . Type . OUTPUT Ġ&& Ġevent . amount Ġ> Ġavailable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIns ufficient Stock Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġavailable Amount Ġ= Ġavailable , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequested Amount Ġ= Ġevent . amount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }