Implement price calculator

This commit is contained in:
2023-08-21 14:45:45 +02:00
parent 41a96b4ca2
commit d5ca5812a1
3 changed files with 402 additions and 31 deletions
+119 -4
View File
@@ -90,6 +90,35 @@ type alias Globals =
, taxGroups : List TaxGroup
}
type CalculatorTax = Net | Gross
ctToInt ct = case ct of
Gross -> 0
Net -> 1
ctShow ct = case ct of
Gross -> "Brutto"
Net -> "Netto"
type alias CalculatorModel =
{ tax : Select.Model CalculatorTax
, bundlePrice : NumberInput.Model Float
, bundleSize : NumberInput.Model Int
}
type CalculatorMsg
= SetTax String
| SetBundlePrice String
| SetBundleSize String
updateCalculator 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 }
type State
= ItemSearch
{ searchTerm : String
@@ -99,6 +128,7 @@ type State
{ barcode : String
, name : String
, salesUnits : NumberInput.Model Int
, calculator : CalculatorModel
, netUnitPrice : NumberInput.Model Float
, grossUnitPrice : NumberInput.Model Float
, group : Select.Model Group
@@ -114,6 +144,7 @@ type Msg
| SetBarcode String
| SetName String
| SetSalesUnits String
| CalculatorMsg CalculatorMsg
| SetNetUnitPrice String
| SetGrossUnitPrice String
| SetGroup String
@@ -148,6 +179,11 @@ updateState msg globals state = case state of
( ItemEditor
{ barcode = searchResult.barcode
, name = searchResult.name
, calculator =
{ tax = Select.init ctShow ctShow Net [Net, Gross]
, bundlePrice = NumberInput.fromFloat searchResult.netUnitPrice
, bundleSize = NumberInput.fromInt 1
}
, netUnitPrice = NumberInput.fromFloat searchResult.netUnitPrice
, grossUnitPrice = NumberInput.fromFloat
(suggestedGrossPrice searchResult.netUnitPrice taxGroup.percentage)
@@ -167,6 +203,8 @@ updateState msg globals state = case state of
(ItemEditor { model | name = name }, Cmd.none)
SetSalesUnits str ->
(ItemEditor { model | salesUnits = NumberInput.update str model.salesUnits }, Cmd.none)
CalculatorMsg msg_ ->
(ItemEditor { model | calculator = updateCalculator msg_ model.calculator }, Cmd.none)
SetNetUnitPrice str ->
( ItemEditor { model | netUnitPrice = NumberInput.update str model.netUnitPrice }
, Cmd.none
@@ -227,6 +265,11 @@ view { globals, state } = case state of
[ label [ for "location" ] [ text "Raum" ]
, Select.view SetLocation model.location
]
, div [ class "form-input" ]
[ label [ for "tax-group" ] [ text "Steuergruppe" ]
, Select.view SetTaxGroup model.taxGroup
]
, Html.map CalculatorMsg <| viewCalculator model.calculator (Select.get model.taxGroup)
, div [ class "form-input" ]
[ label [ for "net-unit-price" ] [ text "Einkaufspreis (Netto)" ]
, input
@@ -237,10 +280,7 @@ view { globals, state } = case state of
, step "0.01"
]
[]
]
, div [ class "form-input" ]
[ label [ for "tax-group" ] [ text "Steuergruppe" ]
, Select.view SetTaxGroup model.taxGroup
, viewSetCalculatedPriceButton model
]
, div [ class "form-input" ]
[ label [ for "gross-unit-price" ] [ text "Verkaufspreis (Brutto)" ]
@@ -257,6 +297,81 @@ view { globals, state } = case state of
]
]
viewCalculator model taxGroup =
let
mainPart =
[ text "("
, input
[ class "formula-input", placeholder "Gebindepreis"
, value <| NumberInput.show model.bundlePrice
, onInput SetBundlePrice
]
[]
, text " ÷ "
, input
[ class "formula-input", placeholder "Gebindegröße"
, value <| NumberInput.show model.bundleSize
, onInput SetBundleSize
]
[]
, text ") "
]
taxPart =
[ text " ÷ "
, input
[ class "formula-input"
, disabled True
, value <| String.fromFloat <| 1 + taxGroup.percentage
]
[]
]
resultPart =
[ text " = "
, input
[ class "formula-input"
, disabled True
, value <| Maybe.withDefault "?" <| Maybe.map String.fromFloat <| calculatorResult 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
]
]
calculatorResult 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
viewSetCalculatedPriceButton model =
case calculatorResult model.calculator (Select.get model.taxGroup) of
Nothing ->
button [ disabled True ] [ text "Auf ? setzen" ]
Just calculatedPrice ->
button
[ onClick <| SetNetUnitPrice <| String.fromFloat calculatedPrice
-- Prevent submitting the form
, type_ "button"
]
[ text <| "Auf " ++ String.fromFloat calculatedPrice ++ " setzen"
]
viewSetSuggestedPriceButton model =
case NumberInput.get model.netUnitPrice of
Nothing ->