From 869bab77e93e2a6c776a4b1fc35ef0fd5df22f5f Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 27 Mar 2016 17:36:33 +0200 Subject: Compute payers client side rather than server side --- src/client/elm/Model/Income.elm | 65 ++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'src/client/elm/Model/Income.elm') diff --git a/src/client/elm/Model/Income.elm b/src/client/elm/Model/Income.elm index 97a5652..f364a8b 100644 --- a/src/client/elm/Model/Income.elm +++ b/src/client/elm/Model/Income.elm @@ -1,6 +1,9 @@ module Model.Income - ( Income - , incomeDecoder + ( Incomes + , Income + , IncomeId + , incomesDecoder + , incomeIdDecoder , incomeDefinedForAll , cumulativeIncomesSince ) where @@ -8,26 +11,46 @@ module Model.Income import Json.Decode as Json exposing ((:=)) import Time exposing (Time, hour) import List exposing (..) +import Dict exposing (Dict) import Model.Date exposing (timeDecoder) -import Model.User exposing (UserId) +import Model.User exposing (UserId, userIdDecoder) import Utils.Maybe exposing (isJust, catMaybes, maybeToList) +type alias Incomes = Dict IncomeId Income + +type alias IncomeId = Int + type alias Income = - { creation : Time + { userId : UserId + , creation : Time , amount : Int } +incomesDecoder : Json.Decoder Incomes +incomesDecoder = Json.map Dict.fromList (Json.list incomeWithIdDecoder) + +incomeWithIdDecoder : Json.Decoder (IncomeId, Income) +incomeWithIdDecoder = + Json.object2 (,) + ("id" := incomeIdDecoder) + incomeDecoder + +incomeIdDecoder : Json.Decoder IncomeId +incomeIdDecoder = Json.int + incomeDecoder : Json.Decoder Income incomeDecoder = - Json.object2 Income + Json.object3 Income + ("userId" := userIdDecoder) ("creation" := timeDecoder) ("amount" := Json.int) -incomeDefinedForAll : List (List Income) -> Maybe Time -incomeDefinedForAll usersIncomes = - let firstIncomes = map (head << sortBy .creation) usersIncomes +incomeDefinedForAll : List UserId -> Incomes -> Maybe Time +incomeDefinedForAll userIds incomes = + let userIncomes = List.map (\userId -> List.filter ((==) userId << .userId) << Dict.values <| incomes) userIds + firstIncomes = map (head << sortBy .creation) userIncomes in if all isJust firstIncomes then head << reverse << List.sort << map .creation << catMaybes <| firstIncomes else Nothing @@ -38,37 +61,39 @@ cumulativeIncomesSince currentTime since incomes = getOrderedIncomesSince : Time -> List Income -> List Income getOrderedIncomesSince time incomes = - let mbStarterIncome = getIncomesAt time incomes + let mbStarterIncome = getIncomeAt time incomes orderedIncomesSince = filter (\income -> income.creation >= time) incomes in (maybeToList mbStarterIncome) ++ orderedIncomesSince -getIncomesAt : Time -> List Income -> Maybe Income -getIncomesAt time incomes = +getIncomeAt : Time -> List Income -> Maybe Income +getIncomeAt time incomes = case incomes of [x] -> if x.creation < time - then Just { creation = time, amount = x.amount } + then Just { userId = x.userId, creation = time, amount = x.amount } else Nothing x1 :: x2 :: xs -> if x1.creation < time && x2.creation > time - then Just { creation = time, amount = x2.amount } - else getIncomesAt time (x2 :: xs) + then Just { userId = x2.userId, creation = time, amount = x2.amount } + else getIncomeAt time (x2 :: xs) [] -> Nothing cumulativeIncome : Time -> List Income -> Int cumulativeIncome currentTime incomes = - getIncomesWithDuration (incomes ++ [{ creation = currentTime, amount = 0 }]) + getIncomesWithDuration currentTime (List.sortBy .creation incomes) |> map durationIncome |> sum -getIncomesWithDuration : List Income -> List (Float, Int) -getIncomesWithDuration incomes = +getIncomesWithDuration : Time -> List Income -> List (Float, Int) +getIncomesWithDuration currentTime incomes = case incomes of - (income1 :: income2 :: xs) -> - (income2.creation - income1.creation, income1.amount) :: (getIncomesWithDuration (income2 :: xs)) - _ -> + [] -> [] + [income] -> + [(currentTime - income.creation, income.amount)] + (income1 :: income2 :: xs) -> + (income2.creation - income1.creation, income1.amount) :: (getIncomesWithDuration currentTime (income2 :: xs)) durationIncome : (Float, Int) -> Int durationIncome (duration, income) = -- cgit v1.2.3