[IMP] point_of_sale: improve multi company

Since the company is not stored anymore on the user and is in the
environement, some parts of the code that was based on the current user
company cannot work anymore.

We've adapted the code to take the company from the relevent documents
to avoid having inconsistencies through the different documents
generated in the point of sale.

TASK-ID: 1997613

closes odoo/odoo#33556

Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
This commit is contained in:
rhe
2019-06-04 07:20:19 +00:00
committed by Pierre Masereel
parent e9be0bb178
commit 2bffd65451
10 changed files with 49 additions and 42 deletions
+7 -3
View File
@@ -536,8 +536,10 @@ class PosOrder(models.Model):
def _default_pricelist(self):
return self._default_session().config_id.pricelist_id
def _default_company_id(self):
return self._default_session().config_id.company_id
name = fields.Char(string='Order Ref', required=True, readonly=True, copy=False, default='/')
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, default=lambda self: self.env.company)
date_order = fields.Datetime(string='Order Date', readonly=True, index=True, default=fields.Datetime.now)
user_id = fields.Many2one(
comodel_name='res.users', string='User',
@@ -552,6 +554,8 @@ class PosOrder(models.Model):
amount_return = fields.Float(string='Returned', digits=0, required=True, readonly=True)
lines = fields.One2many('pos.order.line', 'order_id', string='Order Lines', states={'draft': [('readonly', False)]}, readonly=True, copy=True)
statement_ids = fields.One2many('account.bank.statement.line', 'pos_statement_id', string='Payments', states={'draft': [('readonly', False)]}, readonly=True)
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True,
default=lambda self: self._default_company_id())
pricelist_id = fields.Many2one('product.pricelist', string='Pricelist', required=True, states={
'draft': [('readonly', False)]}, readonly=True, default=_default_pricelist)
partner_id = fields.Many2one('res.partner', string='Customer', change_default=True, index=True, states={'draft': [('readonly', False)], 'paid': [('readonly', False)]})
@@ -1048,7 +1052,7 @@ class PosOrderLine(models.Model):
line[2]['tax_ids'] = [(6, 0, [x.id for x in product.taxes_id])]
return line
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company)
company_id = fields.Many2one('res.company', string='Company', related="order_id.company_id", store=True)
name = fields.Char(string='Line No', required=True, copy=False)
notice = fields.Char(string='Discount Notice')
product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], required=True, change_default=True)
@@ -1059,7 +1063,7 @@ class PosOrderLine(models.Model):
price_subtotal_incl = fields.Float(string='Subtotal', digits=0,
readonly=True, required=True)
discount = fields.Float(string='Discount (%)', digits=0, default=0.0)
order_id = fields.Many2one('pos.order', string='Order Ref', ondelete='cascade')
order_id = fields.Many2one('pos.order', string='Order Ref', ondelete='cascade', required=True)
tax_ids = fields.Many2many('account.tax', string='Taxes', readonly=True)
tax_ids_after_fiscal_position = fields.Many2many('account.tax', compute='_get_tax_ids_after_fiscal_position', string='Taxes to Apply')
pack_lot_ids = fields.One2many('pos.pack.operation.lot', 'pos_order_line_id', string='Lot/serial Number')
@@ -40,6 +40,8 @@ class PosSession(models.Model):
orders_to_reconcile = session.order_ids._filtered_for_reconciliation()
orders_to_reconcile.sudo()._reconcile_payments()
company_id = fields.Many2one('res.company', related='config_id.company_id', string="Company", readonly=True)
config_id = fields.Many2one(
'pos.config', string='Point of Sale',
help="The physical point of sale you will use.",
+1 -5
View File
@@ -263,10 +263,6 @@ exports.PosModel = Backbone.Model.extend({
self.config.iface_cashdrawer ||
self.config.iface_customer_facing_display;
if (self.config.company_id[0] !== self.user.company_id[0]) {
throw new Error(_t("Error: The Point of Sale User must belong to the same company as the Point of Sale. You are probably trying to load the point of sale as an administrator in a multi-company setup, with the administrator account set to the wrong company."));
}
self.db.set_uuid(self.config.uuid);
self.set_cashier(self.get_cashier());
// We need to do it here, since only then the local storage has the correct uuid
@@ -345,7 +341,7 @@ exports.PosModel = Backbone.Model.extend({
'product_tmpl_id','tracking'],
order: _.map(['sequence','default_code','name'], function (name) { return {name: name}; }),
domain: function(self){
var domain = [['sale_ok','=',true],['available_in_pos','=',true]];
var domain = [['sale_ok','=',true],['available_in_pos','=',true],'|',['company_id','=',self.config.company_id[0]],['company_id','=',false]];
if (self.config.limit_categories && self.config.iface_available_categ_ids.length) {
domain.push(['pos_categ_id', 'in', self.config.iface_available_categ_ids]);
}
+23 -20
View File
@@ -45,7 +45,7 @@
<div id="company" class="col-12 col-lg-6 o_setting_box" groups="base.group_multi_company">
<div class="o_setting_right_pane">
<label for="company_id"/>
<div><field name="company_id"/></div>
<div><field name="company_id" readonly="1"/></div>
</div>
</div>
</div>
@@ -211,7 +211,7 @@
<div class="row mt16 o_settings_container">
<div class="col-12 col-lg-6 o_setting_box" title="Choose a specific fiscal position at the order depending on the kind of customer (tax exempt, onsite vs. takeaway, etc.).">
<div class="o_setting_left_pane">
<field name="tax_regime_selection"/>
<field name="tax_regime_selection" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]"/>
</div>
<div class="o_setting_right_pane">
<label for="tax_regime_selection" string="Fiscal Position per Order"/>
@@ -220,7 +220,7 @@
</div>
<div class="content-group" attrs="{'invisible': [('tax_regime_selection', '=', False)]}">
<div class="mt16">
<field name="fiscal_position_ids" widget="many2many_tags" options="{'no_create': True}"/>
<field name="fiscal_position_ids" widget="many2many_tags" options="{'no_create': True}" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]"/>
</div>
<div>
<button name="%(account.action_account_fiscal_position_form)d" icon="fa-arrow-right" type="action" string="Fiscal Positions" class="btn-link"/>
@@ -239,7 +239,7 @@
</div>
<div class="content-group" attrs="{'invisible': [('tax_regime', '=', False)]}">
<div class="mt16">
<field name="default_fiscal_position_id" attrs="{'required': [('tax_regime', '=', True)]}"/>
<field name="default_fiscal_position_id" attrs="{'required': [('tax_regime', '=', True)]}" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]"/>
</div>
</div>
</div>
@@ -247,19 +247,19 @@
</div>
<h2>Pricing</h2>
<div class="row mt16 o_settings_container" id="pricing">
<div class="col-xs-12 col-lg-6 o_setting_box" id="product_prices">
<div class="o_setting_right_pane">
<label for="iface_tax_included" string="Product Prices"/>
<div class="text-muted">
Product prices on receipts
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_tax_included" class="o_light_label" widget="radio"/>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="product_prices">
<div class="o_setting_right_pane">
<label for="iface_tax_included" string="Product Prices"/>
<div class="text-muted">
Product prices on receipts
</div>
<div class="content-group">
<div class="mt16">
<field name="iface_tax_included" class="o_light_label" widget="radio"/>
</div>
<a attrs="{'invisible': [('iface_tax_included', '!=', 'total')]}" href="https://www.odoo.com/documentation/user/12.0/accounting/others/taxes/tax_included.html" target="_blank" class="oe-link"><i class="fa fa-fw fa-arrow-right"/>How to manage tax-included prices</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" >
<div class="o_setting_left_pane">
@@ -289,7 +289,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"/>
<field name="available_pricelist_ids" widget="many2many_tags" domain="['|',('company_id', '=', company_id),('company_id', '=', False)]"/>
</div>
<div class="row">
<label string="Default Pricelist" for="pricelist_id" class="col-lg-3 o_light_label"/>
@@ -445,7 +445,9 @@
<div class="row mt16">
<label string="Invoice Journal" for="invoice_journal_id" class="col-lg-3 o_light_label"/>
<field name="invoice_journal_id"
attrs="{'required': [('module_account', '=', True)]}"/>
domain="[('company_id', '=', company_id)]"
attrs="{'required': [('module_account', '=', True)]}"
context="{'default_company_id': company_id}"/>
</div>
</div>
</div>
@@ -461,7 +463,7 @@
Products will be taken from the default source location of this operation type
</div>
<div class="content-group mt16">
<field name="picking_type_id" required="1"/>
<field name="picking_type_id" required="1" domain="[('company_id', '=', company_id)]"/>
</div>
</div>
</div>
@@ -477,7 +479,7 @@
<div class="content-group">
<div class="row mt16" title="Whenever you close a session, one entry is generated in the following accounting journal for all the orders not invoiced. Invoices are recorded in accounting separately.">
<label string="Sales Journal" for="journal_id" class="col-lg-3 o_light_label" widget="selection"/>
<field name="journal_id"/>
<field name="journal_id" domain="[('company_id', '=', company_id)]" context="{'default_company_id': company_id}"/>
</div>
<div class="row" groups="account.group_account_user" title="Get one journal item per product rather than one journal item per receipt line. This works for any anonymous order. If the customer is set on the order, one journal item is created for each receipt line. This option is recommended for an easy review of your journal entries when managing lots of orders.">
<label string="Group Journal Items" for="group_by" class="col-lg-3 o_light_label"/>
@@ -500,6 +502,7 @@
<tree string="Point of Sale Configuration">
<field name="name" />
<field name="picking_type_id"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</tree>
</field>
</record>
@@ -19,16 +19,16 @@
<button name="open_frontend_cb" type="object" string="Continue Selling" states="opened"
class="oe_highlight"/>
<button name="action_pos_session_closing_control" type="object" string="End of Session"
attrs="{'invisible' : ['|', ('cash_control', '=', False),('state', '!=', 'opened')]}"
attrs="{'invisible' : ['|', ('cash_control', '=', False),('state', '!=', 'opened')]}"
class="oe_highlight"/>
<button name="action_pos_session_closing_control" type="object" string="Validate Closing &amp; Post Entries"
attrs="{'invisible' : ['|', ('cash_control', '=', True),('state', '!=', 'opened')]}"
class="oe_highlight"/>
<button name="action_pos_session_validate" type="object" string="Validate Closing &amp; Post Entries" states="closing_control"
class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="opening_control,opened,closing_control,closed" nolabel="1" />
</header>
<sheet>
<field name="cash_register_id" invisible="1"/>
@@ -87,6 +87,7 @@
<group>
<field name="start_at" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
<field name="stop_at" attrs="{'invisible' : [('state', '!=', 'closed')]}"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</group>
<newline/>
@@ -147,6 +148,7 @@
<field name="config_id" />
<field name="name" />
<field name="user_id" />
<field name="company_id" groups="base.group_multi_company"/>
<field name="start_at" />
<field name="stop_at" />
<field name="state" />
+2 -2
View File
@@ -6,11 +6,10 @@ var models = require('point_of_sale.models');
models.load_models([{
model: 'res.users',
fields: ['name','groups_id'],
domain: function(self){ return [['company_id','=',self.user.company_id[0]],'|', ['groups_id','=', self.config.group_pos_manager_id[0]],['groups_id','=', self.config.group_pos_user_id[0]]]; },
domain: function(self){ return [['company_ids', 'in', self.config.company_id[0]],'|', ['groups_id','=', self.config.group_pos_manager_id[0]],['groups_id','=', self.config.group_pos_user_id[0]]]; },
loaded: function(self,users){
// we attribute a role to the user, 'cashier' or 'manager', depending
// on the group the user belongs.
self.users = users;
self.users.forEach(function(user) {
user.role = 'cashier';
user.groups_id.some(function(group_id) {
@@ -29,6 +28,7 @@ models.load_models([{
},{
model: 'hr.employee',
fields: ['name', 'id', 'barcode', 'pin', 'user_id'],
domain: function(self){ return [['company_id', '=', self.config.company_id[0]]]; },
loaded: function(self, employees) {
if (self.config.module_pos_hr) {
if (self.config.employee_ids.length > 0) {
+3 -1
View File
@@ -8,7 +8,9 @@
<xpath expr="//button[@id='btn_use_employees']" position='replace'>
<div attrs="{'invisible': [('module_pos_hr', '=', False)]}">
<span class="o_form_label oe_edit_only">Allowed Employees </span>
<field name="employee_ids" widget="many2many_tags"/>
<field name="employee_ids" widget="many2many_tags"
domain="[('company_id', '=', company_id)]"
/>
</div>
</xpath>
<xpath expr="//div[@id='pricing']" position='inside'>
+3 -6
View File
@@ -9,13 +9,10 @@ class PosConfig(models.Model):
_inherit = 'pos.config'
def _get_default_pos_team(self):
try:
team = self.env.ref('sales_team.pos_sales_team', raise_if_not_found=False)
return team if team.active else None
except AccessError:
return None
team = self.env['crm.team'].search(['|', ('company_id', '=', self.env.company.id), ('company_id', '=', False)], limit=1)
return team
crm_team_id = fields.Many2one(
'crm.team', string="Sales Team",
help="This Point of sale's sales will be related to this Sales Team.",
help="This Point of sale's sales will be related to this Sales Team.",
default=_get_default_pos_team)
+2 -2
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="pos_config_view_form_pos_sale" model="ir.ui.view">
<record id="pos_config_view_form_pos_sale" model="ir.ui.view">
<field name="name">pos.config.form.pos.sale</field>
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/>
@@ -15,7 +15,7 @@
<div class="text-muted">
Sales are reported to the following sales team
</div>
<field name="crm_team_id"/>
<field name="crm_team_id" domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]"/>
</div>
</div>
</div>
+1
View File
@@ -64,6 +64,7 @@ class PickingType(models.Model):
rate_picking_late = fields.Integer(compute='_compute_picking_count')
rate_picking_backorders = fields.Integer(compute='_compute_picking_count')
barcode = fields.Char('Barcode', copy=False)
company_id = fields.Many2one('res.company', 'Company', related='warehouse_id.company_id', store=True)
@api.one
def _compute_last_done_picking(self):