jon/elm/Main.elm

202 lines
6.9 KiB
Elm

module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as Dec
import Json.Decode.Pipeline exposing (..)
import Json.Encode as Enc
import Set exposing (Set)
main = Browser.element
{ init = \() -> (init, getUnsoundBarcodes loc)
, subscriptions = \_ -> Sub.none
, update = update
, view = view
}
getUnsoundBarcodes : Int -> Cmd Msg
getUnsoundBarcodes location = Http.post
{ url = "/rpc/getUnsoundBarcodes"
, body = Http.jsonBody (Enc.object [("location", Enc.int location)])
, expect = Http.expectJson RcvUnsoundBarcodes <| Dec.list (Dec.map3 UnsoundBarcode
(Dec.field "barcode" Dec.string)
(Dec.field "name" Dec.string)
(Dec.field "entries" Dec.int))
}
getActiveItems : String -> Int -> Cmd Msg
getActiveItems barcode location = Http.post
{ url = "/rpc/getActiveItems"
, body = Http.jsonBody (Enc.object
[ ("barcode", Enc.string barcode)
, ("location", Enc.int location)
])
, expect = Http.expectJson (RcvActiveItems barcode) <| Dec.list decodeOI
}
transferInventory : List { from : Int, to : Int, amount : Int } -> Cmd Msg
transferInventory transfers = Http.post
{ url = "/rpc/transferInventory"
, body = Http.jsonBody (Enc.object
[ ("transfers", Enc.list encodeTransfer transfers)
])
, expect = Http.expectWhatever RcvTransferResponse
}
encodeTransfer t = Enc.object
[ ("from", Enc.int t.from)
, ("to", Enc.int t.to)
, ("amount", Enc.int t.amount)
]
disableItems : List Int -> Cmd Msg
disableItems ids = Http.post
{ url = "/rpc/disableItems"
, body = Http.jsonBody (Enc.object
[ ("items", Enc.list Enc.int ids)
])
, expect = Http.expectWhatever RcvDisableItemResponse
}
decodeOI = Dec.succeed OverviewItem
|> requiredAt ["item", "id"] Dec.int
|> requiredAt ["item", "barcode"] Dec.string
|> requiredAt ["item", "name"] Dec.string
|> requiredAt ["overview", "unitsLeft"] Dec.int
|> requiredAt ["item", "unitPrice"] Dec.float
|> requiredAt ["item", "bought"] Dec.string
|> requiredAt ["overview", "activeMappings"] Dec.int
type alias UnsoundBarcode =
{ barcode : String
, name : String
, entries : Int
}
type alias OverviewItem =
{ id : Int
, barcode : String
, name : String
, unitsLeft : Int
, price : Float
, bought : String
, activeMappings : Int
}
type Model
= Init
| UBList (List UnsoundBarcode)
| Overview String (Set Int) (List OverviewItem)
type Msg
= RcvUnsoundBarcodes (Result Http.Error (List UnsoundBarcode))
| GetActiveItems String Int
| RcvActiveItems String (Result Http.Error (List OverviewItem))
| SetSelected Int Bool
| TransferInventory (List { amount : Int, from : Int, to : Int })
| RcvTransferResponse (Result Http.Error ())
| DisableItem Int
| RcvDisableItemResponse (Result Http.Error ())
| GoBack
init = Init
loc = 2
update msg model = case model of
Init -> case msg of
RcvUnsoundBarcodes (Ok ubs) -> (UBList ubs, Cmd.none)
_ -> (model, Cmd.none)
UBList _ -> case msg of
GetActiveItems barcode location -> (model, getActiveItems barcode location)
RcvActiveItems barcode (Ok ois) -> (Overview barcode (Set.empty) ois, Cmd.none)
_ -> (model, Cmd.none)
Overview barcode selectedItems ois -> case msg of
SetSelected id checked -> (Overview barcode ((if checked then Set.insert else Set.remove) id selectedItems) ois, Cmd.none)
TransferInventory transfers -> (model, transferInventory transfers)
RcvTransferResponse _ -> (model, getActiveItems barcode loc)
RcvActiveItems barcode_ (Ok ois_) -> (Overview barcode_ (Set.empty) ois_, Cmd.none)
DisableItem id -> (model, disableItems [id])
RcvDisableItemResponse _ -> (model, getActiveItems barcode loc)
GoBack -> (model, getUnsoundBarcodes loc)
RcvUnsoundBarcodes (Ok ubs) -> (UBList ubs, Cmd.none)
_ -> (model, Cmd.none)
view model = case model of
Init -> h1 [] [ text "It works!" ]
UBList ubs -> viewUBList ubs
Overview barcode selectedItems ois -> viewOverview barcode selectedItems ois
viewUBList ubs =
let
header = tr []
[ th [] [ text "Barcode" ]
, th [] [ text "Artikel" ]
, th [] [ text "Einträge" ]
, th [] [ text "Aktionen" ]
]
viewUB ub = tr []
[ td [] [ text ub.barcode ]
, td [] [ text ub.name ]
, td [] [ text <| String.fromInt ub.entries ]
, td [] [ button [ onClick (GetActiveItems ub.barcode loc) ] [ text "Einträge ansehen" ] ]
]
in
table [] ([header] ++ List.map viewUB ubs)
viewOverview : String -> Set Int -> List OverviewItem -> Html Msg
viewOverview barcode selectedItems ois =
let
sumSelected =
List.sum
<| List.map (\oi -> oi.unitsLeft)
<| List.filter (\oi -> Set.member oi.id selectedItems) ois
header = tr []
[ th [] []
, th [] [ text "ID" ]
, th [] [ text "Barcode" ]
, th [] [ text "Artikel" ]
, th [] [ text "Kaufdatum" ]
, th [] [ text "Inventar (Soll)" ]
, th [] [ text "Preis" ]
, th [] [ text "Snackeinträge" ]
, th [] [ text "Aktionen" ]
]
viewOI oi = tr []
[ th [] [ input [ type_ "checkbox", onCheck <| SetSelected oi.id, selected <| Set.member oi.id selectedItems ] [] ]
, td [] [ text <| String.fromInt oi.id ]
, td [] [ text oi.barcode ]
, td [] [ text oi.name ]
, td [] [ text oi.bought ]
, td [] [ text <| String.fromInt oi.unitsLeft ]
, td [] [ text <| String.fromFloat oi.price ]
, td [] [ text <| String.fromInt oi.activeMappings ]
, td [] (viewButtons oi)
]
viewButtons oi =
[ button
[ disabled <| Set.member oi.id selectedItems || sumSelected == 0
, onClick <| mkTransferMessage selectedItems oi.id
]
[ text <| String.fromInt sumSelected ++ " Einträge umbuchen" ]
, button
[ disabled <| oi.unitsLeft /= 0 || oi.activeMappings /= 0
, onClick <| DisableItem oi.id
]
[ text "Eintrag deaktivieren" ]
]
mkTransferMessage fromIds toId =
TransferInventory
<| List.map (\oi -> { amount = oi.unitsLeft, from = oi.id, to = toId })
<| List.filter (\oi -> Set.member oi.id fromIds) ois
in
div []
[ button [ onClick GoBack ] [ text "Zurück" ]
, h2 [] [ text barcode ]
, table [] ([header] ++ List.map viewOI ois)
]