[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:
committed by
Pierre Masereel
parent
04dce1445a
commit
9a0a793026
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user