129 lines
3.4 KiB
Elm
129 lines
3.4 KiB
Elm
module Calculator exposing (..)
|
|
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (..)
|
|
|
|
import NumberInput
|
|
import Select
|
|
|
|
type Tax = Net | Gross
|
|
|
|
-- Duplicated from Entry.elm but too lazy to sandwich this out
|
|
type alias TaxGroup =
|
|
{ id : Int
|
|
, description : String
|
|
, percentage : Float
|
|
}
|
|
|
|
showTax : Tax -> String
|
|
showTax tax = case tax of
|
|
Gross -> "Brutto"
|
|
Net -> "Netto"
|
|
|
|
type alias Model =
|
|
{ tax : Select.Model Tax
|
|
, bundlePrice : NumberInput.Model Float
|
|
, bundleSize : NumberInput.Model Int
|
|
}
|
|
|
|
init : Float -> Model
|
|
init bundlePrice = Model
|
|
(Select.init showTax showTax Net [Net, Gross])
|
|
(NumberInput.fromFloat bundlePrice)
|
|
(NumberInput.fromInt 1)
|
|
|
|
getResult : Model -> TaxGroup -> Maybe Float
|
|
getResult model taxGroup =
|
|
case (NumberInput.get model.bundlePrice, NumberInput.get model.bundleSize) of
|
|
(Just bundlePrice, Just bundleSize) ->
|
|
Just <| roundTo 2 <|
|
|
if Select.get model.tax == Gross then
|
|
(bundlePrice / toFloat bundleSize) / (1 + taxGroup.percentage)
|
|
else
|
|
bundlePrice / toFloat bundleSize
|
|
_ ->
|
|
Nothing
|
|
|
|
|
|
type Msg
|
|
= SetTax String
|
|
| SetBundlePrice String
|
|
| SetBundleSize String
|
|
|
|
update : Msg -> Model -> Model
|
|
update msg model = case msg of
|
|
SetTax key ->
|
|
{ model | tax = Select.update key model.tax }
|
|
SetBundlePrice str ->
|
|
{ model | bundlePrice = NumberInput.update str model.bundlePrice }
|
|
SetBundleSize str ->
|
|
{ model | bundleSize = NumberInput.update str model.bundleSize }
|
|
|
|
view : Model -> TaxGroup -> Html Msg
|
|
view model taxGroup =
|
|
let
|
|
mainPart =
|
|
[ text "("
|
|
, div [ class "form-input --inline" ]
|
|
[ label [ for "bundle-price" ] [ text "Gebindepreis" ]
|
|
, input
|
|
[ placeholder "Gebindepreis"
|
|
, value <| NumberInput.show model.bundlePrice
|
|
, onInput SetBundlePrice
|
|
, id "bundle-price"
|
|
, type_ "number"
|
|
, step "0.01"
|
|
]
|
|
[]
|
|
]
|
|
, text " ÷ "
|
|
, div [ class "form-input --inline" ]
|
|
[ label [ for "bundle-size" ] [ text "Gebindegröße" ]
|
|
, input
|
|
[ placeholder "Gebindegröße"
|
|
, value <| NumberInput.show model.bundleSize
|
|
, onInput SetBundleSize
|
|
, id "bundle-size"
|
|
, type_ "number"
|
|
, step "1"
|
|
]
|
|
[]
|
|
]
|
|
, text ") "
|
|
]
|
|
taxPart =
|
|
[ text " ÷ "
|
|
, div [ class "form-input --inline" ]
|
|
[ label [ for "tax" ] [ text "Steuer" ]
|
|
, input
|
|
[ value <| String.fromFloat <| 1 + taxGroup.percentage
|
|
, id "tax"
|
|
, type_ "number"
|
|
, step "0.01"
|
|
, disabled True
|
|
]
|
|
[]
|
|
]
|
|
]
|
|
resultPart =
|
|
[ text " = "
|
|
, text <| Maybe.withDefault "?" <| Maybe.map String.fromFloat <| getResult model taxGroup
|
|
]
|
|
in
|
|
fieldset []
|
|
[ legend [] [ text "Preisrechner" ]
|
|
, div [] <| List.concat <| List.filterMap identity
|
|
[ Just mainPart
|
|
, if Select.get model.tax == Gross then Just taxPart else Nothing
|
|
, Just resultPart
|
|
]
|
|
, div [ class "form-input" ]
|
|
[ label [ for "calculator-tax" ] [ text "Gebindepreis ist" ]
|
|
, Select.view [] SetTax model.tax
|
|
]
|
|
]
|
|
|
|
roundTo : Int -> Float -> Float
|
|
roundTo places x = toFloat (round <| x * 10 ^ toFloat places) / 10 ^ toFloat places
|