Added print group overrides

This commit is contained in:
2022-01-08 17:53:23 +10:00
parent 198d609e62
commit f656c5ab40
11 changed files with 133 additions and 58 deletions

View File

@@ -2,6 +2,7 @@
open DredgeFramework open DredgeFramework
open DredgePos open DredgePos
open DredgePos.Types
open Floorplan open Floorplan
open Microsoft.AspNetCore.Http open Microsoft.AspNetCore.Http
open Reservations open Reservations
@@ -57,6 +58,7 @@ let getOrderScreenData (id: int) =
{| {|
order_screen_pages = Entity.getAllInVenue<order_screen_page_group> order_screen_pages = Entity.getAllInVenue<order_screen_page_group>
sales_categories = Entity.getAllInVenue<sales_category> sales_categories = Entity.getAllInVenue<sales_category>
print_groups = Entity.getAllInVenue<print_group>
|} |}
|> ajaxSuccess |> ajaxSuccess
|> json |> json

View File

@@ -75,12 +75,13 @@ let renderPageGroup (pageGroup: order_screen_page_group) (pageHTML: string) =
] ]
loadTemplateWithVars "orderScreen/page_group" vars loadTemplateWithVars "orderScreen/page_group" vars
let categoryPosButton (category: sales_category) = PosButton (language.getAndReplace "print_with" [category.name]) "categoryOverrideButton" "" let printGroupPosButton (printGroup: print_group) =
PosButton (language.getAndReplace "print_with" [printGroup.name]) "printGroupOverrideButton toggle" $"""data-value="{printGroup.id}" """
let generateSalesCategoryOverrideButtons () = let generateSalesCategoryOverrideButtons () =
Entity.getAllInVenue<sales_category> Entity.getAllInVenue<print_group>
|> Array.map categoryPosButton |> Array.map printGroupPosButton
|> Array.append ([|PosButton (language.getAndReplace "print_with" ["default"]) "categoryOverrideButton" ""|]) |> Array.append ([|PosButton (language.getAndReplace "print_with" ["default"]) "printGroupOverrideButton toggle default active" """data-value="0" """|])
|> String.concat "\n" |> String.concat "\n"

View File

@@ -78,7 +78,7 @@ let ParseSimpleLanguageVariables (string:string) =
let ParseLanguageVariablesWithReplacements (string: string) = let ParseLanguageVariablesWithReplacements (string: string) =
Regex.Replace(string, "<!--\[lang\:(.*?)\|(.*?)\]-->", Regex.Replace(string, "<!--\[lang\:(.*?)\|(.*?)\]-->",
new MatchEvaluator( MatchEvaluator(
fun matchedVar -> fun matchedVar ->
let varName = matchedVar.Groups[1].ToString() let varName = matchedVar.Groups[1].ToString()
let replacements = matchedVar.Groups[2].ToString() let replacements = matchedVar.Groups[2].ToString()

View File

@@ -41,7 +41,7 @@ type sales_category = {
id: int id: int
parent: int parent: int
name: string name: string
print_group: string print_group: int
venue_id: int venue_id: int
} }

View File

@@ -35,6 +35,7 @@
"functions_header":"Functions", "functions_header":"Functions",
"close_order_function":"Close Without Saving", "close_order_function":"Close Without Saving",
"accumulate_function":"Accumulate Items", "accumulate_function":"Accumulate Items",
"multiplier":"Enter a Number",
"void":"Void", "void":"Void",
"pay_function":"Pay", "pay_function":"Pay",
"print_function":"Save & Print", "print_function":"Save & Print",

View File

@@ -79,6 +79,7 @@ const setupCore = (languageVars: Record<string, string>) => {
Application.languageVars = languageVars Application.languageVars = languageVars
const doc = $(document) const doc = $(document)
doc.on('click', '#alertNo, #alertOk', hideAlerts) doc.on('click', '#alertNo, #alertOk', hideAlerts)
doc.on('click', '.toggle', toggle)
window.addEventListener('resize', resize) window.addEventListener('resize', resize)
resize() resize()
@@ -194,6 +195,31 @@ Array.prototype.where = function<x>(this: x[], property: string, value: any) {
const money = (amount: number, fromCents=true) => currency(amount, {fromCents: fromCents}) const money = (amount: number, fromCents=true) => currency(amount, {fromCents: fromCents})
const moneyFromString = (amount: string) => currency(amount) const moneyFromString = (amount: string) => currency(amount)
const toggle = (e: JQuery.TriggeredEvent) => {
const button = $(e.target)
const toggleGroup = button.closest('.toggleGroup')
const input = toggleGroup.find('input.value')
const isActive = button.hasClass('active')
toggleGroup
.find('.toggle')
.removeClass('active')
let value = !isActive
? button.addClass('active').data('value')
: toggleGroup
.find('.toggle.default')
.addClass('active')
.data('value')
input.val(value).trigger('change')
}
const resetToggle = (input: JQuery) => {
input
.closest('.toggleGroup')
.find('.toggle.default')
.trigger('click')
}
//Id generator. //Id generator.
function* newestId(){ function* newestId(){
let id = 0 let id = 0

View File

@@ -1,25 +1,31 @@
type OrderScreenData = { type OrderScreenData = {
order_screen_pages: order_screen_page[] order_screen_pages: order_screen_page[]
sales_categories: sales_category[] sales_categories: sales_category[]
print_groups: print_group[]
} }
type OrderScreen = { type OrderScreen = {
order_screen_pages: order_screen_page[] order_screen_pages: order_screen_page[]
last_added_item: orderItem last_added_item: orderItem
order_items: orderItem[] order_items: orderItem[]
sales_categories: sales_category[] sales_categories: sales_category[]
print_groups: print_group[]
order_item_id_generator: Generator order_item_id_generator: Generator
selected_item_ids: number[] selected_item_ids: number[]
qty_override: number
print_group_override: print_group
} }
let OrderScreen : OrderScreen = { let OrderScreen : OrderScreen = {
order_screen_pages: null, order_screen_pages: null,
last_added_item: null, last_added_item: null,
order_items: [], order_items: [],
print_groups: [],
sales_categories: [], sales_categories: [],
order_item_id_generator: newestId(), order_item_id_generator: newestId(),
selected_item_ids: [], selected_item_ids: [],
qty_override: 1,
print_group_override: null
} }
const loadPageGroup = (e: Event) => { const loadPageGroup = (e: Event) => {
@@ -42,6 +48,8 @@ const loadPageGroup = (e: Event) => {
const setupOrderScreen = (data: OrderScreenData) => { const setupOrderScreen = (data: OrderScreenData) => {
OrderScreen.order_screen_pages = data.order_screen_pages OrderScreen.order_screen_pages = data.order_screen_pages
OrderScreen.sales_categories = data.sales_categories OrderScreen.sales_categories = data.sales_categories
OrderScreen.print_groups = data.print_groups
updateOrderBoxTotals()
let doc = $(document) let doc = $(document)
doc.on('click', '.nextButton', goToNextPage) doc.on('click', '.nextButton', goToNextPage)
doc.on('click', '.prevButton', goToPrevPage) doc.on('click', '.prevButton', goToPrevPage)
@@ -50,7 +58,9 @@ const setupOrderScreen = (data: OrderScreenData) => {
doc.on('click', '.orderBoxTable tbody tr', itemRowClicked) doc.on('click', '.orderBoxTable tbody tr', itemRowClicked)
doc.on('click', '.voidButton', voidButtonClicked) doc.on('click', '.voidButton', voidButtonClicked)
doc.on('dblclick', '.voidButton', voidLastItem) doc.on('dblclick', '.voidButton', voidLastItem)
doc.on('click', '.numpadButton', overrideQty)
doc.on('click', '.accumulateButton', () => toggleMode('accumulate')) doc.on('click', '.accumulateButton', () => toggleMode('accumulate'))
doc.on('change', '[name=print_override]', printGroupOverride)
turnOnMode('accumulate') turnOnMode('accumulate')
@@ -64,7 +74,6 @@ const setupOrderScreen = (data: OrderScreenData) => {
childList: true childList: true
}); });
} }
/** /**
@@ -82,7 +91,12 @@ const addItemToOrderBox = (orderItem:orderItem) => {
const orderBox = $('.orderBoxTable tbody') const orderBox = $('.orderBoxTable tbody')
let selectedRows = orderBox.find('tr.selected') let selectedRows = orderBox.find('tr.selected')
let lastRow : JQuery = selectedRows.length ? selectedRows.first() : orderBox.find('tr').last() let lastRow : JQuery = selectedRows.length ? selectedRows.first() : orderBox.find('tr').last()
const existingRow = orderBox.find(`.itemCell:contains("${orderItem.item.item_name}")`).closest('tr').last() const existingRow = orderBox
.find('tr')
.filterByData('item', orderItem.item)
.filterByData('print_group', orderItem.print_group)
.last()
//If accumulating, just increase the quantity of the existing row. //If accumulating, just increase the quantity of the existing row.
if(existingRow.length > 0 && isInMode('accumulate')){ if(existingRow.length > 0 && isInMode('accumulate')){
@@ -114,7 +128,6 @@ const addInstructionToOrderBox = (instruction: orderItem) => {
selectedRows.each( (_, row) => { selectedRows.each( (_, row) => {
const selectedRow = $(row) const selectedRow = $(row)
const parentRow = getParentRow(selectedRow) const parentRow = getParentRow(selectedRow)
if(parentRow.is(selectedRow) || !parentRow.hasClass('selected')) { if(parentRow.is(selectedRow) || !parentRow.hasClass('selected')) {
const newRow = createOrderRow(instruction) const newRow = createOrderRow(instruction)
getLastInstructionRow(selectedRow).after(newRow.pulse()) getLastInstructionRow(selectedRow).after(newRow.pulse())
@@ -128,14 +141,13 @@ const addInstructionToOrderBox = (instruction: orderItem) => {
const addNewItem = (item: item, qty = 1) => { const addNewItem = (item: item, qty = 1) => {
const salesCategory = OrderScreen.sales_categories.where('id', item.item_category) const salesCategory = OrderScreen.sales_categories.where('id', item.item_category)
const printGroup = OrderScreen.print_group_override ?? OrderScreen.print_groups.where('id', salesCategory.print_group)
const orderItem : orderItem = { const orderItem : orderItem = {
id: OrderScreen.order_item_id_generator.next().value, id: OrderScreen.order_item_id_generator.next().value,
item: item, item: item,
qty: qty, qty: qty,
sales_category: salesCategory, print_group: printGroup,
} }
switch(item.item_type){ switch(item.item_type){
@@ -202,13 +214,23 @@ const createOrderRow = (orderItem: orderItem) => {
const price = money(orderItem.item.price1) const price = money(orderItem.item.price1)
row.data('order-item-id', orderItem.id) row.data('order-item-id', orderItem.id)
row.addClass(`${orderItem.item.item_type}Row`) row.addClass(`${orderItem.item.item_type}Row`)
row row
.setColumnValue(lang('qty_header'), orderItem.qty) .setColumnValue(lang('qty_header'), orderItem.qty)
.setColumnValue(lang('item_header'), orderItem.item.item_name) .setColumnValue(lang('item_header'), orderItem.item.item_name)
.setColumnValue(lang('price_header'), price) .setColumnValue(lang('price_header'), price)
.setColumnValue(lang('total_price_header'), price) .setColumnValue(lang('id_header'), orderItem.item.id)
.setColumnValue(lang('printgroup_header'), OrderScreen.sales_categories.where('id', orderItem.item.item_category)?.name) .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('item', orderItem.item)
if(orderItem.item.item_type == 'instruction' && price.value <= 0){
row
.find('.totalPriceCell')
.css('font-size', 0)
}
return row return row
} }
@@ -220,7 +242,10 @@ const itemButtonClicked = (e: JQuery.TriggeredEvent) => {
if(item.item_type == 'instruction' && existingItemRows.length < 1) return if(item.item_type == 'instruction' && existingItemRows.length < 1) return
addNewItem(item) const qty = OrderScreen.qty_override || 1
OrderScreen.qty_override = 1
addNewItem(item, qty)
} }
@@ -296,8 +321,11 @@ const voidLastItem = () => {
const updateOrderBoxTotals = () => { const updateOrderBoxTotals = () => {
const allRows = $('.orderBoxTable tbody tr') const allRows = $('.orderBoxTable tbody tr')
const selectedRows = $('.orderBoxTable tbody tr.selected') const selectedRows = $('.orderBoxTable tbody tr.selected')
$('.orderBoxTotal').text(getTotalOfRows(allRows)) const completeTotal = lang('totalPrice', getTotalOfRows(allRows))
$('.orderBoxSelectedTotal').text(getTotalOfRows(selectedRows)) const selectedTotal = lang('selectedPrice', getTotalOfRows(selectedRows))
$('.orderBoxTotal').text(completeTotal)
$('.orderBoxSelectedTotal').text(selectedTotal)
} }
const getTotalOfRows = (rows: JQuery) => { const getTotalOfRows = (rows: JQuery) => {
@@ -318,20 +346,45 @@ const calculateRowTotal = (row: JQuery) => {
row.setColumnValue(lang('total_price_header'), price.multiply(qty)) row.setColumnValue(lang('total_price_header'), price.multiply(qty))
} }
const decrementQty = (row: JQuery) => { const decrementQty = (row: JQuery, qty=1) => {
const qty = getQty(row) const existingQty = getQty(row)
if(qty <= 1){
if(existingQty <= 1){
const childRows = row.nextUntil('.itemRow') const childRows = row.nextUntil('.itemRow')
deleteRow(row) deleteRow(row)
deleteRow(childRows) deleteRow(childRows)
return return
} }
row.setColumnValue(lang('qty_header'), existingQty - qty)
row.setColumnValue(lang('qty_header'), qty - 1)
calculateRowTotal(row) calculateRowTotal(row)
} }
const scrollToElement = (element: JQuery) => element.get()[0].scrollIntoView() const scrollToElement = (element: JQuery) => element.get()[0].scrollIntoView()
const overrideQty = () => showVirtualNumpad(lang('multiplier'), 4, false, true, true, qtyOverridden)
const qtyOverridden = (qtyString: string) => OrderScreen.qty_override = Number(qtyString)
const printGroupOverride = (e: JQuery.TriggeredEvent) => {
const input = $(e.target)
const printGroupId = Number(input.val())
const orderBox = $('.orderBoxTable tbody')
const selectedRows = orderBox.find('tr.selected')
const newPrintGroup = OrderScreen.print_groups.where('id', printGroupId)
if(selectedRows.length && newPrintGroup){
selectedRows.each((index, row) => {
$(row).setColumnValue(lang('printgroup_header'), newPrintGroup.name)
$(row).data('print_group', newPrintGroup)
})
OrderScreen.print_group_override = null
resetToggle(input)
} else {
OrderScreen.print_group_override = newPrintGroup
}
}
$(() => ajax('/orderScreen/getOrderScreenData/1', null, 'get', setupOrderScreen, null, null) ) $(() => ajax('/orderScreen/getOrderScreenData/1', null, 'get', setupOrderScreen, null, null) )

View File

@@ -10,11 +10,11 @@ interface order {
interface orderItem { interface orderItem {
id: number, id: number,
qty: number, qty: number,
sales_category: sales_category print_group: print_group
item: item item: item
} }
interface printGroup { interface print_group {
id: number, id: number,
name: string, name: string,
printer: number, printer: number,

View File

@@ -46,6 +46,7 @@ input[type=text], select, textarea
bottom: 0 bottom: 0
left: 0 left: 0
right: 0 right: 0
z-index: 999
@mixin mobile @mixin mobile
@media screen and (max-width: 900px) @media screen and (max-width: 900px)

View File

@@ -51,8 +51,10 @@
> .orderBoxTotal > .orderBoxTotal
align-items: flex-end align-items: flex-end
> small font-size: 1.3em
> .orderBoxSelectedTotal
align-items: flex-start align-items: flex-start
font-size: 0.9em
#rightColumn #rightColumn
@include flex-column @include flex-column
@@ -68,24 +70,10 @@
flex-grow: 0 flex-grow: 0
flex-shrink: 0 flex-shrink: 0
.utilityButtons
@include flex-column-item
@include flex
flex-basis: 20%
> *
@include flex-item
@include flex
flex-basis: 30%
.logoutButton
flex-basis: 10%
.functionButtons .functionButtons
@include flex-column-item @include flex-column-item
@include flex @include flex
flex-basis: 80% flex-basis: 100%
> * > *
@include flex-item @include flex-item
@@ -256,13 +244,13 @@
.itemCell .itemCell
text-align: center text-align: center
width: 70% width: 60%
.qtyCell .qtyCell
width: 10% width: 10%
.printGroupCell .printGroupCell
width: 10% width: 20%
.totalPriceCell .totalPriceCell
width: 10% width: 10%
@@ -271,9 +259,10 @@
text-align: left text-align: left
tr.instructionRow tr.instructionRow
td
font-weight: 100
td.itemCell td.itemCell
padding-left: 2em padding-left: 2em
font-weight: 100
.qtyCell, .totalPriceCell, .printGroupCell .qtyCell, .printGroupCell
font-size: 0 font-size: 0

View File

@@ -20,6 +20,7 @@
<thead> <thead>
<tr> <tr>
<th class="orderBoxCell qtyCell"><!--[lang:qty_header]--></th> <th class="orderBoxCell qtyCell"><!--[lang:qty_header]--></th>
<th class="orderBoxCell itemIdCell hidden"><!--[lang:id_header]--></th>
<th class="orderBoxCell itemCell"><!--[lang:item_header]--></th> <th class="orderBoxCell itemCell"><!--[lang:item_header]--></th>
<th class="orderBoxCell unitPriceCell hidden"><!--[lang:price_header]--></th> <th class="orderBoxCell unitPriceCell hidden"><!--[lang:price_header]--></th>
<th class="orderBoxCell totalPriceCell"><!--[lang:total_price_header]--></th> <th class="orderBoxCell totalPriceCell"><!--[lang:total_price_header]--></th>
@@ -33,30 +34,31 @@
<span class="voidModeWarning" data-visible-in-mode='["void"]'><!--[lang:void_mode]--></span> <span class="voidModeWarning" data-visible-in-mode='["void"]'><!--[lang:void_mode]--></span>
</div> </div>
<div class="orderBoxFooter"> <div class="orderBoxFooter">
<span class="orderBoxTotal">$0.00</span> <span class="orderBoxTotal"><!--[lang:totalPrice|0.00]--></span>
<small><span class="orderBoxSelectedTotal">$0.00</span></small> <small class="orderBoxSelectedTotal"><!--[lang:selectedPrice|0.00]--></small>
</div> </div>
</div> </div>
<div id="rightColumn"> <div id="rightColumn">
<div id="topHalf"> <div id="topHalf">
<div class="utilityButtons">
<a class="posButton"></a>
<a class="posButton"></a>
<a class="posButton"></a>
<a class="posButton logoutButton">×</a>
</div>
<div class="functionButtons"> <div class="functionButtons">
<div class="functionColumn"> <div class="functionColumn toggleGroup">
<!--[var:salesCategoryOverrideButtons]--> <input type="hidden" name="print_override" class="value" />
<!--[var:salesCategoryOverrideButtons]-->
</div> </div>
<div class="functionColumn"> <div class="functionColumn">
<a class="posButton"></a>
<a class="posButton accumulateButton" data-active-in-mode="accumulate"><!--[lang:accumulate_function]--></a> <a class="posButton accumulateButton" data-active-in-mode="accumulate"><!--[lang:accumulate_function]--></a>
<a class="selectCoversButton posButton"><!--[lang:select_covers]--></a>
<a class="keyboardButton posButton"><!--[lang:freetext_button]--></a>
<a class="numpadButton posButton"><!--[lang:numpad_button]--></a>
</div>
<div class="functionColumn">
<a class="posButton voidButton" data-active-in-mode="void"><!--[lang:void]--></a> <a class="posButton voidButton" data-active-in-mode="void"><!--[lang:void]--></a>
<a class="posButton"></a> <a class="posButton"></a>
</div> </div>
<div class="functionColumn"></div> <div class="functionColumn">
<div class="functionColumn"></div> <a class="posButton"><!--[lang:pay_function]--></a>
<a class="posButton"><!--[lang:print_function]--></a>
</div>
</div> </div>
</div> </div>
<div id="pageList"> <div id="pageList">