From 88cca41114a04f7cb6e8bda9ce72b836dbbddf6e Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Sat, 15 Mar 2025 20:57:33 +0100 Subject: Updates as query strings --- front/src/Main.elm | 111 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/front/src/Main.elm b/front/src/Main.elm index 68ead13..4b7692f 100644 --- a/front/src/Main.elm +++ b/front/src/Main.elm @@ -29,7 +29,6 @@ import Html.Attributes exposing ( class , disabled - , href , max , min , placeholder @@ -233,6 +232,7 @@ type alias RawSpecs = , years : String , vat : String , fee : String + , updates : SimUpdates } @@ -246,6 +246,7 @@ defaultRawSpecs = , years = "30" , vat = "6" , fee = "3" + , updates = defaultSimUpdates } @@ -264,10 +265,11 @@ rawSpecsParser = |> apply (UQ.map (Maybe.withDefault defaultRawSpecs.years) <| UQ.string "years") |> apply (UQ.map (Maybe.withDefault defaultRawSpecs.vat) <| UQ.string "vat") |> apply (UQ.map (Maybe.withDefault defaultRawSpecs.fee) <| UQ.string "fee") + |> apply simUpdatesParser rawSpecsToQS : RawSpecs -> List UB.QueryParameter -rawSpecsToQS { title, total, initial, rate, i1, years, vat, fee } = +rawSpecsToQS { title, total, initial, rate, i1, years, vat, fee, updates } = [ UB.string "title" title , UB.string "total" total , UB.string "initial" initial @@ -277,6 +279,7 @@ rawSpecsToQS { title, total, initial, rate, i1, years, vat, fee } = , UB.string "vat" vat , UB.string "fee" fee ] + ++ simUpdatesToQS updates modelToUrl : Model -> String @@ -378,6 +381,102 @@ type alias SimUpdates = } +defaultSimUpdates = + { periodically = [], byMonth = [] } + + +simUpdatesParser : UQ.Parser SimUpdates +simUpdatesParser = + let + parseUpdate str = + String.dropLeft 1 str + |> String.toFloat + |> (case String.left 1 str of + "P" -> + Maybe.map Amortize + + "I" -> + Maybe.map SetI1 + + _ -> + always Nothing + ) + + rawPeriodic str = + List.foldr + (\kv acc -> + case String.split "-" kv of + [ "p", v ] -> + { acc | period = String.toInt v } + + [ "f", v ] -> + { acc | from = String.toInt v } + + [ "t", v ] -> + { acc | to = String.toInt v } + + [ "u", v ] -> + { acc | upd = parseUpdate v } + + _ -> + acc + ) + { period = Nothing + , from = Nothing + , to = Nothing + , upd = Nothing + } + (String.split "," str) + + parsePeriodic rp = + case ( rp.period, rp.upd ) of + ( Just p, Just u ) -> + Just { period = p, from = rp.from, to = rp.to, upd = u } + + _ -> + Nothing + + parseByMonth str = + case String.split ":" str of + [ dr, ur ] -> + Maybe.map2 Tuple.pair (String.toInt dr) (parseUpdate ur) + + _ -> + Nothing + in + UQ.map2 SimUpdates + (UQ.custom "u_period" (List.filterMap (parsePeriodic << rawPeriodic))) + (UQ.custom "u_bymon" (List.filterMap parseByMonth)) + + +simUpdatesToQS : SimUpdates -> List UB.QueryParameter +simUpdatesToQS { periodically, byMonth } = + let + renderUpdate u = + case u of + Amortize f -> + "P" ++ Round.round 2 f + + SetI1 f -> + "I" ++ Round.round 4 f + + renderPeriod { period, from, to, upd } = + [ ( "p", Just (String.fromInt period) ) + , ( "f", Maybe.map String.fromInt from ) + , ( "t", Maybe.map String.fromInt to ) + , ( "u", Just (renderUpdate upd) ) + ] + |> List.filterMap (\( k, vr ) -> Maybe.map (\v -> ( k, v )) vr) + |> List.map (\( k, v ) -> String.join "-" [ k, v ]) + |> String.join "," + + renderMonth ( m, u ) = + String.join ":" [ String.fromInt m, renderUpdate u ] + in + List.map (UB.string "u_period" << renderPeriod) periodically + ++ List.map (UB.string "u_bymon" << renderMonth) byMonth + + updatesInMonth : SimUpdates -> Int -> SimUpdates updatesInMonth { periodically, byMonth } month = let @@ -424,17 +523,13 @@ type alias SimSpecs = parseSimSpecs : RawSpecs -> Maybe SimSpecs -parseSimSpecs { total, rate, i1, years } = +parseSimSpecs { total, rate, i1, years, updates } = case ( List.map String.toFloat [ total, i1 ] , List.map String.toInt [ rate, years ] ) of ( [ Just totalValueF, Just i1F ], [ Just rateI, Just yearsI ] ) -> - let - updates = - { periodically = [], byMonth = [] } - in Just { principal = totalValueF * toFloat rateI / 100 , i1 = i1F @@ -1074,7 +1169,7 @@ simUpdateView attrs m upd = p attrs [ text "+", amountView [] m.settings.currency f ] SetI1 f -> - p attrs [ text <| String.fromFloat f, text "%" ] + p attrs [ text <| String.fromFloat (f * 100), text "%" ] quotaView : Model -> MortgageSim -> Quota -> Html Msg -- cgit v1.2.3