Skip to content

Commit

Permalink
[IMP] point_of_sale: IotBox instead of IP
Browse files Browse the repository at this point in the history
Instead of typing the IP address of the box, the user will have to
select an existing IoT box
+ dependency : when ticking "posbox" in pos setting, should install iot
module (on the PoS settings)
  • Loading branch information
Gert Pellin committed Sep 20, 2018
1 parent 3117afb commit c0a6613
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 88 deletions.
36 changes: 2 additions & 34 deletions addons/point_of_sale/models/pos_config.py
Expand Up @@ -85,13 +85,8 @@ def _compute_default_customer_html(self):
help="Accounting journal used to create invoices.",
default=_default_invoice_journal)
currency_id = fields.Many2one('res.currency', compute='_compute_currency', string="Currency")
iface_cashdrawer = fields.Boolean(string='Cashdrawer', help="Automatically open the cashdrawer.")
iface_payment_terminal = fields.Boolean(string='Payment Terminal', help="Enables Payment Terminal integration.")
iface_electronic_scale = fields.Boolean(string='Electronic Scale', help="Enables Electronic Scale integration.")
iface_vkeyboard = fields.Boolean(string='Virtual KeyBoard', help=u"Don’t turn this option on if you take orders on smartphones or tablets. \n Such devices already benefit from a native keyboard.")
iface_customer_facing_display = fields.Boolean(string='Customer Facing Display', help="Show checkout to customers with a remotely-connected screen.")
iface_print_via_proxy = fields.Boolean(string='Print via Proxy', help="Bypass browser printing and prints via the hardware proxy.")
iface_scan_via_proxy = fields.Boolean(string='Scan via Proxy', help="Enable barcode scanning with a remotely connected barcode scanner.")
iface_big_scrollbars = fields.Boolean('Large Scrollbars', help='For imprecise industrial touchscreens.')
iface_print_auto = fields.Boolean(string='Automatic Receipt Printing', default=False,
help='The receipt will automatically be printed at the end of each order.')
Expand All @@ -109,8 +104,6 @@ def _compute_default_customer_html(self):
cash_control = fields.Boolean(string='Cash Control', help="Check the amount of the cashbox at opening and closing.")
receipt_header = fields.Text(string='Receipt Header', help="A short text that will be inserted as a header in the printed receipt.")
receipt_footer = fields.Text(string='Receipt Footer', help="A short text that will be inserted as a footer in the printed receipt.")
proxy_ip = fields.Char(string='IP Address', size=45,
help='The hostname or ip address of the hardware proxy, Will be autodetected if left empty.')
active = fields.Boolean(default=True)
uuid = fields.Char(readonly=True, default=lambda self: str(uuid4()),
help='A globally unique identifier for this pos configuration, used to prevent conflicts in client-generated data.')
Expand Down Expand Up @@ -159,7 +152,7 @@ def _compute_default_customer_html(self):
module_pos_loyalty = fields.Boolean("Loyalty Program")
module_pos_mercury = fields.Boolean(string="Integrated Card Payments")
module_pos_reprint = fields.Boolean(string="Reprint Receipt")
is_posbox = fields.Boolean("PosBox")
module_pos_iot = fields.Boolean(string="Connect an IoT Box")
is_header_or_footer = fields.Boolean("Header & Footer")

def _compute_is_installed_account_accountant(self):
Expand Down Expand Up @@ -253,10 +246,6 @@ def _check_companies(self):
if any(self.available_pricelist_ids.mapped(lambda pl: pl.company_id.id not in (False, self.company_id.id))):
raise ValidationError(_("The selected pricelists must belong to no company or the company of the point of sale."))

@api.onchange('iface_print_via_proxy')
def _onchange_iface_print_via_proxy(self):
self.iface_print_auto = self.iface_print_via_proxy

@api.onchange('module_account')
def _onchange_module_account(self):
if self.module_account:
Expand All @@ -281,30 +270,13 @@ def _onchange_available_pricelist_ids(self):
if self.pricelist_id not in self.available_pricelist_ids:
self.pricelist_id = False

@api.onchange('iface_scan_via_proxy')
def _onchange_iface_scan_via_proxy(self):
if self.iface_scan_via_proxy:
self.barcode_scanner = True
else:
self.barcode_scanner = False

@api.onchange('barcode_scanner')
def _onchange_barcode_scanner(self):
if self.barcode_scanner:
self.barcode_nomenclature_id = self.env.user.company_id.nomenclature_id
else:
self.barcode_nomenclature_id = False

@api.onchange('is_posbox')
def _onchange_is_posbox(self):
if not self.is_posbox:
self.proxy_ip = False
self.iface_scan_via_proxy = False
self.iface_electronic_scale = False
self.iface_cashdrawer = False
self.iface_print_via_proxy = False
self.iface_customer_facing_display = False

@api.onchange('tax_regime')
def _onchange_tax_regime(self):
if not self.tax_regime:
Expand Down Expand Up @@ -339,7 +311,7 @@ def name_get(self):

@api.model
def create(self, values):
if values.get('is_posbox') and values.get('iface_customer_facing_display'):
if values.get('module_pos_iot') and values.get('iface_customer_facing_display'):
if values.get('customer_facing_display_html') and not values['customer_facing_display_html'].strip():
values['customer_facing_display_html'] = self._compute_default_customer_html()
IrSequence = self.env['ir.sequence'].sudo()
Expand All @@ -365,10 +337,6 @@ def create(self, values):
def write(self, vals):
result = super(PosConfig, self).write(vals)

config_display = self.filtered(lambda c: c.is_posbox and c.iface_customer_facing_display and not (c.customer_facing_display_html or '').strip())
if config_display:
super(PosConfig, config_display).write({'customer_facing_display_html': self._compute_default_customer_html()})

self.sudo()._set_fiscal_position()
self.sudo()._check_modules_to_install()
self.sudo()._check_groups_implied()
Expand Down
61 changes: 7 additions & 54 deletions addons/point_of_sale/views/pos_config_view.xml
Expand Up @@ -109,49 +109,16 @@
</div>
</div>
</div>
<h2>PosBox / Hardware Proxy</h2>
<h2>Hardware</h2>
<div class="row mt16 o_settings_container" id="posbox_reference">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="is_posbox"/>
<field name="module_pos_iot"/>
</div>
<div class="o_setting_right_pane">
<label for="is_posbox"/>
<div class="o_setting_right_pane" name="session_iot">
<label for="module_pos_iot"/>
<div class="text-muted">
Use an integrated hardware setup like <a href="https://www.odoo.com/documentation/user/online/point_of_sale/overview/setup.html" target="_blank">PosBox</a>
</div>
<div class="content-group" attrs="{'invisible' : [('is_posbox', '=', False)]}">
<div class="row mt16">
<label string="IP Address" for="proxy_ip" class="col-lg-3 o_light_label"/>
<field name="proxy_ip"/>
</div>
<div class="row">
<label string="Barcode Scanner" for="iface_scan_via_proxy" class="col-lg-3 o_light_label"/>
<field name="iface_scan_via_proxy"/>
</div>
<div class="row">
<label string="Electronic Scale" for="iface_electronic_scale" class="col-lg-3 o_light_label"/>
<field name="iface_electronic_scale"/>
</div>
<div class="row">
<label string="Cashdrawer" for="iface_cashdrawer" class="col-lg-3 o_light_label"/>
<field name="iface_cashdrawer"/>
</div>
<div class="row">
<label string="Receipt Printer" for="iface_print_via_proxy" class="col-lg-3 o_light_label"/>
<field name="iface_print_via_proxy"/>
</div>
<div class="row">
<label string="Customer Display" for="iface_customer_facing_display" class="col-lg-3 o_light_label"/>
<field name="iface_customer_facing_display"/>
</div>
<field name="customer_facing_display_html" invisible="1"/>
<div class="text-muted" attrs="{'invisible' : ['|', ('iface_customer_facing_display', '=', False), '&amp;', ('id', '!=', False), ('customer_facing_display_html', '!=', '')]}">Save this configuration to see and edit the customer display</div>
<div class="row mt16 o_settings_container" attrs="{'invisible' : ['|', '|',('iface_customer_facing_display', '=', False), ('id', '=', False), ('customer_facing_display_html', '=', '')]}">
<div class="col-12 col-lg-6 o_setting_box">
<field name="customer_facing_display_html" widget="html_frame" nolabel="1" options="{'editor_url': '/point_of_sale/field/customer_facing_display_template'}"/>
</div>
</div>
Connect to an IoT Box to use hardware for the PoS
</div>
</div>
</div>
Expand Down Expand Up @@ -384,28 +351,14 @@
<div class="text-muted">
Print receipts automatically once the payment is registered
</div>
<div class="content-group mt16" attrs="{'invisible' : ['|', ('iface_print_auto', '=', False), ('is_posbox', '=', False)]}">
<div class="content-group mt16" attrs="{'invisible' : ['|', ('iface_print_auto', '=', False), ('module_pos_iot', '=', False)]}">
<div>
<field name="iface_print_skip_screen" class="oe_inline"/><span class="oe_inline"><b>Skip Preview Screen</b></span>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" attrs="{'invisible': [('iface_print_via_proxy','=',False)]}">
<div class="o_setting_left_pane">
<field name='module_pos_reprint'/>
</div>
<div class="o_setting_right_pane">
<label for="module_pos_reprint"/>
<div class="text-muted">
Allow cashier to reprint receipts
</div>
<div class="content-group" attrs="{'invisible': [('module_pos_reprint', '=', False)]}">
<div class="mt16" id="btn_use_pos_reprint">
<button string="Save" type="object" name="execute" class="oe_highlight"/>
</div>
</div>
</div>
<div name="session_reprint" class="col-12 col-lg-6 o_setting_box" invisible="1">
</div>
<div class="col-12 col-lg-6 o_setting_box" id="iface_invoicing">
<div class="o_setting_left_pane">
Expand Down
3 changes: 3 additions & 0 deletions addons/pos_iot/__init__.py
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import models
16 changes: 16 additions & 0 deletions addons/pos_iot/__manifest__.py
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

{
'name': "Point of Sale IoTBox integration",
'summary': """Point of Sale IoTBox integration""",
'description': """""",
'category': 'Point of Sale',
'version': '1.0.1',
'depends': ['iot', 'point_of_sale'],
'data': [
'views/pos_config_view.xml',
],
'installable': True,
'application': False,
}
3 changes: 3 additions & 0 deletions addons/pos_iot/models/__init__.py
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import pos_config
47 changes: 47 additions & 0 deletions addons/pos_iot/models/pos_config.py
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models


class PosConfig(models.Model):
_inherit='pos.config'

iface_cashdrawer = fields.Boolean(string='Cashdrawer', help="Automatically open the cashdrawer.", default=False)
iface_electronic_scale = fields.Boolean(string='Electronic Scale', help="Enables Electronic Scale integration.", default=False)
iface_customer_facing_display = fields.Boolean(string='Customer Facing Display', help="Show checkout to customers with a remotely-connected screen.", default=False)
iface_print_via_proxy = fields.Boolean(string='Print via Proxy', help="Bypass browser printing and prints via the hardware proxy.", default=False)
iface_scan_via_proxy = fields.Boolean(string='Scan via Proxy', help="Enable barcode scanning with a remotely connected barcode scanner.", default=False)

iot_box_id = fields.Many2one('iot.box', string="IoTBox")
proxy_ip = fields.Char(string='IP Address', related="iot_box_id.ip")

@api.onchange('iface_print_via_proxy')
def _onchange_iface_print_via_proxy(self):
self.iface_print_auto = self.iface_print_via_proxy

@api.onchange('iface_scan_via_proxy')
def _onchange_iface_scan_via_proxy(self):
if self.iface_scan_via_proxy:
self.barcode_scanner = True
else:
self.barcode_scanner = False

@api.onchange('module_pos_iot')
def _onchange_module_pos_iot(self):
if not self.module_pos_iot:
self.iot_box_id = False
self.proxy_ip=''
self.iface_scan_via_proxy = False
self.iface_electronic_scale = False
self.iface_cashdrawer = False
self.iface_print_via_proxy = False
self.iface_customer_facing_display = False

@api.multi
def write(self, vals):
config_display = self.filtered(lambda c: c.module_pos_iot and c.iface_customer_facing_display and not (c.customer_facing_display_html or '').strip())
if config_display:
super(PosConfig, config_display).write({'customer_facing_display_html': self._compute_default_customer_html()})

return super(PosConfig, self).write(vals)
66 changes: 66 additions & 0 deletions addons/pos_iot/views/pos_config_view.xml
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="pos_iot_config_view_form" model="ir.ui.view">
<field name="name">pos.iot.config.form.view</field>
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='session_iot']" position="replace">
<div class="o_setting_right_pane" name="session_iot">
<label for="module_pos_iot"/>
<div class="text-muted">
Connect to an IoT Box to use hardware for the PoS
</div>
<div class="content-grou" attrs="{'invisible' : [('module_pos_iot', '=', False)]}">
<field name="iot_box_id"/>
<div class="row">
<label string="Barcode Scanner" for="iface_scan_via_proxy" class="col-lg-3 o_light_label"/>
<field name="iface_scan_via_proxy"/>
</div>
<div class="row">
<label string="Electronic Scale" for="iface_electronic_scale" class="col-lg-3 o_light_label"/>
<field name="iface_electronic_scale"/>
</div>
<div class="row">
<label string="Cashdrawer" for="iface_cashdrawer" class="col-lg-3 o_light_label"/>
<field name="iface_cashdrawer"/>
</div>
<div class="row">
<label string="Receipt Printer" for="iface_print_via_proxy" class="col-lg-3 o_light_label"/>
<field name="iface_print_via_proxy"/>
</div>
<div class="row">
<label string="Customer Display" for="iface_customer_facing_display" class="col-lg-3 o_light_label"/>
<field name="iface_customer_facing_display"/>
</div>
<field name="customer_facing_display_html" invisible="1"/>
<div class="text-muted" attrs="{'invisible' : ['|', ('iface_customer_facing_display', '=', False), '&amp;', ('id', '!=', False), ('customer_facing_display_html', '!=', '')]}">Save this configuration to see and edit the customer display</div>
<div class="row mt16 o_settings_container" attrs="{'invisible' : ['|', '|',('iface_customer_facing_display', '=', False), ('id', '=', False), ('customer_facing_display_html', '=', '')]}">
<div class="col-12 col-lg-6 o_setting_box">
<field name="customer_facing_display_html" widget="html_frame" nolabel="1" options="{'editor_url': '/point_of_sale/field/customer_facing_display_template'}"/>
</div>
</div>
</div>
</div>
</xpath>
<xpath expr="//div[@name='session_reprint']" position="replace">
<div name="session_reprint" class="col-12 col-lg-6 o_setting_box" attrs="{'invisible': [('iface_print_via_proxy','=',False)]}">
<div class="o_setting_left_pane">
<field name='module_pos_reprint'/>
</div>
<div class="o_setting_right_pane">
<label for="module_pos_reprint"/>
<div class="text-muted">
Allow cashier to reprint receipts
</div>
<div class="content-group" attrs="{'invisible': [('module_pos_reprint', '=', False)]}">
<div class="mt16" id="btn_use_pos_reprint">
<button string="Save" type="object" name="execute" class="oe_highlight"/>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

0 comments on commit c0a6613

Please sign in to comment.