From 299416637cef61b3accdaa7a36c6368ade4e4e54 Mon Sep 17 00:00:00 2001 From: Pierre Masereel Date: Fri, 5 Jul 2019 13:06:40 +0000 Subject: [PATCH] [IMP] point_of_sale: set values depending on session Before, when a pos order was created, some of its values were were completed through the default mechanism that was looking for a session opened by the current user, which could lead to wrong values when with recovery session. Since in near future we'll allow one user to open multiple sessions, this behavior won't work anymore, as you could get the config od another session than the one you are working on. We also removed the '_default_session' on field session_id, as the method 'create_from_ui' which creates the orders from the frontend allways set the session_id when it creates a new order. TASK-ID: 2032769 --- addons/point_of_sale/models/pos_order.py | 35 +++++++------------ .../tests/test_point_of_sale_flow.py | 18 ++++++++++ addons/pos_sale/models/pos_order.py | 11 +++--- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 19fee6af361..461ead55610 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -482,15 +482,6 @@ class PosOrder(models.Model): return self.filtered(lambda order: order.state in filter_states and order.partner_id) return self.filtered(lambda order: order.state in filter_states) - def _default_session(self): - return self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1) - - 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='/') date_order = fields.Datetime(string='Order Date', readonly=True, index=True, default=fields.Datetime.now) user_id = fields.Many2one( @@ -506,17 +497,16 @@ 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()) + company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True) pricelist_id = fields.Many2one('product.pricelist', string='Pricelist', required=True, states={ - 'draft': [('readonly', False)]}, readonly=True, default=_default_pricelist) + 'draft': [('readonly', False)]}, readonly=True) partner_id = fields.Many2one('res.partner', string='Customer', change_default=True, index=True, states={'draft': [('readonly', False)], 'paid': [('readonly', False)]}) sequence_number = fields.Integer(string='Sequence Number', help='A session-unique sequence number for the order', default=1) session_id = fields.Many2one( 'pos.session', string='Session', required=True, index=True, domain="[('state', '=', 'opened')]", states={'draft': [('readonly', False)]}, - readonly=True, default=_default_session) + readonly=True) config_id = fields.Many2one('pos.config', related='session_id.config_id', string="Point of Sale", readonly=False) currency_id = fields.Many2one('res.currency', related='config_id.currency_id', string="Currency") currency_rate = fields.Float("Currency Rate", compute='_compute_currency_rate', compute_sudo=True, store=True, readonly=True, help='The rate of the currency to the currency of rate 1 applicable at the date of the order') @@ -541,7 +531,6 @@ class PosOrder(models.Model): sale_journal = fields.Many2one('account.journal', related='session_id.config_id.journal_id', string='Sales Journal', store=True, readonly=True) fiscal_position_id = fields.Many2one( comodel_name='account.fiscal.position', string='Fiscal Position', - default=lambda self: self._default_session().config_id.default_fiscal_position_id, readonly=True, states={'draft': [('readonly', False)]}, ) @@ -615,16 +604,18 @@ class PosOrder(models.Model): @api.model def create(self, values): - if values.get('session_id'): - # set name based on the sequence specified on the config - session = self.env['pos.session'].browse(values['session_id']) - values['name'] = session.config_id.sequence_id._next() - values.setdefault('pricelist_id', session.config_id.pricelist_id.id) - else: - # fallback on any pos.order sequence - values['name'] = self.env['ir.sequence'].next_by_code('pos.order') + session = self.env['pos.session'].browse(values['session_id']) + values = self._complete_values_from_session(session, values) return super(PosOrder, self).create(values) + @api.model + def _complete_values_from_session(self, session, values): + values['name'] = session.config_id.sequence_id._next() + values.setdefault('pricelist_id', session.config_id.pricelist_id.id) + values.setdefault('fiscal_position_id', session.config_id.default_fiscal_position_id.id) + values.setdefault('company_id', session.config_id.company_id.id) + return values + @api.multi def action_view_invoice(self): return { diff --git a/addons/point_of_sale/tests/test_point_of_sale_flow.py b/addons/point_of_sale/tests/test_point_of_sale_flow.py index a3406706a36..ca0d12f330d 100644 --- a/addons/point_of_sale/tests/test_point_of_sale_flow.py +++ b/addons/point_of_sale/tests/test_point_of_sale_flow.py @@ -18,9 +18,12 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): self.env['pos.open.statement'].create({}).open_statement() def test_order_refund(self): + self.pos_config.open_session_cb() + current_session = self.pos_config.current_session_id # I create a new PoS order with 2 lines order = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'partner_id': self.partner1.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'lines': [(0, 0, { @@ -84,6 +87,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): # I click on create a new session button self.pos_config.open_session_cb() + current_session = self.pos_config.current_session_id # I create a PoS order with 2 units of PCSC234 at 450 EUR # and 3 units of PCSC349 at 300 EUR. @@ -91,6 +95,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): untax2, atax2 = compute_tax(self.product4, 300, 3) self.pos_order_pos1 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'partner_id': self.partner1.id, 'lines': [(0, 0, { @@ -155,6 +160,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): untax2, atax2 = compute_tax(self.product4, 300, -3) self.pos_order_pos2 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'partner_id': self.partner1.id, 'lines': [(0, 0, { @@ -219,6 +225,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): untax2, atax2 = compute_tax(self.product4, 300, 3) self.pos_order_pos3 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'partner_id': self.partner1.id, 'lines': [(0, 0, { @@ -291,11 +298,15 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): untax = res['total_excluded'] return untax, sum(tax.get('amount', 0.0) for tax in res['taxes']) + self.pos_config.open_session_cb() + current_session = self.pos_config.current_session_id + untax1, atax1 = compute_tax(self.product3, 450*0.95, 2) untax2, atax2 = compute_tax(self.product4, 300*0.95, 3) # I create a new PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PCSC349 at 300 EUR. (Tax Excl) self.pos_order_pos1 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'partner_id': self.partner1.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'lines': [(0, 0, { @@ -579,6 +590,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): # I click on create a new session button self.pos_config.open_session_cb() + current_session = self.pos_config.current_session_id # I create a PoS order with 2 units of PCSC234 at 450 EUR (Tax Incl) # and 3 units of PCSC349 at 300 EUR. (Tax Excl) @@ -587,6 +599,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): untax2, atax2 = compute_tax(self.product4, 300*0.95, 3) self.pos_order_pos0 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'pricelist_id': self.partner1.property_product_pricelist.copy(default={'currency_id': self.env.ref('base.EUR').id}).id, 'partner_id': self.partner1.id, 'lines': [(0, 0, { @@ -673,9 +686,14 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): self.assertAlmostEqual(a, b) def test_order_to_invoice_no_tax(self): + + self.pos_config.open_session_cb() + current_session = self.pos_config.current_session_id + # I create a new PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PCSC349 at 300 EUR. (Tax Excl) self.pos_order_pos1 = self.PosOrder.create({ 'company_id': self.company_id, + 'session_id': current_session.id, 'partner_id': self.partner1.id, 'pricelist_id': self.partner1.property_product_pricelist.id, 'lines': [(0, 0, { diff --git a/addons/pos_sale/models/pos_order.py b/addons/pos_sale/models/pos_order.py index 456c6a56a42..821782a646a 100644 --- a/addons/pos_sale/models/pos_order.py +++ b/addons/pos_sale/models/pos_order.py @@ -7,11 +7,14 @@ from odoo import api, fields, models class PosOrder(models.Model): _inherit = 'pos.order' - def _default_crm_team(self): - return self._default_session().config_id.crm_team_id - currency_rate = fields.Float("Currency Rate", compute='_compute_currency_rate', store=True, digits=(12, 6), readonly=True, help='The rate of the currency to the currency of rate applicable at the date of the order') - crm_team_id = fields.Many2one('crm.team', string="Sales Team", default=_default_crm_team) + crm_team_id = fields.Many2one('crm.team', string="Sales Team") + + @api.model + def _complete_values_from_session(self, session, values): + values = super(PosOrder, self)._complete_values_from_session(session, values) + values.setdefault('crm_team_id', session.config_id.crm_team_id.id) + return values @api.depends('pricelist_id.currency_id', 'date_order', 'company_id') def _compute_currency_rate(self):