module LoggedIn.Update ( update ) where import Dict import String import Task import Effects exposing (Effects) import Http exposing (Error(..)) import Date exposing (Date) import Model exposing (Model) import Model.Translations exposing (getMessage) import Model.Payment exposing (Payment, Frequency(..), deletePayment) import Server import LoggedData import LoggedIn.Action as LoggedInAction import LoggedIn.Model as LoggedInModel import LoggedIn.Home.Action as HomeAction import LoggedIn.Home.Update as HomeUpdate import LoggedIn.Income.Action as IncomeAction import LoggedIn.Income.Update as IncomeUpdate import LoggedIn.Home.AddPayment.Action as AddPaymentAction import LoggedIn.Home.AddPayment.Update as AddPaymentUpdate import Utils.Tuple as Tuple import Utils.Effects as Effects update : Model -> LoggedInAction.Action -> LoggedInModel.Model -> (LoggedInModel.Model, Effects LoggedInAction.Action) update model action loggedIn = let loggedData = LoggedData.build model loggedIn in case action of LoggedInAction.NoOp -> (loggedIn, Effects.none) LoggedInAction.HomeAction homeAction -> case HomeUpdate.update loggedData homeAction loggedIn.home of (home, effects) -> ( { loggedIn | home = home } , Effects.map LoggedInAction.HomeAction effects ) LoggedInAction.IncomeAction incomeAction -> case IncomeUpdate.update loggedData incomeAction loggedIn.income of (income, effects) -> ( { loggedIn | income = income } , Effects.map LoggedInAction.IncomeAction effects ) LoggedInAction.AddPayment name cost frequency -> update model (LoggedInAction.HomeAction <| HomeAction.UpdateAdd <| AddPaymentAction.WaitingServer) loggedIn |> Tuple.mapSnd (\effect -> Server.addPayment name cost frequency |> Task.map (\paymentId -> case String.toInt cost of Err _ -> LoggedInAction.HomeAction <| HomeAction.UpdateAdd (AddPaymentAction.AddError Nothing (Just (getMessage "CostRequired" loggedData.translations))) Ok costNumber -> LoggedInAction.ValidateAddPayment paymentId name costNumber frequency ) |> flip Task.onError (\err -> case err of BadResponse 400 jsonErr -> case AddPaymentUpdate.addPaymentError model.translations jsonErr of Just addPaymentAction -> Task.succeed (LoggedInAction.HomeAction <| HomeAction.UpdateAdd addPaymentAction) Nothing -> Task.succeed LoggedInAction.NoOp _ -> Task.succeed LoggedInAction.NoOp ) |> Effects.task |> \effect2 -> [effect, effect2] |> Effects.batch ) LoggedInAction.ValidateAddPayment paymentId name cost frequency -> update model (LoggedInAction.HomeAction <| HomeAction.UpdateAdd <| AddPaymentAction.Init frequency) loggedIn |> flip Effects.andThen (\loggedIn -> case frequency of Punctual -> update model (LoggedInAction.HomeAction <| HomeAction.UpdatePage 1) loggedIn Monthly -> update model (LoggedInAction.HomeAction <| HomeAction.ShowMonthlyDetail) loggedIn ) |> Tuple.mapFst (\loggedIn -> let newPayment = Payment paymentId (Date.fromTime model.currentTime) name cost loggedIn.me frequency in { loggedIn | payments = newPayment :: loggedIn.payments } ) LoggedInAction.DeletePayment paymentId -> ( loggedIn , Server.deletePayment paymentId |> Task.map (always (LoggedInAction.ValidateDeletePayment paymentId)) |> flip Task.onError (always <| Task.succeed LoggedInAction.NoOp) |> Effects.task ) LoggedInAction.ValidateDeletePayment paymentId -> ( { loggedIn | payments = deletePayment paymentId loggedIn.payments } , Effects.none ) LoggedInAction.AddIncome creation amount -> ( loggedIn , Server.addIncome creation amount |> Task.map (\incomeId -> (LoggedInAction.ValidateAddIncome incomeId creation amount)) |> flip Task.onError (always <| Task.succeed LoggedInAction.NoOp) |> Effects.task ) LoggedInAction.ValidateAddIncome incomeId creation amount -> let newIncome = { userId = loggedIn.me, creation = (Date.toTime creation), amount = amount } in ( { loggedIn | incomes = Dict.insert incomeId newIncome loggedIn.incomes } , Effects.none ) LoggedInAction.DeleteIncome incomeId -> ( loggedIn , Server.deleteIncome incomeId |> Task.map (always <| LoggedInAction.ValidateDeleteIncome incomeId) |> flip Task.onError (always <| Task.succeed LoggedInAction.NoOp) |> Effects.task ) LoggedInAction.ValidateDeleteIncome incomeId -> ( { loggedIn | incomes = Dict.remove incomeId loggedIn.incomes } , Effects.none )