Files
DredgePos/wwwroot/scripts/ts/dredgepos.orderScreen.ts
2022-01-04 15:04:55 +10:00

271 lines
8.6 KiB
TypeScript

type OrderScreenData = {
order_screen_pages: order_screen_page[]
sales_categories: sales_category[]
}
type OrderScreen = {
order_screen_pages: order_screen_page[]
last_added_item: orderItem
order_items: orderItem[]
sales_categories: sales_category[]
order_item_id_generator: Generator
selected_item_ids: number[]
}
let OrderScreen : OrderScreen = {
order_screen_pages: null,
last_added_item: null,
order_items: [],
sales_categories: [],
order_item_id_generator: newestId(),
selected_item_ids: []
}
const loadPageGroup = (e: Event) => {
let button = $(e.target)
$('.loadPageGroup').removeClass('active')
button.addClass('active')
let pageGroupId = button.data('page-group-id')
$('.pageGroup').hide()
let activeGrid = $(`.pageGroup[data-page-group-id=${pageGroupId}]`)
let navButtons = $('.pageNavigation')
navButtons.css('display', 'flex')
activeGrid.find('.gridPage').length > 1
? navButtons.show()
: navButtons.hide()
activeGrid.css('display', 'inline-flex')
}
const setupOrderScreen = (data: OrderScreenData) => {
OrderScreen.order_screen_pages = data.order_screen_pages
OrderScreen.sales_categories = data.sales_categories
let doc = $(document)
doc.on('click', '.nextButton', goToNextPage)
doc.on('click', '.prevButton', goToPrevPage)
doc.on('click', '.loadPageGroup', loadPageGroup)
doc.on('click', '[data-primary-action=item]', itemButtonClicked)
doc.on('click', 'tr', itemRowClicked)
doc.on('click', '.voidButton', voidButtonClicked)
doc.on('dblclick', '.voidButton', voidLastItem)
doc.on('click', '.accumulateButton', () => toggleMode('accumulate'))
turnOnMode('accumulate')
$('.loadPageGroup').first().trigger('click')
}
/**
* @param direction 1 for forward, -1 for backwards.
*/
const navigatePage = (direction: number) => {
let grid = $('.pageGroup:visible')
grid.get()[0].scrollLeft += grid.width() * direction
}
const goToNextPage = () => navigatePage(1)
const goToPrevPage = () => navigatePage(-1)
const addNewItem = (item: item) => {
let salesCategory = OrderScreen.sales_categories.where('id', item.item_category)
const existingOrderItem = isInMode('accumulate') && item.item_type != 'instruction' ? OrderScreen.order_items.where('item', item) : null
let orderItem : orderItem = existingOrderItem || {
id: OrderScreen.order_item_id_generator.next().value,
item: item,
qty: 0,
sales_category: salesCategory,
}
saveOrderItem(orderItem)
renderOrderBox()
}
const renderOrderBox = () => {
const orderBox = $('.orderBoxTable')
const tbody = orderBox.children('tbody')
const newTbody = $('<tbody />')
OrderScreen.order_items.forEach(orderItem => {
const newRow = createOrderRow(orderItem)
newTbody.append(newRow)
if(orderItem.id == OrderScreen.last_added_item?.id){
pulseElement(newRow)
}
if(OrderScreen.selected_item_ids.includes(orderItem.id)){
selectRow(newRow)
}
})
tbody.replaceWith(newTbody)
const element = orderBox.find('tbody tr').last().get()[0]
element.scrollIntoView()
OrderScreen.last_added_item = null
}
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`)
row
.setColumnValue(lang('qty_header'), orderItem.qty)
.setColumnValue(lang('item_header'), orderItem.item.item_name)
.setColumnValue(lang('price_header'), price)
.setColumnValue(lang('total_price_header'), price)
.setColumnValue(lang('printgroup_header'), OrderScreen.sales_categories.where('id', orderItem.item.item_category)?.name)
.data('order-item-id', orderItem.id)
return row
}
const saveOrderItem = (orderItem: orderItem) => {
const selectedRows = $('.orderBoxTable tbody tr.selected').get()
const currentQty = orderItem.qty
orderItem.qty = currentQty + 1
if( isInMode('accumulate') && orderItem.qty > 1) {
OrderScreen.order_items = OrderScreen.order_items.map(
existingOrderItem => {
if (existingOrderItem == orderItem) return orderItem
else return existingOrderItem
})
} else if(orderItem.item.item_type == 'instruction' && selectedRows.length > 0){
const selectedOrderItemIds : number[] = selectedRows.map(row => {
const orderItem = OrderScreen.order_items.where('id', $(row).data('order-item-id'))
if (orderItem.item && orderItem.item.item_type != 'instruction') {
return orderItem.id
} else {
return null
}
}).filter(number => number)
selectedOrderItemIds.forEach(id => {
let item = OrderScreen.order_items.where('id', id)
let index = OrderScreen.order_items.indexOf(item) + 1
OrderScreen.order_items.splice(index, 0, orderItem)
})
} else {
OrderScreen.order_items.push(orderItem)
}
OrderScreen.last_added_item = orderItem
return orderItem
}
const itemButtonClicked = (e: JQuery.TriggeredEvent) => {
const existingItemRows = $('.itemRow')
const button = $(e.target).closest('.posButton')
const item : item = button.data('item')
if(item.item_type == 'instruction' && existingItemRows.length < 1) return
addNewItem(item)
}
const itemRowClicked = (e: JQuery.TriggeredEvent) => {
const row = $(e.target).closest('tr')
if(isInMode('void')){
voidRows(row)
turnOffMode('void')
return
}
if(!row.hasClass('selected')) selectRow(row)
else deselectRow(row)
}
const selectRow = (row: JQuery) => {
row.addClass('selected')
const id = row.data('order-item-id')
if(!OrderScreen.selected_item_ids.includes(id))
OrderScreen.selected_item_ids.push(id)
const instructionRows = row.nextUntil('.itemRow')
if(row.hasClass('itemRow') && instructionRows.length){
instructionRows.each((index, row) => {
selectRow($(row))
})
}
}
const deselectRow = (row: JQuery) => {
row.removeClass('selected')
const instructionRows = row.nextUntil('.itemRow')
OrderScreen.selected_item_ids = OrderScreen.selected_item_ids.filter(id => id != row.data('order-item-id'))
if(row.hasClass('itemRow') && instructionRows.length){
deselectRow(instructionRows)
}
}
const deleteRow = (row: JQuery) => row.find('*:not(.hidden)').slideUp('fast', () => {
OrderScreen.order_items = OrderScreen.order_items.filter(orderItem => orderItem.id != row.data('order-item-id'))
row.remove()
})
const voidInstructionRow = (row: JQuery) => {
const parentRow = row.prevAll('.itemRow').first()
const parentOrderItem = OrderScreen.order_items.where('id', parentRow.data('order-item-id'))
if(!parentRow.hasClass('selected') || (parentOrderItem && parentOrderItem?.qty == 0) || !parentOrderItem)
decrementQty(OrderScreen.order_items.where('id', row.data('order-item-id')))
}
const voidItemRow = (row : JQuery) => {
const newQty = Number(row.getColumnValue(lang('qty_header'))) - 1
const orderItem = OrderScreen.order_items.where('id', row.data('order-item-id'))
const instructionRows = row.nextUntil('.itemRow')
if(newQty < 1)
voidRows(instructionRows)
decrementQty(orderItem)
}
const voidRow = (row: JQuery) => {
if(row.hasClass('itemRow')) voidItemRow(row)
else voidInstructionRow(row)
}
const voidRows = (rows: JQuery) => rows.each((index, row) => voidRow($(row)))
const voidButtonClicked = () => {
const selectedRows = $('.orderBox tr.selected')
if(isInMode('void')){
turnOffMode('void')
} else if(selectedRows.length){
voidRows(selectedRows)
} else {
turnOnMode('void')
}
}
const voidLastItem = () => {
if(OrderScreen.order_items.length < 1) return
let orderItem = OrderScreen.order_items[OrderScreen.order_items.length-1]
let row = getOrderItemRow(orderItem)
voidRows(row)
}
const decrementQty = (orderItem: orderItem) => {
const row = getOrderItemRow(orderItem)
if(orderItem.qty <= 1){
OrderScreen.order_items = OrderScreen.order_items.filter(item => item != orderItem)
deleteRow(row)
} else {
orderItem.qty--
row.setColumnValue(lang('qty_header'), orderItem.qty)
}
}
const getOrderItemRow = (orderItem: orderItem) => $('tr').filterByData('order-item-id', orderItem.id)
$(() => ajax('/orderScreen/getOrderScreenData/1', null, 'get', setupOrderScreen, null, null) )