[IMP]point_of_sale: Allow to modify pos config

Before, when a session was open, we couldn't change any of the options in the pos config.
Now, we're able to change most of the options except those which would lead to incorrect behavior.

closes odoo/odoo#40500

Task-id: 2086823
Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
This commit is contained in:
Robin Heinz
2020-04-06 12:08:35 +00:00
committed by Pierre Masereel
parent 04dce1445a
commit 9a0a793026
6 changed files with 54 additions and 14 deletions
+7 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
from odoo.exceptions import ValidationError, UserError
class PosCategory(models.Model):
@@ -28,3 +28,9 @@ class PosCategory(models.Model):
cat = cat.parent_id
return res
return [(cat.id, " / ".join(reversed(get_names(cat)))) for cat in self]
def unlink(self):
if self.search_count([('id', 'in', self.ids)]):
if self.env['pos.session'].sudo().search_count([('state', '!=', 'closed')]):
raise UserError(_('You cannot delete a point of sale category while a session is still opened.'))
return super(PosCategory, self).unlink()
+16 -1
View File
@@ -217,6 +217,7 @@ class PosConfig(models.Model):
rounding_method = fields.Many2one('account.cash.rounding', string="Cash rounding")
cash_rounding = fields.Boolean(string="Cash Rounding")
only_round_cash_method = fields.Boolean(string="Only apply rounding on cash")
has_active_session = fields.Boolean(compute='_compute_current_session')
@api.depends('use_pricelist', 'available_pricelist_ids')
def _compute_allowed_pricelist_ids(self):
@@ -252,8 +253,10 @@ class PosConfig(models.Model):
"""If there is an open session, store it to current_session_id / current_session_State.
"""
for pos_config in self:
opened_sessions = pos_config.session_ids.filtered(lambda s: not s.state == 'closed')
session = pos_config.session_ids.filtered(lambda s: not s.state == 'closed' and not s.rescue)
# sessions ordered by id desc
pos_config.has_active_session = opened_sessions and True or False
pos_config.current_session_id = session and session[0].id or False
pos_config.current_session_state = session and session[0].state or False
@@ -462,7 +465,13 @@ class PosConfig(models.Model):
def write(self, vals):
opened_session = self.mapped('session_ids').filtered(lambda s: s.state != 'closed')
if opened_session:
raise UserError(_('Unable to modify this PoS Configuration because there is an open PoS Session based on it.'))
str = []
for key in self._get_forbidden_change_fields():
if key in vals.keys():
str.append(key)
if len(str) > 0:
raise UserError(
_("Unable to modify this PoS Configuration because you can't modify " + ", ".join(str)) + " while a session is open.")
result = super(PosConfig, self).write(vals)
self.sudo()._set_fiscal_position()
@@ -470,6 +479,12 @@ class PosConfig(models.Model):
self.sudo()._check_groups_implied()
return result
def _get_forbidden_change_fields(self):
forbidden_keys = ['module_pos_hr', 'cash_control', 'module_pos_restaurant', 'available_pricelist_ids',
'limit_categories', 'iface_available_categ_ids', 'use_pricelist', 'module_pos_discount',
'payment_method_ids', 'iface_tipproduc']
return forbidden_keys
def unlink(self):
# Delete the pos.config records first then delete the sequences linked to them
sequences_to_delete = self.sequence_id | self.sequence_line_id
+14 -10
View File
@@ -36,10 +36,14 @@
<field name="is_installed_account_accountant" invisible="1"/>
<field name="company_has_template" invisible="1"/>
<field name="allowed_pricelist_ids" invisible="1"/>
<field name="has_active_session" invisible="1"/>
<div class="oe_title" id="title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
</div>
<div class="o_notification_alert alert alert-warning" attrs="{'invisible':[('has_active_session','=', False)]}" role="alert">
A session is currently opened for this PoS. Some settings can only be changed after the session is closed.
</div>
<div class="row mt16 o_settings_container">
<div id="company" class="col-12 col-lg-6 o_setting_box" groups="base.group_multi_company">
<div class="o_setting_right_pane">
@@ -54,7 +58,7 @@
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="module_pos_restaurant"/>
<field name="module_pos_restaurant" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="module_pos_restaurant"/>
@@ -64,7 +68,7 @@
<div class="col-12 col-lg-6 o_setting_box"
title="Employees can scan their badge or enter a PIN to log in to a PoS session. These credentials are configurable in the *HR Settings* tab of the employee form.">
<div class="o_setting_left_pane">
<field name="module_pos_hr"/>
<field name="module_pos_hr" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane" id="login_with_employees">
<span class="o_form_label">Login with Employees</span>
@@ -93,7 +97,7 @@
</div>
<div class="col-12 col-lg-6 o_setting_box" >
<div class="o_setting_left_pane">
<field name="limit_categories"/>
<field name="limit_categories" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="limit_categories"/>
@@ -101,7 +105,7 @@
Available Product Categories
</div>
<div class="content-group mt16" attrs="{'invisible': [('limit_categories', '=', False)]}">
<field name="iface_available_categ_ids" widget="many2many_tags"/>
<field name="iface_available_categ_ids" widget="many2many_tags" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="content-group mt16" attrs="{'invisible': [('limit_categories', '=', False)]}">
<button name="%(product_pos_category_action)d" icon="fa-arrow-right" type="action" string="PoS Product Categories" class="btn-link"/>
@@ -264,7 +268,7 @@
</div>
<div class="col-12 col-lg-6 o_setting_box" id="pricelist_setting" groups="product.group_product_pricelist">
<div class="o_setting_left_pane">
<field name="use_pricelist"/>
<field name="use_pricelist" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="use_pricelist" string="Advanced Pricelists"/>
@@ -274,7 +278,7 @@
<div class="content-group mt16" attrs="{'invisible': [('use_pricelist','=',False)], 'required' : [('use_pricelist', '=', True)]}">
<div class="row mt16">
<label string="Available Pricelists" for="available_pricelist_ids" class="col-lg-3 o_light_label"/>
<field name="available_pricelist_ids" widget="many2many_tags" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]"/>
<field name="available_pricelist_ids" widget="many2many_tags" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
</div>
</div>
@@ -295,7 +299,7 @@
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" >
<div class="o_setting_left_pane">
<field name="module_pos_discount"/>
<field name="module_pos_discount" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="module_pos_discount"/>
@@ -335,7 +339,7 @@
Payment methods available
</div>
<div class="content-group mt16">
<field name="payment_method_ids" colspan="4" nolabel="1" widget="many2many_tags" required="1"/>
<field name="payment_method_ids" colspan="4" nolabel="1" widget="many2many_tags" required="1" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div>
<button name="%(action_payment_methods_tree)d" icon="fa-arrow-right" type="action" string="Payment Methods" class="btn-link"/>
@@ -361,7 +365,7 @@
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="cash_control"/>
<field name="cash_control" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="cash_control"/>
@@ -395,7 +399,7 @@
id="iface_tipproduct"
title="This product is used as reference on customer receipts.">
<div class="o_setting_left_pane">
<field name="iface_tipproduct"/>
<field name="iface_tipproduct" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="iface_tipproduct" string="Tips"/>
@@ -48,3 +48,9 @@ class PosConfig(models.Model):
for table in tables:
result.append({'id': table.id, 'orders': orders_map.get(table.id, 0)})
return result
def _get_forbidden_change_fields(self):
forbidden_keys = super(PosConfig, self)._get_forbidden_change_fields()
forbidden_keys.append('is_table_management')
forbidden_keys.append('floor_ids')
return forbidden_keys
@@ -66,6 +66,15 @@ class RestaurantTable(models.Model):
table_id = self.create(table).id
return table_id
def unlink(self):
confs = self.mapped('floor_id').mapped('pos_config_id').filtered(lambda c: c.is_table_management == True)
opened_session = self.env['pos.session'].search([('config_id', 'in', confs.ids), ('state', '!=', 'closed')])
if opened_session:
error_msg = _("You cannot remove a table that is used in a PoS session, close the session(s) first.")
if confs:
raise UserError(error_msg)
return super(RestaurantTable, self).unlink()
class RestaurantPrinter(models.Model):
@@ -67,7 +67,7 @@
id="is_table_management"
attrs="{'invisible': [('module_pos_restaurant', '=', False)]}">
<div class="o_setting_left_pane">
<field name="is_table_management"/>
<field name="is_table_management" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div class="o_setting_right_pane">
<label for="is_table_management"/>
@@ -78,7 +78,7 @@
<div class="content-group" attrs="{'invisible': [('is_table_management','=',False)]}">
<div class="mt16">
<label string="Floors" for="floor_ids" class="o_light_label"/>
<field name="floor_ids" widget="many2many_tags"/>
<field name="floor_ids" widget="many2many_tags" attrs="{'readonly': [('has_active_session','=', True)]}"/>
</div>
<div>
<button name="%(pos_restaurant.action_restaurant_floor_form)d" icon="fa-arrow-right" type="action" string="Floors" class="btn-link"/>