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) ]