OrderScreen complete
This commit is contained in:
@@ -42,24 +42,25 @@ let unmergeTable tableNumber =
|
||||
|
||||
|
||||
let getFloorplanData (id: int) =
|
||||
let tableList = Entity.getAllInVenue<floorplan_table>
|
||||
let tableList = Entity.GetAllInVenue<floorplan_table>
|
||||
let reservationList = getReservationList tableList
|
||||
{|
|
||||
tables = tableList
|
||||
decorations = Entity.getAllInVenue<floorplan_decoration>
|
||||
decorations = Entity.GetAllInVenue<floorplan_decoration>
|
||||
activeTableNumbers = Floorplan.getActiveTables (getCurrentVenue())
|
||||
rooms = Entity.getAllInVenue<floorplan_room>
|
||||
rooms = Entity.GetAllInVenue<floorplan_room>
|
||||
reservations = reservationList
|
||||
|}
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
|
||||
let getOrderScreenData (id: int) =
|
||||
let getOrderScreenData (tableNumber: int) =
|
||||
{|
|
||||
order_screen_pages = Entity.getAllInVenue<order_screen_page_group>
|
||||
sales_categories = Entity.getAllInVenue<sales_category>
|
||||
print_groups = Entity.getAllInVenue<print_group>
|
||||
custom_item = Entity.getAllByColumn<item> "item_code" "OPEN000" |> first
|
||||
order_screen_pages = Entity.GetAllInVenue<order_screen_page_group>
|
||||
sales_categories = Entity.GetAllInVenue<sales_category>
|
||||
print_groups = Entity.GetAllInVenue<print_group>
|
||||
custom_item = Entity.GetAllByColumn<item> "item_code" "OPEN000" |> first
|
||||
table = getTable tableNumber
|
||||
|}
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
@@ -73,21 +74,18 @@ let getKeyboardLayout (language: string) =
|
||||
] |> json
|
||||
|
||||
let transformTable (table: floorplan_table) =
|
||||
Entity.updateInDatabase table
|
||||
Entity.Update table
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
|
||||
let createTable (tableData: floorplan_table) =
|
||||
|
||||
let result =
|
||||
if tableExists tableData.table_number = "False" then
|
||||
ajaxSuccess (addNewTable tableData)
|
||||
else ajaxFail (tableExists tableData.table_number)
|
||||
|
||||
result |> json
|
||||
if tableExists tableData.table_number = "False" then
|
||||
ajaxSuccess (addNewTable tableData)
|
||||
else ajaxFail (tableExists tableData.table_number)
|
||||
|> json
|
||||
|
||||
let deleteTable (table: floorplan_table) =
|
||||
Entity.deleteById<floorplan_table> table.id
|
||||
Entity.DeleteById<floorplan_table> table.id
|
||||
|> ignore
|
||||
table |> ajaxSuccess |> json
|
||||
|
||||
@@ -113,30 +111,30 @@ let AddDecoration (data: floorplan_decoration) =
|
||||
venue_id = data.venue_id
|
||||
}
|
||||
|
||||
Entity.addToDatabase decoration
|
||||
Entity.Create decoration
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
|
||||
let UpdateDecoration (data: floorplan_decoration) =
|
||||
Entity.updateInDatabase data
|
||||
Entity.Update data
|
||||
|> ignore
|
||||
ajaxSuccess "true" |> json
|
||||
|
||||
let DeleteDecoration (decorationToDelete: floorplan_decoration) =
|
||||
Entity.deleteById<floorplan_decoration> decorationToDelete.id
|
||||
Entity.DeleteById<floorplan_decoration> decorationToDelete.id
|
||||
|> ajaxSuccess
|
||||
|> json
|
||||
|
||||
let newEmptyReservation (reservation: reservation) =
|
||||
let newReservation = {reservation with
|
||||
reservation_created_at = CurrentTime()
|
||||
reservation_time = CurrentTime()
|
||||
created_at = CurrentTime()
|
||||
time = CurrentTime()
|
||||
}
|
||||
|
||||
if reservation.reservation_table_id > 0 then
|
||||
let table = {(getTableById reservation.reservation_table_id) with
|
||||
if reservation.floorplan_table_id > 0 then
|
||||
let table = {(getTableById reservation.floorplan_table_id) with
|
||||
status = 2
|
||||
default_covers = reservation.reservation_covers}
|
||||
default_covers = reservation.covers}
|
||||
updateTablePosition table |> ignore
|
||||
|
||||
let createdReservation = Floorplan.createEmptyReservation newReservation
|
||||
@@ -149,3 +147,10 @@ let unreserveTable (table: floorplan_table) =
|
||||
updateTablePosition newTable |> ignore
|
||||
DeleteReservation newTable.id
|
||||
newTable |> ajaxSuccess |> json
|
||||
|
||||
let loadGrid (gridId: int) =
|
||||
let grid = Entity.GetById<grid> gridId
|
||||
let gridHtml = OrderScreen.loadGrid gridId
|
||||
if gridHtml = "Error" then ajaxFail gridHtml
|
||||
else ajaxSuccess {|grid=grid;gridHtml=gridHtml|}
|
||||
|> json
|
||||
@@ -8,7 +8,7 @@ open Dapper.FSharp
|
||||
open DredgePos
|
||||
open Types
|
||||
|
||||
let decorationsInRoom (roomId: int) = Entity.getAllByColumn "decoration_room" roomId
|
||||
let decorationsInRoom (roomId: int) = Entity.GetAllByColumn "decoration_room" roomId
|
||||
|
||||
let getImageName (image: string, path: string) =
|
||||
let imageName =
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
<PackageReference Include="SQLProvider" Version="1.2.1" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="6.0.0-preview.5.21301.5" />
|
||||
<PackageReference Include="Thoth.Json.Net" Version="5.0.0" />
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.2-beta.21631.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module Floorplan
|
||||
|
||||
open DredgePos
|
||||
open DredgePos.Types
|
||||
open Org.BouncyCastle.Asn1.X509
|
||||
open Reservations
|
||||
|
||||
@@ -116,16 +117,16 @@ let getRoom (roomId: int) =
|
||||
where (eq "id" roomId)
|
||||
} |> db.Select<floorplan_room> |> first
|
||||
|
||||
let updateTablePosition (floorplanTable: floorplan_table) = Entity.updateInDatabase floorplanTable
|
||||
let updateTablePosition (floorplanTable: floorplan_table) = Entity.Update floorplanTable
|
||||
|
||||
let createEmptyReservation (reservation: reservation) =
|
||||
update {
|
||||
table "floorplan_tables"
|
||||
set {| status = 2 |}
|
||||
where(eq "id" reservation.reservation_table_id)
|
||||
where(eq "id" reservation.floorplan_table_id)
|
||||
} |> db.Update |> ignore
|
||||
|
||||
Entity.addToDatabase reservation
|
||||
Entity.Create reservation
|
||||
|
||||
let getChildTables tableNumber =
|
||||
let table = getTable tableNumber
|
||||
@@ -165,7 +166,7 @@ let tableExists (tableNumber: int) =
|
||||
match numberOfResults with
|
||||
| 0 ->
|
||||
let allTables =
|
||||
Entity.getAllInVenue<floorplan_table>
|
||||
Entity.GetAllInVenue<floorplan_table>
|
||||
|> Array.map(findChildTable tableNumber)
|
||||
|> Array.filter(fun tableNumber -> tableNumber <> 0)
|
||||
|
||||
@@ -192,7 +193,7 @@ let addNewTableWithoutOutput (newTable: floorplan_table) =
|
||||
}
|
||||
|> db.Insert
|
||||
|
||||
let addNewTable (newTable: floorplan_table) = Entity.addToDatabase newTable
|
||||
let addNewTable (newTable: floorplan_table) = Entity.Create newTable
|
||||
|
||||
let mergeTables parent child = //Merge two tables together
|
||||
if parent = child then false else
|
||||
@@ -246,7 +247,7 @@ let mergeTables parent child = //Merge two tables together
|
||||
where (eq "table_number" parent + eq "venue_id" (getCurrentVenue()))
|
||||
} |> db.Update |> ignore
|
||||
|
||||
Entity.deleteById<floorplan_table> newChildTable.id
|
||||
Entity.DeleteById<floorplan_table> newChildTable.id
|
||||
|> ignore
|
||||
|
||||
true
|
||||
@@ -289,30 +290,19 @@ let makeRoomButton (room: floorplan_room) =
|
||||
Theme.loadTemplateWithVars "roomButton" vars
|
||||
|
||||
let getReservationList (tableList: floorplan_table[]) =
|
||||
let tableIds =
|
||||
tableList
|
||||
|> Array.map(fun table -> box table.id)
|
||||
|> List.ofArray
|
||||
|
||||
if tableIds.Length > 0 then
|
||||
select {
|
||||
table "reservations"
|
||||
where (isIn "reservation_table_id" tableIds)
|
||||
}
|
||||
|> db.Select<reservation>
|
||||
else [||]
|
||||
tableList |> Array.collect Entity.GetAllRelated<reservation, floorplan_table>
|
||||
|
||||
let newReservation name time covers =
|
||||
let reservation = {
|
||||
id = 0
|
||||
reservation_name = name
|
||||
reservation_time = time
|
||||
reservation_covers = covers
|
||||
reservation_table_id = 0
|
||||
reservation_created_at = CurrentTime()
|
||||
name = name
|
||||
time = time
|
||||
covers = covers
|
||||
floorplan_table_id = 0
|
||||
created_at = CurrentTime()
|
||||
}
|
||||
|
||||
Entity.addToDatabase reservation
|
||||
Entity.Create reservation
|
||||
|
||||
|
||||
let tableList () = Entity.getAllInVenue<floorplan_table>
|
||||
let tableList () = Entity.GetAllInVenue<floorplan_table>
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
open Dapper.FSharp
|
||||
open DredgeFramework
|
||||
open Pluralize.NET.Core
|
||||
open FSharp.Reflection
|
||||
|
||||
let getDatabaseTable<'x> =
|
||||
let GetDatabaseTable<'x> =
|
||||
let typeName = typeof<'x>.Name
|
||||
Pluralizer().Pluralize typeName
|
||||
|
||||
let addToDatabase (record: 'x)=
|
||||
let tableName = getDatabaseTable<'x>
|
||||
let Create (record: 'x)=
|
||||
let tableName = GetDatabaseTable<'x>
|
||||
insert {
|
||||
table tableName
|
||||
value record
|
||||
@@ -18,42 +19,50 @@ let addToDatabase (record: 'x)=
|
||||
|> first
|
||||
|
||||
|
||||
let inline updateInDatabase (record: ^x) =
|
||||
let tableName = getDatabaseTable<'x>
|
||||
let id = ((^x) : (member id : int) (record))
|
||||
let inline Update (record: ^x) =
|
||||
let tableName = GetDatabaseTable<'x>
|
||||
let id = ((^x) : (member id : int) record)
|
||||
update {
|
||||
table tableName
|
||||
set record
|
||||
where (eq "id" id)
|
||||
excludeColumn "id"
|
||||
}
|
||||
|> db.Update
|
||||
|
||||
let getAll<'x> =
|
||||
let typeName = typeof<'x>.Name
|
||||
let tableName = Pluralizer().Pluralize typeName
|
||||
let GetAll<'x> =
|
||||
let tableName = GetDatabaseTable<'x>
|
||||
|
||||
select {
|
||||
table tableName
|
||||
}
|
||||
|> db.Select<'x>
|
||||
|
||||
let getAllByColumn<'x> (column: string) (value: obj) =
|
||||
let typeName = typeof<'x>.Name
|
||||
let tableName = Pluralizer().Pluralize typeName
|
||||
let GetAllByColumn<'x> (column: string) (value: obj) =
|
||||
let tableName = GetDatabaseTable<'x>
|
||||
|
||||
select {
|
||||
table tableName
|
||||
where (eq column value)
|
||||
} |> db.Select<'x>
|
||||
|
||||
let getAllInVenue<'x> = getAllByColumn<'x> "venue_id" (getCurrentVenue ())
|
||||
let getById<'x> (id: int) = getAllByColumn<'x> "id" id |> first
|
||||
let GetAllInVenue<'x> = GetAllByColumn<'x> "venue_id" (getCurrentVenue ())
|
||||
let GetById<'x> (id: int) = GetAllByColumn<'x> "id" id |> first
|
||||
|
||||
let deleteById<'x> id =
|
||||
let inline GetRelated<'x, .. > (entity: ^y) =
|
||||
let columnName = typeof<'x>.Name + "_id"
|
||||
let primaryKeyValue = typeof<'y>.GetProperty(columnName).GetValue(entity) :?> int
|
||||
GetById<'x> primaryKeyValue
|
||||
|
||||
let inline GetAllRelated<'x, .. > (entity: ^y) =
|
||||
let id = typeof<'y>.GetProperty("id").GetValue(entity) :?> int
|
||||
let columnName = typeof<'y>.Name + "_id"
|
||||
GetAllByColumn<'x> columnName id
|
||||
|
||||
let DeleteById<'x> id =
|
||||
let typeName = typeof<'x>.Name
|
||||
let tableName = Pluralizer().Pluralize typeName
|
||||
|
||||
let entity = getById<'x> id
|
||||
let entity = GetById<'x> id
|
||||
|
||||
delete {
|
||||
table tableName
|
||||
@@ -61,3 +70,7 @@ let deleteById<'x> id =
|
||||
} |> db.Delete |> ignore
|
||||
|
||||
entity
|
||||
|
||||
let inline Delete< ^x when ^x: (member id: int) > (entity: ^x) =
|
||||
typeof<'x>.GetProperty("id").GetValue(entity) :?> int
|
||||
|> DeleteById<'x>
|
||||
|
||||
@@ -4,16 +4,19 @@ open DredgePos
|
||||
open DredgePos.Types
|
||||
open FSharp.Collections
|
||||
open Thoth.Json.Net
|
||||
open Types
|
||||
open Theme
|
||||
|
||||
|
||||
let getAllPageGrids () = Entity.getAllInVenue<order_screen_page_group>
|
||||
let getAllPageGrids () = Entity.GetAllInVenue<order_screen_page_group>
|
||||
|> Array.filter(fun pageGroup -> pageGroup.grid_id <> 0)
|
||||
|> Array.map(fun pageGroup -> (Entity.getById<grid> pageGroup.grid_id), pageGroup)
|
||||
|> Array.map(fun pageGroup -> (Entity.GetById<grid> pageGroup.grid_id), pageGroup)
|
||||
|
||||
let getImageButtonData (button: button) =
|
||||
let item = Entity.getAllByColumn<item> "item_code" button.primary_action_value
|
||||
let itemCode =
|
||||
if button.primary_action = "item" then button.primary_action_value
|
||||
else button.secondary_action_value
|
||||
|
||||
let item = Entity.GetAllByColumn<item> "item_code" itemCode
|
||||
|> first
|
||||
|
||||
let extraData =
|
||||
@@ -26,9 +29,31 @@ let getImageButtonData (button: button) =
|
||||
text = item.item_name
|
||||
|}
|
||||
|
||||
let getGridButtonData (button: button) =
|
||||
let gridId =
|
||||
if button.primary_action = "grid" then button.primary_action_value
|
||||
else button.secondary_action_value
|
||||
|> int
|
||||
|
||||
let grid = Entity.GetById<grid> gridId
|
||||
{|
|
||||
extra_data = map ["data-grid", jsonEncode gridId] |> htmlAttributes
|
||||
text = grid.grid_name
|
||||
|}
|
||||
|
||||
let getActionData (button: button) (action: string) =
|
||||
let actionValue =
|
||||
if action = "primary" then button.primary_action
|
||||
else button.secondary_action
|
||||
|
||||
match actionValue with
|
||||
| "item" -> getImageButtonData button
|
||||
| "grid" -> getGridButtonData button
|
||||
| "spacer" -> {|extra_data=""; text=""|}
|
||||
| _ -> {|extra_data=""; text=""|}
|
||||
|
||||
let renderButton (buttonId: int) =
|
||||
let button = Entity.getById<button> buttonId
|
||||
let button = Entity.GetById<button> buttonId
|
||||
|
||||
let extra_styles =
|
||||
match button.extra_styles.Length with
|
||||
@@ -44,34 +69,36 @@ let renderButton (buttonId: int) =
|
||||
|
||||
let extraClasses = [|imageClass; spacerClass|] |> String.concat " "
|
||||
|
||||
let action_data =
|
||||
match button.primary_action with
|
||||
| "item" -> getImageButtonData button
|
||||
| "spacer" -> {|extra_data=""; text=""|}
|
||||
| _ -> {|extra_data=""; text=""|}
|
||||
let primary_action_data = getActionData button "primary"
|
||||
let secondary_action_data = getActionData button "secondary"
|
||||
|
||||
let action_extra_data = primary_action_data.extra_data + " " + secondary_action_data.extra_data
|
||||
let button_text =
|
||||
if button.text.Length > 0 then button.text
|
||||
else
|
||||
if primary_action_data.text.Length > 0 then primary_action_data.text
|
||||
else secondary_action_data.text
|
||||
|
||||
let vars = map [
|
||||
"extra_classes", button.extra_classes + " " + extraClasses
|
||||
"extra_styles", extra_styles
|
||||
"primary_action", button.primary_action
|
||||
"secondary_action", button.secondary_action
|
||||
"text", if button.text.Length > 0 then button.text else action_data.text
|
||||
"text", button_text
|
||||
"image", image
|
||||
"extra_data", action_data.extra_data
|
||||
"extra_data", action_extra_data
|
||||
]
|
||||
|
||||
loadTemplateWithVars "orderScreen/grid_button" vars
|
||||
|
||||
let renderPage (buttonHTML: string) =
|
||||
let vars = map [
|
||||
"pageButtons", buttonHTML
|
||||
]
|
||||
let renderPage (grid: grid) (buttonHTML: string) =
|
||||
let vars = map ["pageButtons", buttonHTML; "rows", string grid.grid_rows; "cols", string grid.grid_cols]
|
||||
loadTemplateWithVars "orderScreen/page" vars
|
||||
|
||||
let renderPageGroup (pageGroup: order_screen_page_group) (pageHTML: string) =
|
||||
let vars = map [
|
||||
"pages", pageHTML
|
||||
"page_group_id", pageGroup.id.ToString()
|
||||
"page_group_id", string pageGroup.id
|
||||
]
|
||||
loadTemplateWithVars "orderScreen/page_group" vars
|
||||
|
||||
@@ -79,24 +106,32 @@ let printGroupPosButton (printGroup: print_group) =
|
||||
PosButton (language.getAndReplace "print_with" [printGroup.name]) "printGroupOverrideButton toggle" $"""data-value="{printGroup.id}" """
|
||||
|
||||
let generateSalesCategoryOverrideButtons () =
|
||||
Entity.getAllInVenue<print_group>
|
||||
Entity.GetAllInVenue<print_group>
|
||||
|> Array.map printGroupPosButton
|
||||
|> Array.append ([|PosButton (language.getAndReplace "print_with" ["default"]) "printGroupOverrideButton toggle default active" """data-value="0" """|])
|
||||
|> Array.append [|PosButton (language.getAndReplace "print_with" ["default"]) "printGroupOverrideButton toggle default active" """data-value="0" """|]
|
||||
|> String.concat "\n"
|
||||
|
||||
|
||||
let renderGrid (grid: grid) =
|
||||
let gridData = grid.grid_data |> Decode.Auto.fromString<Map<string, int[]>>
|
||||
|
||||
match gridData with
|
||||
| Error _ -> "Error"
|
||||
| Ok pages ->
|
||||
pages
|
||||
|> Map.toArray
|
||||
|> Array.map snd
|
||||
|> Array.map(fun row -> row |> Array.map renderButton |> String.concat "\n")
|
||||
|> Array.map (renderPage grid)
|
||||
|> String.concat "\n"
|
||||
|
||||
let loadGrid gridId = renderGrid (Entity.GetById<grid> gridId)
|
||||
|
||||
|
||||
let getPagesHTML (gridInfo: grid * order_screen_page_group) =
|
||||
let grid, pageGroup = gridInfo
|
||||
|
||||
let pages = grid.grid_data |> Decode.Auto.fromString<Map<string, int[]>>
|
||||
renderGrid grid
|
||||
|> renderPageGroup pageGroup
|
||||
|
||||
|
||||
match pages with
|
||||
| Error _ -> "Error"
|
||||
| Ok pages ->
|
||||
pages
|
||||
|> Map.toArray
|
||||
|> Array.map snd
|
||||
|> Array.map(fun row -> row |> Array.map renderButton |> String.concat "\n")
|
||||
|> Array.map renderPage
|
||||
|> String.concat "\n"
|
||||
|> renderPageGroup pageGroup
|
||||
@@ -20,7 +20,7 @@ let loadFloorplan (ctx: HttpContext) : HttpHandler =
|
||||
Session.RequireClerkAuthentication ctx
|
||||
|
||||
let roomMenu =
|
||||
Entity.getAllInVenue<floorplan_room>
|
||||
Entity.GetAllInVenue<floorplan_room>
|
||||
|> Array.map makeRoomButton
|
||||
|> String.concat "\n"
|
||||
|
||||
@@ -43,14 +43,20 @@ let loadOrderScreen (ctx: HttpContext) (tableNumber: int) : HttpHandler =
|
||||
let covers = if tableNumber > 0 then (getTable tableNumber).default_covers else 0
|
||||
let coverString = language.getAndReplace "covers" [covers]
|
||||
|
||||
let coverSelectorButton = if tableNumber > 0 then Theme.loadTemplateWithVars "orderScreen/cover_selector_button" (map ["covers", coverString]) else ""
|
||||
let changeCoverNumberButton = if tableNumber > 0 then Theme.loadTemplateWithVars "orderScreen/change_cover_number_button" (map ["covers", coverString]) else ""
|
||||
|
||||
let orderNumber =
|
||||
if tableNumber > 0 then language.getAndReplace "active_table" [tableNumber]
|
||||
else language.get "new_order"
|
||||
|
||||
let containerAttributes =
|
||||
if tableNumber > 0 then
|
||||
map ["data-table", jsonEncode (getTable tableNumber)]
|
||||
|> Theme.htmlAttributes
|
||||
else ""
|
||||
|
||||
let categoryList =
|
||||
Entity.getAllInVenue<order_screen_page_group>
|
||||
Entity.GetAllInVenue<order_screen_page_group>
|
||||
|> Array.filter (fun page_group -> page_group.id <> 0)
|
||||
|> Array.sortBy (fun {order=order} -> order)
|
||||
|> Array.map (fun category ->
|
||||
@@ -65,22 +71,24 @@ let loadOrderScreen (ctx: HttpContext) (tableNumber: int) : HttpHandler =
|
||||
|> Array.map OrderScreen.getPagesHTML
|
||||
|> String.concat "\n"
|
||||
|
||||
let customItem =
|
||||
Entity.getAllByColumn<item> "item_code" "OPEN000"
|
||||
|> filterFirst
|
||||
|> Array.map jsonEncode
|
||||
|> String.concat ""
|
||||
|
||||
let coverSelectorButtons =
|
||||
Array.init (covers+1) id
|
||||
|> Array.map(fun coverNumber ->
|
||||
let text = if coverNumber > 0 then language.getAndReplace "selected_cover" [coverNumber]
|
||||
else language.get "cover_zero"
|
||||
Theme.PosButton text "coverSelectorButton" $"""data-cover="{coverNumber}" """)
|
||||
|> String.concat "\n"
|
||||
|
||||
let variables = map [
|
||||
"title", "Order"
|
||||
"containerAttributes", containerAttributes
|
||||
"categoryList", categoryList
|
||||
"pageGroups", grids
|
||||
"orderNumber", orderNumber
|
||||
"coverSelectorButton", coverSelectorButton
|
||||
"changeCoverNumberButton", changeCoverNumberButton
|
||||
"covers", coverString
|
||||
"salesCategoryOverrideButtons", OrderScreen.generateSalesCategoryOverrideButtons ()
|
||||
"custom", OrderScreen.generateSalesCategoryOverrideButtons ()
|
||||
"coverSelectorButtons", coverSelectorButtons
|
||||
]
|
||||
|
||||
let styles = ["dredgepos.orderScreen.css"]
|
||||
@@ -88,7 +96,8 @@ let loadOrderScreen (ctx: HttpContext) (tableNumber: int) : HttpHandler =
|
||||
let currentClerk = recordToMap <| Session.getCurrentClerk ctx
|
||||
let arrays = map ["clerk", currentClerk]
|
||||
|
||||
htmlString <| Theme.loadTemplateWithVarsArraysScriptsAndStyles "orderScreen" variables arrays scripts styles
|
||||
Theme.loadTemplateWithVarsArraysScriptsAndStyles "orderScreen" variables arrays scripts styles
|
||||
|> htmlString
|
||||
|
||||
let getOpenTables() =
|
||||
let rows = openTables()
|
||||
|
||||
@@ -2,6 +2,7 @@ namespace WebApplication
|
||||
|
||||
|
||||
open DredgePos
|
||||
open DredgePos.Types
|
||||
open Microsoft.AspNetCore.Server.Kestrel.Core
|
||||
open Reservations
|
||||
open Saturn
|
||||
@@ -40,10 +41,11 @@ module Program =
|
||||
getf "/unmergeTable/%i" AjaxController.unmergeTable
|
||||
getf "/tableExists/%i" (fun tableNumber -> json <| Floorplan.tableExists tableNumber)
|
||||
}
|
||||
|
||||
let orderScreenRouter = router {
|
||||
pipe_through browser
|
||||
getf "/getOrderScreenData/%i" AjaxController.getOrderScreenData
|
||||
getf "/getGridHtml/%i" AjaxController.loadGrid
|
||||
post "/updateCovers" (bindJson<floorplan_table> (fun table -> Entity.Update table |> Array.head |> DredgeFramework.ajaxSuccess |> json))
|
||||
}
|
||||
|
||||
let pageRouter = router {
|
||||
|
||||
@@ -49,7 +49,7 @@ let ParseVariables (varArray: Map<string, string>) (html:string) =
|
||||
if varName |> ToLowerCase = "title" then titlePrefix varArray[varName]
|
||||
else varArray[varName]
|
||||
else
|
||||
"<!--[Undefined Variable: " + varName + "]-->"
|
||||
""
|
||||
))
|
||||
|
||||
let ParseArrays (arrayArray: Map<string, Map<string, string>>) (string:string) =
|
||||
|
||||
16
Types.fs
16
Types.fs
@@ -3,11 +3,17 @@ module DredgePos.Types
|
||||
[<CLIMutable>]
|
||||
type reservation = {
|
||||
id: int
|
||||
reservation_name: string
|
||||
reservation_time: int
|
||||
reservation_covers: int
|
||||
reservation_table_id: int
|
||||
reservation_created_at: int
|
||||
name: string
|
||||
time: int
|
||||
covers: int
|
||||
floorplan_table_id: int
|
||||
created_at: int
|
||||
}
|
||||
|
||||
[<CLIMutable>]
|
||||
type venue = {
|
||||
id: int
|
||||
venue_name: string
|
||||
}
|
||||
|
||||
[<CLIMutable>]
|
||||
|
||||
@@ -45,8 +45,6 @@ const ajax = (endpoint: string, data: any, method = 'POST', successFunction: Fun
|
||||
beforeSend: beforeFunction
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
For the flow of the app, synchronous is commonly preferred
|
||||
though trying to keep its usage as low as possible.
|
||||
@@ -229,5 +227,13 @@ function* newestId(){
|
||||
}
|
||||
}
|
||||
|
||||
const loadTemplate = (templateSelector: string) => {
|
||||
const content = $(templateSelector)
|
||||
.clone()
|
||||
.removeAttr('id')
|
||||
.prop('content')
|
||||
return $(content)
|
||||
}
|
||||
|
||||
|
||||
$(() => ajax('/ajax/languageVars', null, 'GET', setupCore, null, null))
|
||||
@@ -10,7 +10,7 @@ interface floorplan{
|
||||
transformer: Konva.Transformer
|
||||
tableLayer: Konva.Layer
|
||||
rooms: room[]
|
||||
tables: table[]
|
||||
tables: floorplan_table[]
|
||||
decorations: decoration[]
|
||||
activeTableNumbers: number[]
|
||||
selectedTableNumber: number
|
||||
@@ -24,7 +24,7 @@ interface floorplan{
|
||||
}
|
||||
|
||||
interface floorplan_data{
|
||||
tables: table[]
|
||||
tables: floorplan_table[]
|
||||
decorations: decoration[]
|
||||
activeTableNumbers: number[]
|
||||
rooms: room[]
|
||||
@@ -137,9 +137,9 @@ const getRoomById = (roomId: number) => {
|
||||
)
|
||||
}
|
||||
|
||||
const tableIsOpen = (table: table) => Floorplan.activeTableNumbers.includes(table.table_number)
|
||||
const tableIsOpen = (table: floorplan_table) => Floorplan.activeTableNumbers.includes(table.table_number)
|
||||
|
||||
const createTableShape = (table: table) => {
|
||||
const createTableShape = (table: floorplan_table) => {
|
||||
const draggable = isInMode('edit')
|
||||
|
||||
const tableGroup = new Konva.Group({
|
||||
@@ -243,7 +243,7 @@ const saveTableTransformation = (tableGroup: Konva.Group) => {
|
||||
const originalTable = getTableDataFromGroup(tableGroup)
|
||||
const tableShape = getTableShapeFromGroup(tableGroup)
|
||||
|
||||
const newTableInfo : table = {
|
||||
const newTableInfo : floorplan_table = {
|
||||
table_number : originalTable.table_number,
|
||||
previous_state : originalTable.previous_state,
|
||||
merged_children : originalTable.merged_children,
|
||||
@@ -265,7 +265,7 @@ const saveTableTransformation = (tableGroup: Konva.Group) => {
|
||||
}
|
||||
|
||||
|
||||
const saveTable = (tableToUpdate: table) => {
|
||||
const saveTable = (tableToUpdate: floorplan_table) => {
|
||||
const tables =
|
||||
Floorplan
|
||||
.tables
|
||||
@@ -309,20 +309,20 @@ const getTableGroupFromTableNumber = (tableNumber : number) => {
|
||||
return getTableGroupFromShape(tableShape)
|
||||
}
|
||||
|
||||
const setReservationStatus = (table: table) => {
|
||||
const setReservationStatus = (table: floorplan_table) => {
|
||||
const reservationText = $('.reservationStatus')
|
||||
const tableShape = getTableShapeFromTableNumber(table.table_number)
|
||||
reservationText.text('')
|
||||
|
||||
if(table.status == 2) {
|
||||
tableShape.fill('lightgreen')
|
||||
const reservations = Floorplan.reservations.filter(reservation => reservation.reservation_table_id == table.id)
|
||||
const reservations = Floorplan.reservations.filter(reservation => reservation.floorplan_table_id == table.id)
|
||||
if (reservations.length) {
|
||||
turnOnMode('reservedTableSelected')
|
||||
reservationText.text(lang('reserved'))
|
||||
let reservation = reservations[0]
|
||||
if (reservation.reservation_name != '') {
|
||||
reservationText.text(lang('reserved_for', reservation.reservation_name))
|
||||
if (reservation.name != '') {
|
||||
reservationText.text(lang('reserved_for', reservation.name))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -340,11 +340,11 @@ const reserveTable = () => {
|
||||
const createEmptyReservation = (covers: number) => {
|
||||
const newReservation: reservation = {
|
||||
id: 0,
|
||||
reservation_covers: covers,
|
||||
reservation_created_at: 0,
|
||||
reservation_table_id: getSelectedTableData().id,
|
||||
reservation_name: '',
|
||||
reservation_time: 0,
|
||||
covers: covers,
|
||||
created_at: 0,
|
||||
floorplan_table_id: getSelectedTableData().id,
|
||||
name: '',
|
||||
time: 0,
|
||||
}
|
||||
|
||||
ajax('/ajax/newEmptyReservation', newReservation,'post', emptyReservationCreated, null, null )
|
||||
@@ -354,7 +354,7 @@ const emptyReservationCreated = (reservation: reservation) => {
|
||||
Floorplan.reservations.push(reservation)
|
||||
const selectedTable = getSelectedTableData()
|
||||
selectedTable.status = 2
|
||||
selectedTable.default_covers = reservation.reservation_covers
|
||||
selectedTable.default_covers = reservation.covers
|
||||
updateTableData(selectedTable)
|
||||
updateCoverText(selectedTable)
|
||||
setReservationStatus(getSelectedTableData())
|
||||
@@ -364,8 +364,8 @@ const emptyReservationCreated = (reservation: reservation) => {
|
||||
|
||||
const addReservationName = (name: string) => {
|
||||
hideVirtualKeyboard()
|
||||
const reservation = Floorplan.reservations.filter(reservation => reservation.reservation_table_id == getSelectedTableData().id)[0]
|
||||
reservation.reservation_name = name
|
||||
const reservation = Floorplan.reservations.filter(reservation => reservation.floorplan_table_id == getSelectedTableData().id)[0]
|
||||
reservation.name = name
|
||||
ajax('/ajax/updateReservation', reservation, 'post', reservationNameAdded, null, null)
|
||||
}
|
||||
|
||||
@@ -376,9 +376,9 @@ const reservationNameAdded = (updatedReservation: reservation) => {
|
||||
setReservationStatus(getSelectedTableData())
|
||||
}
|
||||
|
||||
const getReservationsOnTable = (table: table) => Floorplan.reservations.filter(reservation => reservation.reservation_table_id == table.id)
|
||||
const getReservationsOnTable = (table: floorplan_table) => Floorplan.reservations.filter(reservation => reservation.floorplan_table_id == table.id)
|
||||
|
||||
const updateTableData = (tableToRemove: table) => {
|
||||
const updateTableData = (tableToRemove: floorplan_table) => {
|
||||
Floorplan.tables = Floorplan.tables.filter(table => table.id != tableToRemove.id)
|
||||
Floorplan.tables.push(tableToRemove)
|
||||
}
|
||||
@@ -389,8 +389,8 @@ const unreserveTable = () => {
|
||||
ajax('/ajax/unreserveTable', selectedTable, 'post', tableUnreserved, null, null)
|
||||
}
|
||||
|
||||
const tableUnreserved = (table: table) => {
|
||||
Floorplan.reservations = Floorplan.reservations.filter(reservation => reservation.reservation_table_id != table.id)
|
||||
const tableUnreserved = (table: floorplan_table) => {
|
||||
Floorplan.reservations = Floorplan.reservations.filter(reservation => reservation.floorplan_table_id != table.id)
|
||||
updateTableData(table)
|
||||
setReservationStatus(table)
|
||||
}
|
||||
@@ -438,7 +438,7 @@ const selectTable = (tableShape: Konva.Shape) => {
|
||||
turnOnMode('tableSelected')
|
||||
}
|
||||
|
||||
const updateCoverText = (table:table) => $('.selectedTableCovers').text(lang('covers', table.default_covers.toString()))
|
||||
const updateCoverText = (table:floorplan_table) => $('.selectedTableCovers').text(lang('covers', table.default_covers.toString()))
|
||||
|
||||
const tableDblClicked = (event: Konva.KonvaEventObject<any>) => {
|
||||
let tableShape = getTableShapeFromGroup(event.currentTarget as Konva.Group)
|
||||
@@ -718,7 +718,7 @@ const redrawTable = (tableGroup: Konva.Group) => {
|
||||
const showAddTablePopup = () => showVirtualNumpad(lang('new_table_number'), 4, false, false, true, addTable);
|
||||
|
||||
const addTable = (tableNumber: number) => {
|
||||
const newTable : table = {
|
||||
const newTable : floorplan_table = {
|
||||
id: 0,
|
||||
table_number: tableNumber,
|
||||
room_id: Floorplan.currentRoom.id,
|
||||
@@ -738,7 +738,7 @@ const addTable = (tableNumber: number) => {
|
||||
ajax('/ajax/createTable', newTable, 'post', tableAdded, tableNotAdded, null)
|
||||
}
|
||||
|
||||
const tableAdded = (table: table) => {
|
||||
const tableAdded = (table: floorplan_table) => {
|
||||
deselectTables()
|
||||
const newTableGroup = createTableShape(table)
|
||||
Floorplan.tables.push(table)
|
||||
@@ -766,7 +766,7 @@ const deleteTable = (tableNumber: number) => {
|
||||
ajax(`/ajax/deleteTable`, tableToDelete, 'post', tableDeleted, null, null);
|
||||
}
|
||||
|
||||
const tableDeleted = (deletedTable: table) => {
|
||||
const tableDeleted = (deletedTable: floorplan_table) => {
|
||||
Floorplan.tables = Floorplan.tables.filter(table => table.table_number != deletedTable.table_number)
|
||||
const tableGroup = getTableGroupFromTableNumber(deletedTable.table_number)
|
||||
deselectTables()
|
||||
@@ -776,7 +776,7 @@ const tableDeleted = (deletedTable: table) => {
|
||||
const toggleMergeMode = () => toggleMode('merge')
|
||||
|
||||
|
||||
const mergeTables = (table1: table, table2: table ) => {
|
||||
const mergeTables = (table1: floorplan_table, table2: floorplan_table ) => {
|
||||
toggleMergeMode()
|
||||
if(table1.table_number == table2.table_number){
|
||||
posAlert(lang('error_self_merge'))
|
||||
@@ -785,7 +785,7 @@ const mergeTables = (table1: table, table2: table ) => {
|
||||
ajax('/ajax/mergeTables', [table1, table2], 'post', tablesMerged, null, null)
|
||||
}
|
||||
|
||||
const tablesMerged = (tables: Record<'child'|'parent'|'merged', table>) => {
|
||||
const tablesMerged = (tables: Record<'child'|'parent'|'merged', floorplan_table>) => {
|
||||
tableDeleted(tables['child'])
|
||||
tableDeleted(tables['parent'])
|
||||
tableAdded(tables['merged'])
|
||||
@@ -797,7 +797,7 @@ const tablesMerged = (tables: Record<'child'|'parent'|'merged', table>) => {
|
||||
|
||||
const unmergeTable = () => ajax(`/ajax/unmergeTable/${Floorplan.selectedTableNumber}`, null, 'get', tablesUnmerged, null, null)
|
||||
|
||||
const tablesUnmerged = (tables: Record<'child'|'parent', table>) => {
|
||||
const tablesUnmerged = (tables: Record<'child'|'parent', floorplan_table>) => {
|
||||
const parentTable = tables['parent']
|
||||
const childTable = tables['child']
|
||||
|
||||
@@ -809,7 +809,7 @@ const tablesUnmerged = (tables: Record<'child'|'parent', table>) => {
|
||||
|
||||
const toggleTransferMode = () => toggleMode('transfer')
|
||||
|
||||
const transferTables = (origin: table, destination: table) => {
|
||||
const transferTables = (origin: floorplan_table, destination: floorplan_table) => {
|
||||
if(origin.table_number == destination.table_number){
|
||||
posAlert(lang('transfer_self_error'))
|
||||
return
|
||||
@@ -818,7 +818,7 @@ const transferTables = (origin: table, destination: table) => {
|
||||
ajax(`/ajax/transferTable/${origin.table_number}/${destination.table_number}`, null, 'get', tableTransferred, null, null)
|
||||
}
|
||||
|
||||
const tableTransferred = (tables: Record<"origin"|"destination", table>) => {
|
||||
const tableTransferred = (tables: Record<"origin"|"destination", floorplan_table>) => {
|
||||
const origin = tables['origin']
|
||||
const destination = tables['destination']
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ type OrderScreen = {
|
||||
qty_override: number
|
||||
print_group_override: print_group
|
||||
custom_item: item,
|
||||
selected_cover: number
|
||||
table: floorplan_table,
|
||||
}
|
||||
|
||||
let OrderScreen : OrderScreen = {
|
||||
@@ -28,17 +30,24 @@ let OrderScreen : OrderScreen = {
|
||||
selected_item_ids: [],
|
||||
qty_override: 1,
|
||||
print_group_override: null,
|
||||
custom_item: null
|
||||
custom_item: null,
|
||||
selected_cover: 0,
|
||||
table: null,
|
||||
}
|
||||
|
||||
const loadPageGroup = (e: Event) => {
|
||||
let button = $(e.target)
|
||||
const button = $(e.target)
|
||||
const container = $('#pageGroupContainer')
|
||||
|
||||
$('.loadPageGroup').removeClass('active')
|
||||
button.addClass('active')
|
||||
|
||||
let pageGroupId = button.data('page-group-id')
|
||||
$('.pageGroup').hide()
|
||||
|
||||
container.find('.pageGroup').hide()
|
||||
|
||||
let activeGrid = $(`.pageGroup[data-page-group-id=${pageGroupId}]`)
|
||||
let navButtons = $('.pageNavigation')
|
||||
let navButtons = container.next('.pageNavigation')
|
||||
navButtons.css('display', 'flex')
|
||||
|
||||
activeGrid.find('.gridPage').length > 1
|
||||
@@ -49,6 +58,9 @@ const loadPageGroup = (e: Event) => {
|
||||
}
|
||||
|
||||
const setupOrderScreen = (data: OrderScreenData) => {
|
||||
|
||||
$('.coverSelector, .gridContainer').hide()
|
||||
|
||||
OrderScreen.order_screen_pages = data.order_screen_pages
|
||||
OrderScreen.sales_categories = data.sales_categories
|
||||
OrderScreen.print_groups = data.print_groups
|
||||
@@ -60,6 +72,8 @@ const setupOrderScreen = (data: OrderScreenData) => {
|
||||
doc.on('click', '.prevButton', goToPrevPage)
|
||||
doc.on('click', '.loadPageGroup', loadPageGroup)
|
||||
doc.on('click', '[data-primary-action=item]', itemButtonClicked)
|
||||
doc.on('click', '[data-primary-action=grid],[data-secondary-action=grid]', gridButtonClicked)
|
||||
doc.on('click', '.closeGrid', hideGrids)
|
||||
doc.on('click', '.freetextButton', freetext)
|
||||
doc.on('click', '.openItemButton', customItem)
|
||||
doc.on('click', '.orderBoxTable tbody tr', itemRowClicked)
|
||||
@@ -67,6 +81,9 @@ const setupOrderScreen = (data: OrderScreenData) => {
|
||||
doc.on('dblclick', '.voidButton', voidLastItem)
|
||||
doc.on('click', '.numpadButton', overrideQty)
|
||||
doc.on('click', '.accumulateButton', () => toggleMode('accumulate'))
|
||||
doc.on('click', '.changeCoverNumberButton', changeCoverNumberPrompt)
|
||||
doc.on('click', '.showCoverSelectorButton', showCoverSelector)
|
||||
doc.on('click', '.coverSelectorButton', coverSelected)
|
||||
doc.on('change', '[name=print_override]', printGroupOverride)
|
||||
|
||||
turnOnMode('accumulate')
|
||||
@@ -85,23 +102,29 @@ const setupOrderScreen = (data: OrderScreenData) => {
|
||||
|
||||
/**
|
||||
* @param direction 1 for forward, -1 for backwards.
|
||||
* @param button
|
||||
*/
|
||||
const navigatePage = (direction: number) => {
|
||||
let grid = $('.pageGroup:visible')
|
||||
const navigatePage = (direction: number, button: JQuery) => {
|
||||
const grid =
|
||||
button
|
||||
.parent()
|
||||
.parent()
|
||||
.find('.pageGroup:visible')
|
||||
grid.get()[0].scrollLeft += grid.width() * direction
|
||||
}
|
||||
|
||||
const goToNextPage = () => navigatePage(1)
|
||||
const goToPrevPage = () => navigatePage(-1)
|
||||
const goToNextPage = (e: JQuery.TriggeredEvent) => navigatePage(1, $(e.target))
|
||||
const goToPrevPage = (e: JQuery.TriggeredEvent) => navigatePage(-1, $(e.target))
|
||||
|
||||
const addItemToOrderBox = (orderItem:orderItem) => {
|
||||
const orderBox = $('.orderBoxTable tbody')
|
||||
let selectedRows = orderBox.find('tr.selected')
|
||||
let lastRow : JQuery = selectedRows.length ? selectedRows.first() : orderBox.find('tr').last()
|
||||
let lastRow : JQuery = selectedRows.length ? getLastInstructionRow(selectedRows.first()) : orderBox.find('tr').last()
|
||||
const existingRow = orderBox
|
||||
.find('tr')
|
||||
.filterByData('item', orderItem.item)
|
||||
.filterByData('print_group', orderItem.print_group)
|
||||
.filterByData('cover', orderItem.cover)
|
||||
.last()
|
||||
|
||||
|
||||
@@ -137,16 +160,28 @@ const addInstructionToOrderBox = (instruction: orderItem) => {
|
||||
const parentRow = getParentRow(selectedRow)
|
||||
if(parentRow.is(selectedRow) || !parentRow.hasClass('selected')) {
|
||||
const newRow = createOrderRow(instruction)
|
||||
getLastInstructionRow(selectedRow).after(newRow.pulse())
|
||||
newRow.setColumnValue(lang('printgroup_header'), selectedRow.getColumnValue(lang('printgroup_header')))
|
||||
getLastInstructionRow(selectedRow).after(newRow)
|
||||
newRow
|
||||
.setColumnValue( lang('printgroup_header'), selectedRow.getColumnValue(lang('printgroup_header')) )
|
||||
|
||||
|
||||
if(parentRow.hasClass('selected')){
|
||||
selectRow(newRow)
|
||||
} else {
|
||||
newRow.pulse()
|
||||
}
|
||||
|
||||
scrollToElement(newRow)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const lastRow = orderBox.find('tr').last()
|
||||
orderBox.append(newRow.pulse())
|
||||
newRow.setColumnValue(lang('printgroup_header'), lastRow.getColumnValue(lang('printgroup_header')))
|
||||
newRow
|
||||
.setColumnValue(lang('printgroup_header'), lastRow.getColumnValue(lang('printgroup_header')))
|
||||
.appendTo(orderBox)
|
||||
.pulse()
|
||||
scrollToElement(newRow)
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +193,7 @@ const addNewItem = (item: item, qty = 1) => {
|
||||
item: item,
|
||||
qty: qty,
|
||||
print_group: printGroup,
|
||||
cover: OrderScreen.selected_cover,
|
||||
}
|
||||
|
||||
switch(item.item_type){
|
||||
@@ -222,19 +258,23 @@ const renderOrderBox = () => {
|
||||
const createOrderRow = (orderItem: orderItem) => {
|
||||
const row = $('.orderBoxTable').EmptyRow()
|
||||
const price = money(orderItem.item.price1)
|
||||
row.data('order-item-id', orderItem.id)
|
||||
row.addClass(`${orderItem.item.item_type}Row`)
|
||||
|
||||
const itemCellText = $('<span/>').text(orderItem.item.item_name)
|
||||
row
|
||||
.addClass(`${orderItem.item.item_type}Row`)
|
||||
.setColumnValue(lang('qty_header'), orderItem.qty)
|
||||
.setColumnValue(lang('item_header'), orderItem.item.item_name)
|
||||
.setColumnValue(lang('price_header'), price)
|
||||
.setColumnValue(lang('id_header'), orderItem.item.id)
|
||||
.setColumnValue(lang('total_price_header'), price.multiply(orderItem.qty))
|
||||
.setColumnValue(lang('printgroup_header'), orderItem.print_group?.name)
|
||||
.data('order-item-id', orderItem.id)
|
||||
.data('order-item-id', orderItem.id)
|
||||
.data('print_group', orderItem.print_group)
|
||||
.data('cover', orderItem.cover)
|
||||
.data('item', orderItem.item)
|
||||
.find('td.itemCell')
|
||||
.append(itemCellText)
|
||||
|
||||
changeCoverOnRow(row, orderItem.cover)
|
||||
|
||||
if(orderItem.item.item_type == 'instruction' && price.value <= 0){
|
||||
row
|
||||
@@ -246,6 +286,7 @@ const createOrderRow = (orderItem: orderItem) => {
|
||||
}
|
||||
|
||||
const itemButtonClicked = (e: JQuery.TriggeredEvent) => {
|
||||
hideGrids()
|
||||
const existingItemRows = $('.itemRow')
|
||||
const button = $(e.target).closest('.posButton')
|
||||
const item : item = button.data('item')
|
||||
@@ -259,6 +300,41 @@ const itemButtonClicked = (e: JQuery.TriggeredEvent) => {
|
||||
|
||||
}
|
||||
|
||||
const gridButtonClicked = (e: JQuery.TriggeredEvent) => {
|
||||
const button = $(e.target).closest('.posButton')
|
||||
const grid : number = button.data('grid')
|
||||
ajax(`/orderScreen/getGridHtml/${grid}`, null, null,gridHtmlGenerated, null, null)
|
||||
}
|
||||
|
||||
|
||||
const hideGrids = () => $('.gridContainer').hide()
|
||||
|
||||
|
||||
const gridHtmlGenerated = (gridData: {gridHtml:string, grid: grid}) => {
|
||||
const gridContainer = $('.gridContainer')
|
||||
const gridCellWidth = getGridCellWidth()
|
||||
const gridCellHeight = getGridCellHeight()
|
||||
const grid = gridData.grid
|
||||
const gridHtml = gridData.gridHtml
|
||||
|
||||
gridContainer
|
||||
.show()
|
||||
.width(gridCellWidth * grid.grid_cols)
|
||||
.children('.gridContainerHeader')
|
||||
.children('span')
|
||||
.text(grid.grid_name)
|
||||
.parent()
|
||||
.parent()
|
||||
.find('.pageGroup')
|
||||
.html(gridHtml)
|
||||
.show()
|
||||
.parent()
|
||||
.height(gridCellHeight * grid.grid_rows)
|
||||
.closest('.gridContainer')
|
||||
.find('.pageNavigation')
|
||||
.toggle(gridContainer.find('.gridPage').length > 1)
|
||||
.height(gridCellHeight)
|
||||
}
|
||||
|
||||
const itemRowClicked = (e: JQuery.TriggeredEvent) => {
|
||||
const row = $(e.target).closest('tr')
|
||||
@@ -369,7 +445,19 @@ const decrementQty = (row: JQuery, qty=1) => {
|
||||
calculateRowTotal(row)
|
||||
}
|
||||
|
||||
const scrollToElement = (element: JQuery) => element.get()[0].scrollIntoView()
|
||||
const scrollToElement = (JQueryElement: JQuery) => {
|
||||
const element = JQueryElement.get()[0]
|
||||
const container = JQueryElement.closest('.orderBox').get()[0]
|
||||
const containerTop = $(container).scrollTop()
|
||||
const containerBottom = containerTop + $(container).height();
|
||||
const elemTop = element.offsetTop
|
||||
const elemBottom = elemTop + $(element).height();
|
||||
if (elemTop < containerTop) {
|
||||
$(container).scrollTop(elemTop);
|
||||
} else if (elemBottom > containerBottom) {
|
||||
$(container).scrollTop(elemBottom - $(container).height());
|
||||
}
|
||||
}
|
||||
|
||||
const overrideQty = () => showVirtualNumpad(lang('multiplier'), 4, false, true, true, qtyOverridden)
|
||||
|
||||
@@ -429,4 +517,88 @@ const customItemTextSubmitted = (text: string) => {
|
||||
showVirtualNumpad(lang('enter_item_price'), 4, false, true, true, submitFunction)
|
||||
}
|
||||
|
||||
$(() => ajax('/orderScreen/getOrderScreenData/1', null, 'get', setupOrderScreen, null, null) )
|
||||
const getGridCellHeight = () => $('#pageGroupContainer').height()/8
|
||||
const getGridCellWidth = () => $('#pageGroupContainer').width()/6
|
||||
|
||||
|
||||
const showCoverSelector = (event: JQuery.TriggeredEvent) => {
|
||||
const button = $(event.target)
|
||||
const gridHeight = getGridCellHeight()
|
||||
|
||||
const coverSelector = $('.coverSelector')
|
||||
coverSelector
|
||||
.toggle(!coverSelector.is(':visible'))
|
||||
.width(button.width())
|
||||
.css({
|
||||
left: button.offset().left + 'px',
|
||||
top: button.offset().top + button.height() + 'px',
|
||||
})
|
||||
.find('.coverSelectorButton')
|
||||
.height(gridHeight)
|
||||
|
||||
}
|
||||
|
||||
const coverSelected = (event: JQuery.TriggeredEvent) => {
|
||||
$('.coverSelector').hide()
|
||||
const button = $(event.target)
|
||||
const cover = Number(button.data('cover'))
|
||||
const selectedRows = $('.orderBoxTable tbody').find('tr.itemRow.selected')
|
||||
|
||||
selectedRows.each( (_, selectedRow) => changeCoverOnRow($(selectedRow), cover))
|
||||
OrderScreen.selected_cover = cover
|
||||
}
|
||||
|
||||
const changeCoverOnRow = (row: JQuery, cover: number) => {
|
||||
row.data('cover', cover)
|
||||
const itemCell = row.find('.itemCell')
|
||||
const existingCoverSpan = itemCell.find('small')
|
||||
const coverSpan = existingCoverSpan.length > 0
|
||||
? existingCoverSpan
|
||||
: $('<small/>').appendTo(itemCell)
|
||||
|
||||
coverSpan.text(lang('selected_cover', cover.toString()))
|
||||
if(cover < 1 || !row.hasClass('itemRow')) {
|
||||
coverSpan.remove()
|
||||
}
|
||||
}
|
||||
|
||||
const changeCoverNumberPrompt = () =>
|
||||
showVirtualNumpad(lang('how_many_covers'), 3, false, false, true, changeCoverNumberPromptSubmitted)
|
||||
|
||||
|
||||
const changeCoverNumberPromptSubmitted = (value: string) => updateCoverNumbers(Number(value))
|
||||
|
||||
const updateCoverNumbers = (covers: number) => {
|
||||
let newTable = Object.assign({}, OrderScreen.table)
|
||||
newTable.default_covers = covers
|
||||
ajax('/orderScreen/updateCovers', newTable, 'post', coverNumbersUpdated, null, null)
|
||||
}
|
||||
|
||||
const coverNumbersUpdated = (newTable: floorplan_table) => {
|
||||
const covers = newTable.default_covers
|
||||
OrderScreen.table = newTable
|
||||
$('.changeCoverNumberButton').text(lang('covers', covers.toString()))
|
||||
generateCoverSelector()
|
||||
}
|
||||
|
||||
const generateCoverSelector = () => {
|
||||
const covers = OrderScreen.table.default_covers
|
||||
const coverSelector = $('.coverSelector')
|
||||
coverSelector.hide().children().remove()
|
||||
|
||||
for(let cover=0; cover<=covers; cover++) {
|
||||
const buttonText = cover==0 ? lang('cover_zero') : lang('selected_cover', cover.toString())
|
||||
loadTemplate('#posButtonTemplate')
|
||||
.find('a')
|
||||
.first()
|
||||
.addClass('coverSelectorButton')
|
||||
.text(buttonText)
|
||||
.data('cover', cover)
|
||||
.appendTo(coverSelector)
|
||||
}
|
||||
}
|
||||
|
||||
$(() => {
|
||||
OrderScreen.table = $('#pageContainer').data('table') || null
|
||||
ajax('/orderScreen/getOrderScreenData/1', null, 'get', setupOrderScreen, null, null)
|
||||
})
|
||||
@@ -8,10 +8,11 @@ interface order {
|
||||
}
|
||||
|
||||
interface orderItem {
|
||||
id: number,
|
||||
qty: number,
|
||||
id: number
|
||||
qty: number
|
||||
print_group: print_group
|
||||
item: item
|
||||
cover: number
|
||||
}
|
||||
|
||||
interface print_group {
|
||||
@@ -32,7 +33,7 @@ interface ApplicationState {
|
||||
languageVars: Record<any, string>
|
||||
}
|
||||
|
||||
interface table {
|
||||
interface floorplan_table {
|
||||
table_number: number,
|
||||
room_id: number
|
||||
venue_id: number
|
||||
@@ -71,11 +72,11 @@ interface room {
|
||||
|
||||
interface reservation {
|
||||
id: number,
|
||||
reservation_name: string,
|
||||
reservation_time: number,
|
||||
reservation_covers: number,
|
||||
reservation_created_at: number,
|
||||
reservation_table_id: number,
|
||||
name: string,
|
||||
time: number,
|
||||
covers: number,
|
||||
created_at: number,
|
||||
floorplan_table_id: number,
|
||||
}
|
||||
|
||||
interface keyboard {
|
||||
|
||||
@@ -120,108 +120,120 @@
|
||||
::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
.pageGroup
|
||||
/*display: inline-flex*/
|
||||
@include flex-column-item
|
||||
flex-basis: 100%
|
||||
flex-grow: 0
|
||||
overflow-x: auto
|
||||
display: none
|
||||
.pageGroup
|
||||
/*display: inline-flex*/
|
||||
@include flex-column-item
|
||||
flex-basis: 100%
|
||||
flex-grow: 0
|
||||
overflow-x: auto
|
||||
display: none
|
||||
|
||||
.gridPage
|
||||
width: 100%
|
||||
height: 100%
|
||||
flex-shrink: 0
|
||||
flex-grow: 0
|
||||
display: grid
|
||||
grid-template-columns: repeat(6, 1fr)
|
||||
grid-template-rows: repeat(8, 1fr)
|
||||
.gridPage
|
||||
width: 100%
|
||||
height: 100%
|
||||
flex-shrink: 0
|
||||
flex-grow: 0
|
||||
display: grid
|
||||
|
||||
.doubleWidth
|
||||
width: calc(200%)
|
||||
z-index: 10
|
||||
.doubleWidth
|
||||
width: calc(200%)
|
||||
z-index: 10
|
||||
|
||||
.doubleHeight
|
||||
height: calc(200%)
|
||||
z-index: 10
|
||||
.doubleHeight
|
||||
height: calc(200%)
|
||||
z-index: 10
|
||||
|
||||
.hasImage
|
||||
.buttonImg
|
||||
background-repeat: no-repeat
|
||||
background-size: contain
|
||||
background-position: center
|
||||
background-origin: content-box
|
||||
.hasImage
|
||||
.buttonImg
|
||||
background-repeat: no-repeat
|
||||
background-size: contain
|
||||
background-position: center
|
||||
background-origin: content-box
|
||||
|
||||
.hasImage.normal
|
||||
font-size: 0.8em
|
||||
.buttonImg
|
||||
flex-basis: 40%
|
||||
height: 100%
|
||||
padding: 0.7em
|
||||
justify-content: flex-end
|
||||
.hasImage.normal
|
||||
font-size: 0.8em
|
||||
.buttonImg
|
||||
flex-basis: 40%
|
||||
height: 100%
|
||||
padding: 0.7em
|
||||
justify-content: flex-end
|
||||
|
||||
.text
|
||||
@include flex
|
||||
justify-content: flex-start
|
||||
flex-basis: 60%
|
||||
height: 100%
|
||||
|
||||
.hasImage.doubleHeight
|
||||
@include flex-column
|
||||
|
||||
.buttonImg
|
||||
padding: 0.6em
|
||||
flex-basis: 65%
|
||||
width: 100%
|
||||
flex-shrink: 0
|
||||
flex-grow: 0
|
||||
|
||||
.text
|
||||
@include flex
|
||||
align-items: flex-start
|
||||
flex-grow: 0
|
||||
flex-shrink: 0
|
||||
flex-basis: 35%
|
||||
width: 100%
|
||||
overflow: hidden
|
||||
font-size: 0.9em
|
||||
|
||||
.hasImage.doubleWidth
|
||||
flex-direction: row
|
||||
.buttonImg
|
||||
@include flex
|
||||
flex-basis: 30%
|
||||
height: 100%
|
||||
padding-top: 2%
|
||||
|
||||
.text
|
||||
@include flex
|
||||
flex-basis: 70%
|
||||
height: 100%
|
||||
justify-content: flex-start
|
||||
|
||||
.hasImage.doubleHeight.doubleWidth
|
||||
flex-direction: row
|
||||
|
||||
.buttonImg
|
||||
@include flex
|
||||
flex-basis: 50%
|
||||
height: 100%
|
||||
|
||||
|
||||
.text
|
||||
@include flex
|
||||
flex-basis: 50%
|
||||
height: 100%
|
||||
|
||||
|
||||
.pageNavigation
|
||||
.text
|
||||
@include flex
|
||||
@include flex-column-item
|
||||
display: none
|
||||
justify-content: flex-start
|
||||
flex-basis: 60%
|
||||
height: 100%
|
||||
|
||||
> *
|
||||
@include flex-item
|
||||
.hasImage.doubleHeight
|
||||
@include flex-column
|
||||
|
||||
.buttonImg
|
||||
padding: 0.6em
|
||||
flex-basis: 65%
|
||||
width: 100%
|
||||
flex-shrink: 0
|
||||
flex-grow: 0
|
||||
|
||||
.text
|
||||
@include flex
|
||||
align-items: flex-start
|
||||
flex-grow: 0
|
||||
flex-shrink: 0
|
||||
flex-basis: 35%
|
||||
width: 100%
|
||||
overflow: hidden
|
||||
font-size: 0.9em
|
||||
|
||||
.hasImage.doubleWidth
|
||||
flex-direction: row
|
||||
.buttonImg
|
||||
@include flex
|
||||
flex-basis: 30%
|
||||
height: 100%
|
||||
padding-top: 2%
|
||||
|
||||
.text
|
||||
@include flex
|
||||
flex-basis: 70%
|
||||
height: 100%
|
||||
justify-content: flex-start
|
||||
|
||||
.hasImage.doubleHeight.doubleWidth
|
||||
flex-direction: row
|
||||
|
||||
.buttonImg
|
||||
@include flex
|
||||
flex-basis: 50%
|
||||
height: 100%
|
||||
|
||||
|
||||
.text
|
||||
@include flex
|
||||
flex-basis: 50%
|
||||
height: 100%
|
||||
|
||||
|
||||
.pageNavigation
|
||||
@include flex
|
||||
@include flex-column-item
|
||||
|
||||
> *
|
||||
@include flex-item
|
||||
|
||||
|
||||
.coverSelector
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
border: 2px solid var(--global-border-color)
|
||||
background: var(--global-bgcolor)
|
||||
position: absolute
|
||||
z-index: 100
|
||||
|
||||
.coverSelectorButton
|
||||
flex-basis: 50%
|
||||
|
||||
.coverSelectorButton:first-of-type
|
||||
flex-basis: 100%
|
||||
|
||||
|
||||
.orderBoxTable
|
||||
@@ -267,12 +279,65 @@
|
||||
|
||||
td.itemCell
|
||||
text-align: left
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
tr.instructionRow
|
||||
td
|
||||
font-weight: 100
|
||||
td.itemCell
|
||||
padding-left: 2em
|
||||
small
|
||||
font-size: 0
|
||||
|
||||
.qtyCell, .printGroupCell
|
||||
font-size: 0
|
||||
|
||||
.gridContainer
|
||||
background: var(--global-bgcolor)
|
||||
border: var(--global-border-color) solid 2px
|
||||
z-index: 500
|
||||
margin: auto
|
||||
position: absolute
|
||||
left: 0
|
||||
right: 0
|
||||
top: 50%
|
||||
transform: translateY(-50%)
|
||||
|
||||
.gridContainerHeader
|
||||
height: 3em
|
||||
width: 100%
|
||||
@include flex
|
||||
background-color: var(--global-secondary-bgcolor)
|
||||
border-bottom: solid 1px var(--global-border-color)
|
||||
|
||||
> *
|
||||
@include flex
|
||||
height: 100%
|
||||
|
||||
span
|
||||
flex-basis: 90%
|
||||
.closeGrid
|
||||
flex-basis: 10%
|
||||
|
||||
.gridContainerGrid
|
||||
width: 100%
|
||||
@include flex-column
|
||||
scrollbar-width: none
|
||||
-ms-overflow-style: none
|
||||
|
||||
::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
.pageGroup
|
||||
display: inline-flex
|
||||
flex-basis: 100%
|
||||
flex-grow: 0
|
||||
overflow-x: auto
|
||||
|
||||
.gridPage
|
||||
width: 100%
|
||||
height: 100%
|
||||
flex-shrink: 0
|
||||
flex-grow: 0
|
||||
display: grid
|
||||
@@ -8,11 +8,11 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="pageContainer">
|
||||
<div id="pageContainer" <!--[var: containerAttributes]-->>
|
||||
<div id="leftColumn">
|
||||
<h1 class="tableHeading"><!--[var: orderNumber]--></h1>
|
||||
<div class="tableInfo">
|
||||
<!--[var: coverSelectorButton]-->
|
||||
<!--[var: changeCoverNumberButton]-->
|
||||
<a class="posButton">Logged in as <!--[arr:clerk|clerk_name]--></a>
|
||||
</div>
|
||||
<div class="orderBox">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="functionColumn">
|
||||
<a class="posButton accumulateButton" data-active-in-mode="accumulate"><!--[lang:accumulate_function]--></a>
|
||||
<a class="selectCoversButton posButton"><!--[lang:select_covers]--></a>
|
||||
<a class="showCoverSelectorButton posButton"><!--[lang:select_covers]--></a>
|
||||
</div>
|
||||
<div class="functionColumn">
|
||||
<a class="posButton voidButton" data-active-in-mode="void"><!--[lang:void]--></a>
|
||||
@@ -75,6 +75,10 @@
|
||||
</div>
|
||||
|
||||
<!--[template:keyboards]-->
|
||||
|
||||
<!--[template:orderScreen/grid_container]-->
|
||||
<!--[template:orderScreen/cover_selector]-->
|
||||
<template id="posButtonTemplate">
|
||||
<!--[template:components/posButton]-->
|
||||
</template>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
<a href="#" class="posButton changeCoverNumberButton"><!--[var:covers]--></a>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="coverSelector">
|
||||
<!--[var:coverSelectorButtons]-->
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
<a href="#" class="posButton coverSelector"><!--[var:covers]--></a>
|
||||
13
wwwroot/themes/restaurant/orderScreen/grid_container.tpl.htm
Normal file
13
wwwroot/themes/restaurant/orderScreen/grid_container.tpl.htm
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="gridContainer">
|
||||
<div class="gridContainerHeader">
|
||||
<span></span>
|
||||
<div class="posButton closeGrid">×</div>
|
||||
</div>
|
||||
<div class="gridContainerGrid">
|
||||
<div class="pageGroup"></div>
|
||||
</div>
|
||||
<div class="pageNavigation">
|
||||
<a class="posButton prevButton"><!--[lang:prev_page]--></a>
|
||||
<a class="posButton nextButton"><!--[lang:next_page]--></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,6 @@
|
||||
<div class="gridPage">
|
||||
<div class="gridPage" style="
|
||||
grid-template-columns: repeat(<!--[var:cols]-->, 1fr);
|
||||
grid-template-rows: repeat(<!--[var:rows]-->, 1fr);
|
||||
">
|
||||
<!--[var:pageButtons]-->
|
||||
</div>
|
||||
Reference in New Issue
Block a user