[WIP] pos_restaurant: floor and tables in the pos
This commit is contained in:
committed by
Frédéric van der Essen
parent
52c3b52bf0
commit
fdaff3e52b
@@ -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({
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -1,6 +1,91 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- RESTAURANTS FLOORS -->
|
||||
|
||||
<record model="ir.ui.view" id="view_restaurant_floor_form">
|
||||
<field name="name">Restaurant Floors</field>
|
||||
<field name="model">restaurant.floor</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Restaurant Floor">
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="name" />
|
||||
<field name="pos_config_id" />
|
||||
</group>
|
||||
<field name="table_ids">
|
||||
<tree string='Tables'>
|
||||
<field name="name" />
|
||||
<field name="shape" />
|
||||
<field name="width" />
|
||||
<field name="height" />
|
||||
<field name="position_h" />
|
||||
<field name="position_v" />
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_restaurant_floor_tree">
|
||||
<field name="name">Restaurant Floors</field>
|
||||
<field name="model">restaurant.floor</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Restaurant Floors">
|
||||
<field name="name" />
|
||||
<field name="pos_config_id" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_restaurant_floor_form">
|
||||
<field name="name">Restaurant Floors</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">restaurant.floor</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a Restaurant Floor.
|
||||
</p><p>
|
||||
A restaurant floor represents the place where customers are served, this is where you can
|
||||
define and position the tables.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_restaurant_table_form">
|
||||
<field name="name">Restaurant Table</field>
|
||||
<field name="model">restaurant.table</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Restaurant Table">
|
||||
<group col="2">
|
||||
<field name="name" />
|
||||
<field name="shape" />
|
||||
<field name="color" />
|
||||
</group>
|
||||
<group col="4">
|
||||
<field name="position_h" />
|
||||
<field name="position_v" />
|
||||
<field name="width" />
|
||||
<field name="height" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="point_of_sale.menu_point_config_product"
|
||||
action="action_restaurant_floor_form"
|
||||
id="menu_restaurant_floor_all"
|
||||
sequence="30"
|
||||
groups="point_of_sale.group_pos_manager"/>
|
||||
|
||||
<!-- RESTAURANT PRINTERS -->
|
||||
|
||||
<record model="ir.ui.view" id="view_restaurant_printer_form">
|
||||
<field name="name">Order Printer</field>
|
||||
<field name="model">restaurant.printer</field>
|
||||
@@ -64,6 +149,7 @@
|
||||
<group string="Bar & Restaurant" >
|
||||
<field name="iface_splitbill" />
|
||||
<field name="iface_printbill" />
|
||||
<field name="floor_ids" />
|
||||
<field name="printer_ids" />
|
||||
</group>
|
||||
</sheet>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
@@ -8,4 +8,6 @@ openerp.pos_restaurant = function(instance){
|
||||
|
||||
openerp_restaurant_printbill(instance,module);
|
||||
|
||||
openerp_restaurant_floors(instance,module);
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-name="FloorScreenWidget">
|
||||
<div class='floor-screen screen'>
|
||||
<div class='screen-content-flexbox'>
|
||||
<div class='floor-selector'>
|
||||
<t t-foreach="widget.pos.floors" t-as="floor">
|
||||
<t t-if="floor.id === widget.floor.id">
|
||||
<span class='button button-floor active' t-att-data-id="floor.id"><t t-esc="floor.name" /></span>
|
||||
</t>
|
||||
<t t-if="floor.id !== widget.floor.id">
|
||||
<span class='button button-floor' t-att-data-id="floor.id"><t t-esc="floor.name" /></span>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class='floor-map'>
|
||||
<t t-foreach="widget.floor.tables" t-as="table">
|
||||
<div class='table' t-att-style='widget.table_style(table)'><t t-esc='table.name' /></div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -15,6 +15,7 @@
|
||||
<script type="text/javascript" src="/pos_restaurant/static/src/js/multiprint.js"></script>
|
||||
<script type="text/javascript" src="/pos_restaurant/static/src/js/splitbill.js"></script>
|
||||
<script type="text/javascript" src="/pos_restaurant/static/src/js/printbill.js"></script>
|
||||
<script type="text/javascript" src="/pos_restaurant/static/src/js/floors.js"></script>
|
||||
<script type="text/javascript" src="/pos_restaurant/static/src/js/main.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user