From fdaff3e52bc82792e0956741e09b57412cc0de5c Mon Sep 17 00:00:00 2001 From: Frederic van der Essen Date: Mon, 8 Sep 2014 11:35:03 +0200 Subject: [PATCH] [WIP] pos_restaurant: floor and tables in the pos --- addons/point_of_sale/static/src/js/screens.js | 3 + addons/pos_restaurant/__openerp__.py | 1 + addons/pos_restaurant/restaurant.py | 28 ++++++ addons/pos_restaurant/restaurant_view.xml | 86 +++++++++++++++++++ .../static/src/css/restaurant.css | 54 ++++++++++++ addons/pos_restaurant/static/src/js/floors.js | 86 +++++++++++++++++++ addons/pos_restaurant/static/src/js/main.js | 2 + .../pos_restaurant/static/src/xml/floors.xml | 25 ++++++ addons/pos_restaurant/views/templates.xml | 1 + 9 files changed, 286 insertions(+) create mode 100644 addons/pos_restaurant/static/src/js/floors.js create mode 100644 addons/pos_restaurant/static/src/xml/floors.xml diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index f92fb50127a..56f538a4cd6 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -134,6 +134,9 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa set_default_screen: function(){ this.set_current_screen(this.default_screen); }, + change_default_screen: function(screen){ + this.default_screen = screen; + }, }); module.ScreenWidget = module.PosBaseWidget.extend({ diff --git a/addons/pos_restaurant/__openerp__.py b/addons/pos_restaurant/__openerp__.py index edb5b0b64de..119efa45bbb 100644 --- a/addons/pos_restaurant/__openerp__.py +++ b/addons/pos_restaurant/__openerp__.py @@ -48,6 +48,7 @@ This module adds several restaurant features to the Point of Sale: 'static/src/xml/multiprint.xml', 'static/src/xml/splitbill.xml', 'static/src/xml/printbill.xml', + 'static/src/xml/floors.xml', ], 'installable': True, 'auto_install': False, diff --git a/addons/pos_restaurant/restaurant.py b/addons/pos_restaurant/restaurant.py index c7d02a336c1..69a1e3f4137 100644 --- a/addons/pos_restaurant/restaurant.py +++ b/addons/pos_restaurant/restaurant.py @@ -28,6 +28,33 @@ from openerp.tools.translate import _ _logger = logging.getLogger(__name__) +class restaurant_floor(osv.osv): + _name = 'restaurant.floor' + _columns = { + 'name': fields.char('Floor Name', size=32, required=True, help='An internal identification of the restaurant floor'), + 'pos_config_id': fields.many2one('pos.config','Point of Sale'), + 'background_image': fields.binary('Background Image', help='A background image used to display a floor layout in the point of sale interface'), + 'table_ids': fields.one2many('restaurant.table','floor_id','Tables', help='The list of tables in this floor'), + } + +class restaurant_table(osv.osv): + _name = 'restaurant.table' + _columns = { + 'name': fields.char('Table Name', size=32, required=True, help='An internal identification of a table'), + 'floor_id': fields.many2one('restaurant.floor','Floor'), + 'shape': fields.selection([('square','Square'),('round','Round')],'Shape', required=True), + 'position_h': fields.integer('Horizontal Position', help="The table's horizontal position from the left side to the table's center, in percentage of the floor's width"), + 'position_v': fields.integer('Vertical Position', help="The table's vertical position from the top to the table's center, in percentage of the floor's height"), + 'width': fields.integer('Width', help="The table's width in percentage of the floor's width"), + 'height': fields.integer('Height', help="The table's height in percentage of the floor's height"), + 'color': fields.char('Color', size=32, help="The table's color"), + } + _defaults = { + 'shape': 'square', + 'height': 10, + 'width': 10, + } + class restaurant_printer(osv.osv): _name = 'restaurant.printer' @@ -46,6 +73,7 @@ class pos_config(osv.osv): _columns = { 'iface_splitbill': fields.boolean('Bill Splitting', help='Enables Bill Splitting in the Point of Sale'), 'iface_printbill': fields.boolean('Bill Printing', help='Allows to print the Bill before payment'), + 'floor_ids': fields.one2many('restaurant.floor','pos_config_id','Restaurant Floors', help='The restaurant floors served by this point of sale'), 'printer_ids': fields.many2many('restaurant.printer','pos_config_printer_rel', 'config_id','printer_id',string='Order Printers'), } _defaults = { diff --git a/addons/pos_restaurant/restaurant_view.xml b/addons/pos_restaurant/restaurant_view.xml index 84adc883b94..27d5e2cbd99 100644 --- a/addons/pos_restaurant/restaurant_view.xml +++ b/addons/pos_restaurant/restaurant_view.xml @@ -1,6 +1,91 @@ + + + + + Restaurant Floors + restaurant.floor + +
+ + + + + + + + + + + + + + + + + +
+
+
+ + + Restaurant Floors + restaurant.floor + + + + + + + + + + Restaurant Floors + ir.actions.act_window + restaurant.floor + form + tree,form + +

+ Click to add a Restaurant Floor. +

+ A restaurant floor represents the place where customers are served, this is where you can + define and position the tables. +

+
+
+ + + Restaurant Table + restaurant.table + +
+ + + + + + + + + + + +
+
+
+ + + + + Order Printer restaurant.printer @@ -64,6 +149,7 @@ + diff --git a/addons/pos_restaurant/static/src/css/restaurant.css b/addons/pos_restaurant/static/src/css/restaurant.css index 0ffebfc0a46..de1afd0b398 100644 --- a/addons/pos_restaurant/static/src/css/restaurant.css +++ b/addons/pos_restaurant/static/src/css/restaurant.css @@ -1,2 +1,56 @@ /* --- Restaurant Specific CSS --- */ +.screen .screen-content-flexbox { + margin: 0px auto; + max-width: 1024px; + text-align: left; + height: 100%; + overflow: hidden; + position: relative; + display: flex; + flex-flow: column nowrap; +} + +/* ------ FLOOR SELECTOR ------- */ + +.floor-selector { + line-height: 48px; + font-size: 18px; + border-bottom: solid 1px rgb(196,196,196); + display: flex; + text-align: center; + width: 100%; +} +.floor-selector .button { + cursor: pointer; + border-left: dashed 1px rgb(196,196,196); + flex: 1; +} +.floor-selector .button:first-child { + border-left: none; +} +.floor-selector .button.active { + background: rgb(210, 231, 210); +} + +/* ------ FLOOR MAP ------- */ + +.floor-map { + flex: 1; + position: relative; + width: auto; + margin: 8px; + border-radius: 3px; + background: rgba(0,0,0,0.1); +} +.floor-map .table{ + position: absolute; + text-align: center; + font-size: 18px; + color: white; + background: rgb(53, 211, 116); + border-radius: 3px; + cursor: pointer; +} + + diff --git a/addons/pos_restaurant/static/src/js/floors.js b/addons/pos_restaurant/static/src/js/floors.js new file mode 100644 index 00000000000..a097cd03823 --- /dev/null +++ b/addons/pos_restaurant/static/src/js/floors.js @@ -0,0 +1,86 @@ +function openerp_restaurant_floors(instance,module){ + + module.PosModel.prototype.models.push({ + model: 'restaurant.floor', + fields: ['name','background_image','table_ids'], + domain: function(self){ return [['pos_config_id','=',self.config.id]] }, + loaded: function(self,floors){ + self.floors = floors; + self.floors_by_id = {}; + for (var i = 0; i < floors.length; i++) { + floors[i].tables = []; + self.floors_by_id[floors[i].id] = floors[i]; + } + }, + }); + + module.PosModel.prototype.models.push({ + model: 'restaurant.table', + fields: ['name','width','height','position_h','position_v','shape','floor_id','color'], + loaded: function(self,tables){ + for (var i = 0; i < tables.length; i++) { + var floor = self.floors_by_id[tables[i].floor_id[0]]; + if (floor) { + floor.tables.push(tables[i]); + } + } + }, + }); + + module.FloorScreenWidget = module.ScreenWidget.extend({ + template: 'FloorScreenWidget', + show_leftpane: false, + + init: function(parent, options) { + this._super(parent, options); + this.floor = this.pos.floors[0]; + }, + click_floor_button: function(event,$el){ + var floor = this.pos.floors_by_id[$el.data('id')]; + if (floor !== this.floor) { + this.floor = floor; + this.renderElement(); + } + }, + table_style: function(table){ + function unit(val){ return Math.floor(val * 10) + 'px'; } + var str = ""; + var style = { + 'width': unit(table.width), + 'height': unit(table.height), + 'line-height': unit(table.height), + 'margin-left': unit(-table.width/2), + 'margin-top': unit(-table.height/2), + 'top': unit(table.position_v + table.height/2), + 'left': unit(table.position_h + table.width/2), + 'border-radius': table.shape === 'round' ? + unit(Math.max(table.width,table.height)/2) : '3px', + }; + for (s in style) { + str += s + ":" + style[s] + "; "; + } + return str; + }, + renderElement: function(){ + var self = this; + this._super(); + this.$('.floor-selector .button').click(function(event){ + self.click_floor_button(event,$(this)); + }); + }, + }); + + module.PosWidget.include({ + build_widgets: function(){ + var self = this; + this._super(); + if (this.pos.floors.length > 0) { + this.floors_screen = new module.FloorScreenWidget(this,{}); + this.floors_screen.appendTo(this.$('.screens')); + this.screen_selector.add_screen('floors',this.floors_screen); + this.screen_selector.change_default_screen('floors'); + } + }, + }); + +} diff --git a/addons/pos_restaurant/static/src/js/main.js b/addons/pos_restaurant/static/src/js/main.js index 606eef836a8..6967ba9e95c 100644 --- a/addons/pos_restaurant/static/src/js/main.js +++ b/addons/pos_restaurant/static/src/js/main.js @@ -8,4 +8,6 @@ openerp.pos_restaurant = function(instance){ openerp_restaurant_printbill(instance,module); + openerp_restaurant_floors(instance,module); + }; diff --git a/addons/pos_restaurant/static/src/xml/floors.xml b/addons/pos_restaurant/static/src/xml/floors.xml new file mode 100644 index 00000000000..0126d9ff653 --- /dev/null +++ b/addons/pos_restaurant/static/src/xml/floors.xml @@ -0,0 +1,25 @@ + + + + +
+
+
+ + + + + + + + +
+
+ +
+
+
+
+
+
+
diff --git a/addons/pos_restaurant/views/templates.xml b/addons/pos_restaurant/views/templates.xml index 10c269be86f..bd2610c8279 100644 --- a/addons/pos_restaurant/views/templates.xml +++ b/addons/pos_restaurant/views/templates.xml @@ -15,6 +15,7 @@ +