summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorFrédéric van der Essen <fvdessen@gmail.com>2015-02-01 00:41:18 +0100
committerFrédéric van der Essen <fvdessen@gmail.com>2015-02-02 16:29:32 +0100
commit3335a79e6b6de83c82c290b4591e89f8e6ca5742 (patch)
treed00539dc581cac869d8ee9eb2b5450d62c3bdf51 /addons
parent386f5f99d63e4565ab3bcf756b9d39dc136a5d52 (diff)
[IMP] point_of_sale, pos_restaurant: Table seats
Diffstat (limited to 'addons')
-rw-r--r--addons/point_of_sale/point_of_sale_view.xml2
-rw-r--r--addons/point_of_sale/static/src/css/pos.css17
-rw-r--r--addons/point_of_sale/static/src/js/popups.js2
-rw-r--r--addons/point_of_sale/static/src/xml/pos.xml27
-rw-r--r--addons/pos_restaurant/restaurant.py19
-rw-r--r--addons/pos_restaurant/restaurant_view.xml22
-rw-r--r--addons/pos_restaurant/static/src/css/restaurant.css51
-rw-r--r--addons/pos_restaurant/static/src/js/floors.js120
-rw-r--r--addons/pos_restaurant/static/src/js/multiprint.js7
-rw-r--r--addons/pos_restaurant/static/src/js/splitbill.js3
-rw-r--r--addons/pos_restaurant/static/src/xml/floors.xml19
11 files changed, 247 insertions, 42 deletions
diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml
index 2401574df33..64ddbc82fc5 100644
--- a/addons/point_of_sale/point_of_sale_view.xml
+++ b/addons/point_of_sale/point_of_sale_view.xml
@@ -22,7 +22,7 @@
<field name="state" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
</header>
<sheet>
- <group col="4" colspan="4">
+ <group col="4" colspan="4" name="order_fields">
<field name="name"/>
<field name="date_order"/>
<field name="session_id" required="1"/>
diff --git a/addons/point_of_sale/static/src/css/pos.css b/addons/point_of_sale/static/src/css/pos.css
index daf8c12e4c0..9ea9986d823 100644
--- a/addons/point_of_sale/static/src/css/pos.css
+++ b/addons/point_of_sale/static/src/css/pos.css
@@ -565,6 +565,20 @@ td {
.pos .control-button .fa{
margin-right: 4px;
}
+.pos .control-button .control-button-number {
+ color: rgb(226, 226, 226);
+ background: rgb(85, 85, 85);
+ display: inline-block;
+ height: 28px;
+ vertical-align: middle;
+ font-weight: bold;
+ line-height: 28px;
+ width: 28px;
+ border-radius: 50%;
+ text-align: center;
+ margin-left: -16px;
+ margin-right: 4px;
+}
.pos .control-button.highlight,
.pos .button.highlight {
@@ -2117,6 +2131,9 @@ td {
box-sizing: border-box;
width: 80%;
}
+.pos .popup-number .popup-input {
+ text-align: center;
+}
.pos .popup input:focus,
.pos .popup-input.active {
outline: none;
diff --git a/addons/point_of_sale/static/src/js/popups.js b/addons/point_of_sale/static/src/js/popups.js
index e0db66f5392..314dc8556c8 100644
--- a/addons/point_of_sale/static/src/js/popups.js
+++ b/addons/point_of_sale/static/src/js/popups.js
@@ -194,7 +194,7 @@ openerp.point_of_sale.load_popups = function load_popups(instance, module) {
var self = this;
this._super(options);
- this.inputbuffer = options.value || '';
+ this.inputbuffer = '' + options.value || '';
this.renderElement();
this.firstinput = true;
},
diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml
index cc094485f02..4c77b710982 100644
--- a/addons/point_of_sale/static/src/xml/pos.xml
+++ b/addons/point_of_sale/static/src/xml/pos.xml
@@ -666,6 +666,9 @@
<div>Served by <t t-esc='receipt.cashier' /></div>
</div>
</t>
+ <t t-if='!receipt.customer_count'>
+ <div>Guests: <t t-esc='receipt.customer_count' /></div>
+ </t>
</div>
<br /><br />
@@ -981,17 +984,29 @@
<button class="input-button number-char" data-action='1'>1</button>
<button class="input-button number-char" data-action='2'>2</button>
<button class="input-button number-char" data-action='3'>3</button>
- <button class="mode-button add" data-action='+10'>+10</button>
+ <t t-if="widget.options.cheap">
+ <button class="mode-button add" data-action='+1'>+1</button>
+ </t><t t-if="!widget.options.cheap">
+ <button class="mode-button add" data-action='+10'>+10</button>
+ </t>
<br />
<button class="input-button number-char" data-action='4'>4</button>
<button class="input-button number-char" data-action='5'>5</button>
<button class="input-button number-char" data-action='6'>6</button>
- <button class="mode-button add" data-action='+20'>+20</button>
+ <t t-if="widget.options.cheap">
+ <button class="mode-button add" data-action='+2'>+2</button>
+ </t><t t-if="!widget.options.cheap">
+ <button class="mode-button add" data-action='+20'>+20</button>
+ </t>
<br />
<button class="input-button number-char" data-action='7'>7</button>
<button class="input-button number-char" data-action='8'>8</button>
<button class="input-button number-char" data-action='9'>9</button>
- <button class="mode-button add" data-action='+50'>+50</button>
+ <t t-if="widget.options.cheap">
+ <button class="mode-button add" data-action='+5'>+5</button>
+ </t><t t-if="!widget.options.cheap">
+ <button class="mode-button add" data-action='+50'>+50</button>
+ </t>
<br />
<button class="input-button numpad-char" data-action='CLEAR' >C</button>
<button class="input-button number-char" data-action='0'>0</button>
@@ -1002,12 +1017,12 @@
<br />
</div>
<div class="footer">
- <div class="button confirm">
- Ok
- </div>
<div class="button cancel">
Cancel
</div>
+ <div class="button confirm">
+ Ok
+ </div>
</div>
</div>
</div>
diff --git a/addons/pos_restaurant/restaurant.py b/addons/pos_restaurant/restaurant.py
index 70583f06c16..512b1e7cdc3 100644
--- a/addons/pos_restaurant/restaurant.py
+++ b/addons/pos_restaurant/restaurant.py
@@ -53,17 +53,19 @@ class restaurant_table(osv.osv):
'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.float('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.float('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.float('Width', help="The table's width in percentage of the floor's width"),
- 'height': fields.float('Height', help="The table's height in percentage of the floor's height"),
- 'color': fields.char('Color', size=32, help="The table's color"),
+ 'position_h': fields.float('Horizontal Position', help="The table's horizontal position from the left side to the table's center, in pixels"),
+ 'position_v': fields.float('Vertical Position', help="The table's vertical position from the top to the table's center, in pixels"),
+ 'width': fields.float('Width', help="The table's width in pixels"),
+ 'height': fields.float('Height', help="The table's height in pixels"),
+ 'seats': fields.integer('Seats', help="The default number of customer served at this table."),
+ 'color': fields.char('Color', help="The table's color, expressed as a valid 'background' CSS property value"),
'active': fields.boolean('Active',help='If false, the table is deactivated and will not be available in the point of sale'),
'pos_order_ids':fields.one2many('pos.order','table_id','Pos Orders', help='The orders served at this table'),
}
_defaults = {
'shape': 'square',
+ 'seats': 1,
'position_h': 10,
'position_v': 10,
'height': 50,
@@ -121,4 +123,11 @@ class pos_order(osv.osv):
_inherit = 'pos.order'
_columns = {
'table_id': fields.many2one('restaurant.table','Table', help='The table where this order was served'),
+ 'customer_count' : fields.integer('Guests', help='The amount of customers that have been served by this order.'),
}
+
+ def _order_fields(self, cr, uid, ui_order, context=None):
+ fields = super(pos_order,self)._order_fields(cr,uid,ui_order,context)
+ fields['table_id'] = ui_order.get('table_id',0)
+ fields['customer_count'] = ui_order.get('customer_count',0)
+ return fields
diff --git a/addons/pos_restaurant/restaurant_view.xml b/addons/pos_restaurant/restaurant_view.xml
index 3094a681b48..27f323651b7 100644
--- a/addons/pos_restaurant/restaurant_view.xml
+++ b/addons/pos_restaurant/restaurant_view.xml
@@ -2,6 +2,21 @@
<openerp>
<data>
+
+ <!-- POS ORDERS -->
+
+ <record model="ir.ui.view" id="view_pos_pos_form">
+ <field name="name">pos.order.form.view.inherit</field>
+ <field name="model">pos.order</field>
+ <field name="inherit_id" ref="point_of_sale.view_pos_pos_form"></field>
+ <field name="arch" type="xml">
+ <xpath expr="//group[@name='order_fields']" position="inside">
+ <field name="table_id"/>
+ <field name="customer_count"/>
+ </xpath>
+ </field>
+ </record>
+
<!-- RESTAURANTS FLOORS -->
<record model="ir.ui.view" id="view_restaurant_floor_form">
@@ -19,6 +34,7 @@
<field name="table_ids">
<tree string='Tables'>
<field name="name" />
+ <field name="seats" />
<field name="shape" />
</tree>
</field>
@@ -62,10 +78,12 @@
<form string="Restaurant Table">
<group col="2">
<field name="name" />
+ <field name="floor_id" />
+ <field name="seats" />
+ </group>
+ <group col="4" string="Appearance">
<field name="shape" />
<field name="color" />
- </group>
- <group col="4">
<field name="position_h" />
<field name="position_v" />
<field name="width" />
diff --git a/addons/pos_restaurant/static/src/css/restaurant.css b/addons/pos_restaurant/static/src/css/restaurant.css
index 1bbac339406..57d667670d8 100644
--- a/addons/pos_restaurant/static/src/css/restaurant.css
+++ b/addons/pos_restaurant/static/src/css/restaurant.css
@@ -49,6 +49,7 @@
background-repeat: no-repeat;
overflow: hidden;
background-size: cover;
+ transition: all 300ms ease-in-out;
}
@media screen and (min-width: 1024px) {
@@ -80,11 +81,42 @@
border-radius: 3px;
cursor: pointer;
box-shadow: 0px 3px rgba(0,0,0,0.07);
+ transition: background, background-color 300ms ease-in-out;
+}
+.floor-map .table .table-cover {
+ display: block;
+ position: absolute;
+ left: 0; right: 0; bottom: 0;
+ border-radius: 0px 0px 3px 3px;
+ background: rgba(0,0,0,0.2);
+}
+.floor-map .table .table-cover.full {
+ border-radius: 3px 3px 3px 3px;
+}
+.floor-map .table .table-seats {
+ position: absolute;
+ display: inline-block;
+ bottom: 0;
+ left: 50%;
+ height: 20px;
+ width: 20px;
+ line-height: 20px;
+ font-size: 16px;
+ border-radius: 50%;
+ margin-left: -10px;
+ margin-bottom: 4px;
+ background: black;
+ color: white;
+ opacity: 0.2;
+ z-index: 3;
}
.floor-map .table .label {
display: block;
max-height: 100%;
overflow: hidden;
+ position: relative;
+ bottom: 5px;
+ z-index: 5;
}
.floor-map .table.selected {
outline: solid rgba(255,255,255,0.3);
@@ -96,7 +128,7 @@
top: 0;
right: 0;
font-size: 20px;
- margin: 4px;
+ margin: 8px;
line-height: 32px;
width: 32px;
text-align: center;
@@ -106,20 +138,20 @@
}
.floor-map .edit-button.editing.active {
background: #444;
+ border-color: transparent;
color: white;
}
.floor-map .edit-bar {
position: absolute;
top: 0;
right: 40px;
- margin: 4px;
- line-height: 32px;
+ margin: 8px;
+ line-height: 34px;
text-align: center;
border-radius: 5px;
cursor: pointer;
font-size: 20px;
- border: solid 1px rgba(0,0,0,0.2);
- background: #F0EEEE;
+ background: rgba(255,255,255,0.5);
}
.floor-map .edit-bar .edit-button {
position: relative;
@@ -127,14 +159,15 @@
display: inline-block;
cursor: pointer;
margin-right: -4px;
- border-right: solid 1px rgba(0,0,0,0.1);
+ border-right: solid 1px rgba(0,0,0,0.2);
transition: all 150ms linear;
}
.floor-map .edit-bar .edit-button.disabled {
- opacity: 0.5;
- border-right: solid 1px rgba(0,0,0,0.2);
cursor: default;
}
+.floor-map .edit-bar .edit-button.disabled > * {
+ opacity: 0.5;
+}
.floor-map .edit-bar .color-picker {
position: absolute;
left: -106px;
@@ -192,6 +225,7 @@
box-shadow: 0px 2px 3px rgba(0,0,0,0.2);
cursor: grab;
transition: all 150ms linear;
+ z-index: 100;
}
.floor-map .table.selected .table-handle:hover {
width: 20px;
@@ -217,6 +251,7 @@
line-height: 20px;
border-radius: 10px;
font-size: 16px;
+ z-index: 10;
}
.floor-map .table .order-count.notify-printing {
background: red;
diff --git a/addons/pos_restaurant/static/src/js/floors.js b/addons/pos_restaurant/static/src/js/floors.js
index 7b5e7d6f9a0..fe13ed552c9 100644
--- a/addons/pos_restaurant/static/src/js/floors.js
+++ b/addons/pos_restaurant/static/src/js/floors.js
@@ -27,7 +27,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
// them with their floor.
module.load_models({
model: 'restaurant.table',
- fields: ['name','width','height','position_h','position_v','shape','floor_id','color'],
+ fields: ['name','width','height','position_h','position_v','shape','floor_id','color','seats'],
loaded: function(self,tables){
self.tables_by_id = {};
for (var i = 0; i < tables.length; i++) {
@@ -161,8 +161,8 @@ openerp.pos_restaurant.load_floors = function(instance,module){
}
},
set_table_color: function(color){
- this.table.color = color;
- this.renderElement();
+ this.table.color = _.escape(color);
+ this.$el.css({'background': this.table.color});
},
set_table_name: function(name){
if (name) {
@@ -170,6 +170,12 @@ openerp.pos_restaurant.load_floors = function(instance,module){
this.renderElement();
}
},
+ set_table_seats: function(seats){
+ if (seats) {
+ this.table.seats = Number(seats);
+ this.renderElement();
+ }
+ },
// The table's positioning is handled via css absolute positioning,
// which is handled here.
table_style: function(){
@@ -187,7 +193,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
unit(Math.max(table.width,table.height)/2) : '3px',
};
if (table.color) {
- style['background-color'] = table.color;
+ style['background'] = table.color;
}
if (table.height >= 150 && table.width >= 150) {
style['font-size'] = '32px';
@@ -290,8 +296,10 @@ openerp.pos_restaurant.load_floors = function(instance,module){
},
renderElement: function(){
var self = this;
- this.order_count = this.pos.get_table_orders(this.table).length;
- this.notifications = this.get_notifications();
+ this.order_count = this.pos.get_table_orders(this.table).length;
+ this.customer_count = this.pos.get_customer_count(this.table);
+ this.fill = Math.min(1,Math.max(0,this.customer_count / this.table.seats));
+ this.notifications = this.get_notifications();
this._super();
this.$el.on('mouseup', function(event){ self.click_handler(event,$(this)); });
@@ -375,7 +383,7 @@ openerp.pos_restaurant.load_floors = function(instance,module){
event.stopPropagation();
event.preventDefault();
});
- this.renderElement();
+ this.$('.floor-map').css({"background-color": _.escape(background)});
},
deselect_tables: function(){
for (var i = 0; i < this.table_widgets.length; i++) {
@@ -437,6 +445,19 @@ openerp.pos_restaurant.load_floors = function(instance,module){
});
}
},
+ tool_change_seats: function(){
+ var self = this;
+ if (this.selected_table) {
+ this.gui.show_popup('number',{
+ 'title':_t('Number of Seats ?'),
+ 'cheap': true,
+ 'value': this.selected_table.table.seats,
+ 'confirm': function(value) {
+ self.selected_table.set_table_seats(value);
+ },
+ });
+ }
+ },
tool_duplicate_table: function(){
if (this.selected_table) {
var tw = this.create_table(this.selected_table.table);
@@ -448,12 +469,13 @@ openerp.pos_restaurant.load_floors = function(instance,module){
},
tool_new_table: function(){
var tw = this.create_table({
- 'position_v': 50,
- 'position_h': 50,
- 'width': 50,
- 'height': 50,
+ 'position_v': 100,
+ 'position_h': 100,
+ 'width': 75,
+ 'height': 75,
'name': 'T1',
'shape': 'square',
+ 'seats': 1,
});
this.select_table(tw);
},
@@ -562,6 +584,10 @@ openerp.pos_restaurant.load_floors = function(instance,module){
self.tool_rename_table();
});
+ this.$('.edit-button.seats').click(function(event){
+ self.tool_change_seats();
+ });
+
this.$('.edit-button.trash').click(function(event){
self.tool_trash_table();
});
@@ -573,7 +599,6 @@ openerp.pos_restaurant.load_floors = function(instance,module){
this.$('.color-picker .color').click(function(event){
self.tool_colorpicker_pick(event,$(this));
- self.tool_colorpicker_close();
event.stopPropagation();
});
@@ -624,6 +649,13 @@ openerp.pos_restaurant.load_floors = function(instance,module){
if (!this.table) {
this.table = this.pos.table;
}
+ if (!this.customer_count) {
+ if (this.table) {
+ this.customer_count = this.table.seats;
+ } else {
+ this.customer_count = 1;
+ }
+ }
this.save_to_db();
},
export_as_JSON: function() {
@@ -632,19 +664,29 @@ openerp.pos_restaurant.load_floors = function(instance,module){
json.table_id = this.table ? this.table.id : false;
json.floor = this.table ? this.table.floor.name : false;
json.floor_id = this.table ? this.table.floor.id : false;
+ json.customer_count = this.customer_count;
return json;
},
init_from_JSON: function(json) {
_super_order.init_from_JSON.apply(this,arguments);
this.table = this.pos.tables_by_id[json.table_id];
this.floor = this.table ? this.pos.floors_by_id[json.floor_id] : undefined;
+ this.customer_count = json.customer_count || 1;
},
export_for_printing: function() {
var json = _super_order.export_for_printing.apply(this,arguments);
json.table = this.table ? this.table.name : undefined;
json.floor = this.table ? this.table.floor.name : undefined;
+ json.customer_count = this.get_customer_count();
return json;
},
+ get_customer_count: function(){
+ return this.customer_count;
+ },
+ set_customer_count: function(count) {
+ this.customer_count = Math.max(count,0);
+ this.trigger('change');
+ },
});
// We need to modify the OrderSelector to hide itself when we're on
@@ -759,6 +801,16 @@ openerp.pos_restaurant.load_floors = function(instance,module){
return t_orders;
},
+ // get customer count at table
+ get_customer_count: function(table) {
+ var orders = this.get_table_orders(table);
+ var count = 0;
+ for (var i = 0; i < orders.length; i++) {
+ count += orders[i].get_customer_count();
+ }
+ return count;
+ },
+
// When we validate an order we go back to the floor plan.
// When we cancel an order and there is multiple orders
// on the table, stay on the table.
@@ -775,6 +827,50 @@ openerp.pos_restaurant.load_floors = function(instance,module){
_super_posmodel.on_removed_order.apply(this,arguments);
}
},
+
+
+ });
+
+ module.TableGuestsButton = module.ActionButtonWidget.extend({
+ template: 'TableGuestsButton',
+ guests: function() {
+ if (this.pos.get_order()) {
+ return this.pos.get_order().customer_count;
+ } else {
+ return 0;
+ }
+ },
+ button_click: function() {
+ var self = this;
+ this.gui.show_popup('number', {
+ 'title': _t('Guests ?'),
+ 'cheap': true,
+ 'value': this.pos.get_order().customer_count,
+ 'confirm': function(value) {
+ value = Math.max(1,Number(value));
+ self.pos.get_order().set_customer_count(value);
+ self.renderElement();
+ },
+ });
+ },
+ });
+
+ module.OrderWidget.include({
+ update_summary: function(){
+ this._super();
+ if (this.getParent().action_buttons &&
+ this.getParent().action_buttons.guests) {
+ this.getParent().action_buttons.guests.renderElement();
+ }
+ },
+ });
+
+ module.define_action_button({
+ 'name': 'guests',
+ 'widget': module.TableGuestsButton,
+ 'condition': function(){
+ return this.pos.config.iface_floorplan;
+ },
});
};
diff --git a/addons/pos_restaurant/static/src/js/multiprint.js b/addons/pos_restaurant/static/src/js/multiprint.js
index 61b8c1663a4..fdb458c81a2 100644
--- a/addons/pos_restaurant/static/src/js/multiprint.js
+++ b/addons/pos_restaurant/static/src/js/multiprint.js
@@ -229,13 +229,6 @@ openerp.pos_restaurant.load_multiprint = function(instance,module){
order.saveChanges();
}
},
- hilight: function(hi){
- if (hi) {
- this.$el.addClass('highlight');
- } else {
- this.$el.removeClass('highlight');
- }
- },
});
module.define_action_button({
diff --git a/addons/pos_restaurant/static/src/js/splitbill.js b/addons/pos_restaurant/static/src/js/splitbill.js
index cc640599512..f3d672ca7ac 100644
--- a/addons/pos_restaurant/static/src/js/splitbill.js
+++ b/addons/pos_restaurant/static/src/js/splitbill.js
@@ -125,6 +125,9 @@ openerp.pos_restaurant.load_splitbill = function(instance, module){
neworder.saveChanges();
}
+ neworder.set_customer_count(1);
+ order.set_customer_count(order.get_customer_count() - 1);
+
this.pos.get('orders').add(neworder);
this.pos.set('selectedOrder',neworder);
}
diff --git a/addons/pos_restaurant/static/src/xml/floors.xml b/addons/pos_restaurant/static/src/xml/floors.xml
index f401bb54f27..4406fc58749 100644
--- a/addons/pos_restaurant/static/src/xml/floors.xml
+++ b/addons/pos_restaurant/static/src/xml/floors.xml
@@ -17,15 +17,30 @@
</t>
</t>
+ <t t-name="TableGuestsButton">
+ <div class='control-button'>
+ <span class='control-button-number'>
+ <t t-esc="widget.guests()" />
+ </span>
+ Guests
+ </div>
+ </t>
+
<t t-name="TableWidget">
<t t-if='!widget.selected'>
<div class='table' t-att-style='widget.table_style_str()'>
+ <span
+ t-if="widget.table.shape !== 'round'"
+ t-att-class='"table-cover " + (widget.fill >= 1 ? "full" : "")'
+ t-att-style='"height: " + Math.ceil(widget.fill * 100) + "%;"'
+ ></span>
<t t-if='widget.order_count'>
<span t-att-class='"order-count " + (widget.notifications.printing ? "notify-printing":"")'><t t-esc='widget.order_count'/></span>
</t>
<span class='label'>
<t t-esc='widget.table.name' />
</span>
+ <span class="table-seats"><t t-esc="widget.table.seats" /></span>
</div>
</t>
<t t-if='widget.selected'>
@@ -33,6 +48,7 @@
<span class='label'>
<t t-esc='widget.table.name' />
</span>
+ <span class="table-seats"><t t-esc="widget.table.seats" /></span>
<span class='table-handle top'></span>
<span class='table-handle bottom'></span>
<span class='table-handle left'></span>
@@ -82,6 +98,9 @@
<span class='edit-button rename needs-selection'>
<i class='fa fa-font'></i>
</span>
+ <span class='edit-button seats needs-selection'>
+ <i class='fa fa-user'></i>
+ </span>
<span class='edit-button shape needs-selection'>
<span class='button-option square'><i class='fa fa-square-o'></i></span>
<span class='button-option round oe_hidden'><i class='fa fa-circle-o'></i></span>