module Model.Payment ( perPage , Payments , Payment , PaymentId , Frequency(..) , paymentsDecoder , paymentIdDecoder , deletePayment , totalPayments , punctual , monthly , groupAndSortByMonth ) where import Date exposing (..) import Json.Decode as Json exposing ((:=)) import Model.User exposing (UserId, userIdDecoder) import Model.Date exposing (dateDecoder) import Utils.List as List import Utils.Date as Date perPage : Int perPage = 8 type alias Payments = List Payment type alias Payment = { id : PaymentId , creation : Date , name : String , cost : Int , userId : UserId , frequency : Frequency } type alias PaymentId = Int type Frequency = Punctual | Monthly paymentsDecoder : Json.Decoder Payments paymentsDecoder = Json.list paymentDecoder paymentDecoder : Json.Decoder Payment paymentDecoder = Json.object6 Payment ("id" := paymentIdDecoder) ("creation" := dateDecoder) ("name" := Json.string) ("cost" := Json.int) ("userId" := userIdDecoder) ("frequency" := frequencyDecoder) paymentIdDecoder : Json.Decoder PaymentId paymentIdDecoder = Json.int frequencyDecoder : Json.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) ) deletePayment : PaymentId -> Payments -> Payments deletePayment paymentId = List.filter (((/=) paymentId) << .id) totalPayments : (Payment -> Bool) -> UserId -> Payments -> Int totalPayments paymentFilter userId payments = payments |> List.filter (\payment -> paymentFilter payment && payment.userId == userId && payment.frequency == Punctual ) |> List.map .cost |> List.sum punctual : Payments -> Payments punctual = List.filter ((==) Punctual << .frequency) monthly : UserId -> Payments -> Payments monthly userId = List.filter (\p -> p.frequency == Monthly && p.userId == userId) groupAndSortByMonth : Payments -> List ((Month, Int), Payments) groupAndSortByMonth payments = payments |> List.groupBy (\payment -> (Date.year payment.creation, Date.monthToNum << Date.month <| payment.creation)) |> List.sortBy fst |> List.map (\((year, month), payments) -> ((Date.numToMonth month, year), payments)) |> List.reverse