aboutsummaryrefslogtreecommitdiff
path: root/src/client/elm/Model
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/elm/Model')
-rw-r--r--src/client/elm/Model/Category.elm35
-rw-r--r--src/client/elm/Model/Conf.elm4
-rw-r--r--src/client/elm/Model/Date.elm8
-rw-r--r--src/client/elm/Model/Income.elm37
-rw-r--r--src/client/elm/Model/Init.elm22
-rw-r--r--src/client/elm/Model/InitResult.elm16
-rw-r--r--src/client/elm/Model/Payer.elm9
-rw-r--r--src/client/elm/Model/Payment.elm61
-rw-r--r--src/client/elm/Model/PaymentCategory.elm48
-rw-r--r--src/client/elm/Model/Size.elm10
-rw-r--r--src/client/elm/Model/Translations.elm25
-rw-r--r--src/client/elm/Model/User.elm24
12 files changed, 193 insertions, 106 deletions
diff --git a/src/client/elm/Model/Category.elm b/src/client/elm/Model/Category.elm
new file mode 100644
index 0000000..8b653a7
--- /dev/null
+++ b/src/client/elm/Model/Category.elm
@@ -0,0 +1,35 @@
+module Model.Category exposing
+ ( Categories
+ , Category
+ , CategoryId
+ , categoriesDecoder
+ , categoryIdDecoder
+ , empty
+ )
+
+import Json.Decode as Decode exposing (Decoder)
+import Utils.Json as Json
+import Dict exposing (Dict)
+
+type alias Categories = Dict CategoryId Category
+
+type alias CategoryId = Int
+
+type alias Category =
+ { name : String
+ , color : String
+ }
+
+categoriesDecoder : Decoder Categories
+categoriesDecoder =
+ Json.dictDecoder (Decode.field "id" categoryIdDecoder) <|
+ Decode.map2
+ Category
+ (Decode.field "name" Decode.string)
+ (Decode.field "color" Decode.string)
+
+categoryIdDecoder : Decoder CategoryId
+categoryIdDecoder = Decode.int
+
+empty : Categories
+empty = Dict.empty
diff --git a/src/client/elm/Model/Conf.elm b/src/client/elm/Model/Conf.elm
index ec04622..308fa04 100644
--- a/src/client/elm/Model/Conf.elm
+++ b/src/client/elm/Model/Conf.elm
@@ -3,11 +3,11 @@ module Model.Conf exposing
, confDecoder
)
-import Json.Decode exposing (..)
+import Json.Decode as Decode exposing (Decoder)
type alias Conf =
{ currency : String
}
confDecoder : Decoder Conf
-confDecoder = object1 Conf ("currency" := string)
+confDecoder = Decode.map Conf (Decode.field "currency" Decode.string)
diff --git a/src/client/elm/Model/Date.elm b/src/client/elm/Model/Date.elm
index f3c9b91..bfba02f 100644
--- a/src/client/elm/Model/Date.elm
+++ b/src/client/elm/Model/Date.elm
@@ -4,12 +4,12 @@ module Model.Date exposing
)
import Date as Date exposing (Date)
+import Json.Decode as Decode exposing (Decoder)
+import Json.Decode.Extra as Decode
import Time exposing (Time)
-import Json.Decode as Json exposing (..)
-
timeDecoder : Decoder Time
-timeDecoder = Json.map Date.toTime dateDecoder
+timeDecoder = Decode.map Date.toTime dateDecoder
dateDecoder : Decoder Date
-dateDecoder = customDecoder string Date.fromString
+dateDecoder = Decode.string |> Decode.andThen (Date.fromString >> Decode.fromResult)
diff --git a/src/client/elm/Model/Income.elm b/src/client/elm/Model/Income.elm
index a5ca34b..34578c6 100644
--- a/src/client/elm/Model/Income.elm
+++ b/src/client/elm/Model/Income.elm
@@ -9,7 +9,8 @@ module Model.Income exposing
, cumulativeIncomesSince
)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
+import Utils.Json as Json
import Time exposing (Time, hour)
import List exposing (..)
import Dict exposing (Dict)
@@ -17,7 +18,7 @@ import Dict exposing (Dict)
import Model.Date exposing (timeDecoder)
import Model.User exposing (UserId, userIdDecoder)
-import Utils.Maybe exposing (isJust, catMaybes, maybeToList)
+import Utils.Maybe as Maybe
type alias Incomes = Dict IncomeId Income
@@ -29,31 +30,23 @@ type alias Income =
, amount : Int
}
-incomesDecoder : Json.Decoder Incomes
-incomesDecoder = Json.map Dict.fromList (Json.list incomeWithIdDecoder)
+incomesDecoder : Decoder Incomes
+incomesDecoder =
+ Json.dictDecoder (Decode.field "id" incomeIdDecoder) <|
+ Decode.map3 Income
+ (Decode.field "userId" userIdDecoder)
+ (Decode.field "date" timeDecoder)
+ (Decode.field "amount" Decode.int)
-incomeWithIdDecoder : Json.Decoder (IncomeId, Income)
-incomeWithIdDecoder =
- Json.object2 (,)
- ("id" := incomeIdDecoder)
- incomeDecoder
-
-incomeIdDecoder : Json.Decoder IncomeId
-incomeIdDecoder = Json.int
-
-incomeDecoder : Json.Decoder Income
-incomeDecoder =
- Json.object3 Income
- ("userId" := userIdDecoder)
- ("date" := timeDecoder)
- ("amount" := Json.int)
+incomeIdDecoder : Decoder IncomeId
+incomeIdDecoder = Decode.int
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 .time) userIncomes
- in if all isJust firstIncomes
- then head << reverse << List.sort << map .time << catMaybes <| firstIncomes
+ in if all Maybe.isJust firstIncomes
+ then head << reverse << List.sort << map .time << Maybe.cat <| firstIncomes
else Nothing
userCumulativeIncomeSince : Time -> Time -> Incomes -> UserId -> Int
@@ -71,7 +64,7 @@ getOrderedIncomesSince : Time -> List Income -> List Income
getOrderedIncomesSince time incomes =
let mbStarterIncome = getIncomeAt time incomes
orderedIncomesSince = filter (\income -> income.time >= time) incomes
- in (maybeToList mbStarterIncome) ++ orderedIncomesSince
+ in (Maybe.toList mbStarterIncome) ++ orderedIncomesSince
getIncomeAt : Time -> List Income -> Maybe Income
getIncomeAt time incomes =
diff --git a/src/client/elm/Model/Init.elm b/src/client/elm/Model/Init.elm
index 3a86dba..db7069f 100644
--- a/src/client/elm/Model/Init.elm
+++ b/src/client/elm/Model/Init.elm
@@ -3,23 +3,29 @@ module Model.Init exposing
, initDecoder
)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
import Model.Payment exposing (Payments, paymentsDecoder)
-import Model.Income exposing (Incomes, incomesDecoder)
import Model.User exposing (Users, UserId, usersDecoder, userIdDecoder)
+import Model.Income exposing (Incomes, incomesDecoder)
+import Model.Category exposing (Categories, categoriesDecoder)
+import Model.PaymentCategory exposing (PaymentCategories, paymentCategoriesDecoder)
type alias Init =
{ users : Users
, me : UserId
, payments : Payments
, incomes : Incomes
+ , categories : Categories
+ , paymentCategories : PaymentCategories
}
-initDecoder : Json.Decoder Init
+initDecoder : Decoder Init
initDecoder =
- Json.object4 Init
- ("users" := usersDecoder)
- ("me" := userIdDecoder)
- ("payments" := paymentsDecoder)
- ("incomes" := incomesDecoder)
+ Decode.map6 Init
+ (Decode.field "users" usersDecoder)
+ (Decode.field "me" userIdDecoder)
+ (Decode.field "payments" paymentsDecoder)
+ (Decode.field "incomes" incomesDecoder)
+ (Decode.field "categories" categoriesDecoder)
+ (Decode.field "paymentCategories" paymentCategoriesDecoder)
diff --git a/src/client/elm/Model/InitResult.elm b/src/client/elm/Model/InitResult.elm
index c8da533..7ce0be2 100644
--- a/src/client/elm/Model/InitResult.elm
+++ b/src/client/elm/Model/InitResult.elm
@@ -3,7 +3,7 @@ module Model.InitResult exposing
, initResultDecoder
)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
import Model.Init exposing (Init, initDecoder)
@@ -12,17 +12,17 @@ type InitResult =
| InitSuccess Init
| InitError String
-initResultDecoder : Json.Decoder InitResult
-initResultDecoder = ("tag" := Json.string) `Json.andThen` initResultDecoderWithTag
+initResultDecoder : Decoder InitResult
+initResultDecoder = (Decode.field "tag" Decode.string) |> Decode.andThen initResultDecoderWithTag
-initResultDecoderWithTag : String -> Json.Decoder InitResult
+initResultDecoderWithTag : String -> Decoder InitResult
initResultDecoderWithTag tag =
case tag of
"InitEmpty" ->
- Json.succeed InitEmpty
+ Decode.succeed InitEmpty
"InitSuccess" ->
- Json.map InitSuccess ("contents" := initDecoder)
+ Decode.map InitSuccess (Decode.field "contents" initDecoder)
"InitError" ->
- Json.map InitError ("contents" := Json.string)
+ Decode.map InitError (Decode.field "contents" Decode.string)
_ ->
- Json.fail <| "got " ++ tag ++ " for InitResult"
+ Decode.fail <| "got " ++ tag ++ " for InitResult"
diff --git a/src/client/elm/Model/Payer.elm b/src/client/elm/Model/Payer.elm
index e5a4b65..1663273 100644
--- a/src/client/elm/Model/Payer.elm
+++ b/src/client/elm/Model/Payer.elm
@@ -6,7 +6,6 @@ module Model.Payer exposing
, useIncomesFrom
)
-import Json.Decode as Json exposing (..)
import Dict exposing (..)
import List
import Maybe
@@ -54,7 +53,7 @@ getOrderedExceedingPayers currentTime users incomes payments =
mbMaxRatio =
postPaymentPayers
|> Dict.toList
- |> List.map (.ratio << snd)
+ |> List.map (.ratio << Tuple.second)
|> List.maximum
in case mbMaxRatio of
Just maxRatio ->
@@ -110,15 +109,15 @@ getPayers currentTime users incomes payments =
exceedingPayersFromAmounts : List (UserId, Int) -> List ExceedingPayer
exceedingPayersFromAmounts userAmounts =
- let mbMinAmount = List.minimum << List.map snd <| userAmounts
+ let mbMinAmount = List.minimum << List.map Tuple.second <| userAmounts
in case mbMinAmount of
Nothing ->
[]
Just minAmount ->
userAmounts
|> List.map (\userAmount ->
- { userId = fst userAmount
- , amount = snd userAmount - minAmount
+ { userId = Tuple.first userAmount
+ , amount = Tuple.second userAmount - minAmount
}
)
|> List.filter (\payer -> payer.amount > 0)
diff --git a/src/client/elm/Model/Payment.elm b/src/client/elm/Model/Payment.elm
index 5109b2f..f61ded8 100644
--- a/src/client/elm/Model/Payment.elm
+++ b/src/client/elm/Model/Payment.elm
@@ -6,6 +6,7 @@ module Model.Payment exposing
, Frequency(..)
, paymentsDecoder
, paymentIdDecoder
+ , find
, edit
, delete
, totalPayments
@@ -18,15 +19,16 @@ module Model.Payment exposing
import Date exposing (..)
import Date.Extra.Core exposing (monthToInt, intToMonth)
-import Json.Decode as Json exposing ((:=))
-import String
+import Json.Decode as Decode exposing (Decoder)
+import Json.Decode.Extra as Decode
import List
import Form.Validate as Validate exposing (Validation)
-import Model.User exposing (UserId, userIdDecoder)
import Model.Date exposing (dateDecoder)
+import Model.User exposing (UserId, userIdDecoder)
import Utils.List as List
+import Utils.Search as Search
perPage : Int
perPage = 7
@@ -46,31 +48,36 @@ type alias PaymentId = Int
type Frequency = Punctual | Monthly
-paymentsDecoder : Json.Decoder Payments
-paymentsDecoder = Json.list paymentDecoder
+paymentsDecoder : Decoder Payments
+paymentsDecoder = Decode.list paymentDecoder
-paymentDecoder : Json.Decoder Payment
+paymentDecoder : Decoder Payment
paymentDecoder =
- Json.object6 Payment
- ("id" := paymentIdDecoder)
- ("name" := Json.string)
- ("cost" := Json.int)
- ("date" := dateDecoder)
- ("userId" := userIdDecoder)
- ("frequency" := frequencyDecoder)
-
-paymentIdDecoder : Json.Decoder PaymentId
-paymentIdDecoder = Json.int
-
-frequencyDecoder : Json.Decoder Frequency
+ Decode.map6 Payment
+ (Decode.field "id" paymentIdDecoder)
+ (Decode.field "name" Decode.string)
+ (Decode.field "cost" Decode.int)
+ (Decode.field "date" dateDecoder)
+ (Decode.field "userId" userIdDecoder)
+ (Decode.field "frequency" frequencyDecoder)
+
+paymentIdDecoder : Decoder PaymentId
+paymentIdDecoder = Decode.int
+
+frequencyDecoder : Decoder Frequency
frequencyDecoder =
- Json.customDecoder
- Json.string
- (\input -> case input of
- "Punctual" -> Ok Punctual
- "Monthly" -> Ok Monthly
- _ -> Err ("Could not deduce Punctual nor Monthly from " ++ input)
- )
+ let frequencyResult input =
+ case input of
+ "Punctual" -> Ok Punctual
+ "Monthly" -> Ok Monthly
+ _ -> Err ("Could not deduce Punctual nor Monthly from " ++ input)
+ in Decode.string |> Decode.andThen (Decode.fromResult << frequencyResult)
+
+find : PaymentId -> Payments -> Maybe Payment
+find paymentId payments =
+ payments
+ |> List.filter (\p -> p.id == paymentId)
+ |> List.head
edit : Payment -> Payments -> Payments
edit payment payments = payment :: delete payment.id payments
@@ -98,7 +105,7 @@ groupAndSortByMonth : Payments -> List ((Month, Int), Payments)
groupAndSortByMonth payments =
payments
|> List.groupBy (\payment -> (Date.year payment.date, monthToInt << Date.month <| payment.date))
- |> List.sortBy fst
+ |> List.sortBy Tuple.first
|> List.map (\((year, month), payments) -> ((intToMonth month, year), payments))
|> List.reverse
@@ -118,7 +125,7 @@ paymentSort frequency =
searchSuccess : String -> Payment -> Bool
searchSuccess search { name, cost } =
let searchSuccessWord word =
- ( String.contains (String.toLower word) (String.toLower name)
+ ( String.contains (Search.format word) (Search.format name)
|| String.contains word (toString cost)
)
in List.all searchSuccessWord (String.words search)
diff --git a/src/client/elm/Model/PaymentCategory.elm b/src/client/elm/Model/PaymentCategory.elm
new file mode 100644
index 0000000..87678fe
--- /dev/null
+++ b/src/client/elm/Model/PaymentCategory.elm
@@ -0,0 +1,48 @@
+module Model.PaymentCategory exposing
+ ( PaymentCategories
+ , paymentCategoriesDecoder
+ , search
+ , isCategoryUnused
+ , set
+ , update
+ )
+
+import Dict exposing (Dict)
+import Json.Decode as Decode exposing (Decoder)
+
+import Model.Category exposing (CategoryId, categoryIdDecoder)
+import Utils.Json as Json
+import Utils.Search as Search
+
+type alias PaymentCategories = List PaymentCategory
+
+type alias PaymentCategory =
+ { name : String
+ , category : CategoryId
+ }
+
+paymentCategoriesDecoder : Decoder PaymentCategories
+paymentCategoriesDecoder =
+ Decode.list <| Decode.map2 PaymentCategory
+ (Decode.field "name" Decode.string)
+ (Decode.field "category" categoryIdDecoder)
+
+search : String -> PaymentCategories -> Maybe CategoryId
+search paymentName paymentCategories =
+ paymentCategories
+ |> List.filter (\pc -> Search.format pc.name == Search.format paymentName)
+ |> List.head
+ |> Maybe.map .category
+
+isCategoryUnused : CategoryId -> PaymentCategories -> Bool
+isCategoryUnused category paymentCategories =
+ paymentCategories
+ |> List.filter ((==) category << .category)
+ |> List.isEmpty
+
+set : String -> CategoryId -> PaymentCategories -> PaymentCategories
+set name category paymentCategories = update name name category paymentCategories
+
+update : String -> String -> CategoryId -> PaymentCategories -> PaymentCategories
+update oldName newName category paymentCategories =
+ { name = newName, category = category } :: List.filter (\pc -> not <| Search.format pc.name == Search.format oldName) paymentCategories
diff --git a/src/client/elm/Model/Size.elm b/src/client/elm/Model/Size.elm
index b29e90b..f40fb01 100644
--- a/src/client/elm/Model/Size.elm
+++ b/src/client/elm/Model/Size.elm
@@ -3,15 +3,15 @@ module Model.Size exposing
, sizeDecoder
)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
type alias Size =
{ width: Int
, height: Int
}
-sizeDecoder : Json.Decoder Size
+sizeDecoder : Decoder Size
sizeDecoder =
- Json.object2 Size
- ("width" := Json.int)
- ("height" := Json.int)
+ Decode.map2 Size
+ (Decode.field "width" Decode.int)
+ (Decode.field "height" Decode.int)
diff --git a/src/client/elm/Model/Translations.elm b/src/client/elm/Model/Translations.elm
index 57409b0..9b314e1 100644
--- a/src/client/elm/Model/Translations.elm
+++ b/src/client/elm/Model/Translations.elm
@@ -7,13 +7,13 @@ module Model.Translations exposing
)
import Maybe exposing (withDefault)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
import String
type alias Translations = List Translation
-translationsDecoder : Json.Decoder Translations
-translationsDecoder = Json.list translationDecoder
+translationsDecoder : Decoder Translations
+translationsDecoder = Decode.list translationDecoder
type alias Translation =
{ key : String
@@ -27,25 +27,24 @@ getTranslation key translations =
|> List.head
|> Maybe.map .message
-translationDecoder : Json.Decoder Translation
+translationDecoder : Decoder Translation
translationDecoder =
- Json.object2 Translation
- ("key" := Json.string)
- ("message" := Json.list partDecoder)
+ Decode.map2 Translation
+ (Decode.field "key" Decode.string)
+ (Decode.field "message" (Decode.list partDecoder))
type MessagePart =
Order Int
| Str String
-partDecoder : Json.Decoder MessagePart
-partDecoder =
- ("tag" := Json.string) `Json.andThen` partDecoderWithTag
+partDecoder : Decoder MessagePart
+partDecoder = (Decode.field "tag" Decode.string) |> Decode.andThen partDecoderWithTag
-partDecoderWithTag : String -> Json.Decoder MessagePart
+partDecoderWithTag : String -> Decoder MessagePart
partDecoderWithTag tag =
case tag of
- "Order" -> Json.object1 Order ("contents" := Json.int)
- _ -> Json.object1 Str ("contents" := Json.string)
+ "Order" -> Decode.map Order (Decode.field "contents" Decode.int)
+ _ -> Decode.map Str (Decode.field "contents" Decode.string)
-----
diff --git a/src/client/elm/Model/User.elm b/src/client/elm/Model/User.elm
index 02f2cea..f6e8147 100644
--- a/src/client/elm/Model/User.elm
+++ b/src/client/elm/Model/User.elm
@@ -8,7 +8,7 @@ module Model.User exposing
, getUserName
)
-import Json.Decode as Json exposing ((:=))
+import Json.Decode as Decode exposing (Decoder)
import Dict exposing (Dict)
type alias Users = Dict UserId User
@@ -20,23 +20,23 @@ type alias User =
, email : String
}
-usersDecoder : Json.Decoder Users
-usersDecoder = Json.map Dict.fromList (Json.list userWithIdDecoder)
+usersDecoder : Decoder Users
+usersDecoder = Decode.map Dict.fromList (Decode.list userWithIdDecoder)
-userWithIdDecoder : Json.Decoder (UserId, User)
+userWithIdDecoder : Decode.Decoder (UserId, User)
userWithIdDecoder =
- Json.object2 (,)
- ("id" := userIdDecoder)
+ Decode.map2 (,)
+ (Decode.field "id" userIdDecoder)
userDecoder
-userIdDecoder : Json.Decoder UserId
-userIdDecoder = Json.int
+userIdDecoder : Decoder UserId
+userIdDecoder = Decode.int
-userDecoder : Json.Decoder User
+userDecoder : Decoder User
userDecoder =
- Json.object2 User
- ("name" := Json.string)
- ("email" := Json.string)
+ Decode.map2 User
+ (Decode.field "name" Decode.string)
+ (Decode.field "email" Decode.string)
getUserName : Users -> UserId -> Maybe String
getUserName users userId =