[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:
@@ -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.",
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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 & Post Entries"
|
||||
attrs="{'invisible' : ['|', ('cash_control', '=', True),('state', '!=', 'opened')]}"
|
||||
class="oe_highlight"/>
|
||||
<button name="action_pos_session_validate" type="object" string="Validate Closing & 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" />
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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'>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user