from odoo.tests import TransactionCase, tagged @tagged('post_install', '-at_install') class TestPosHideMargin(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() # Find the first active company active_company = cls.env['res.company'].search([], limit=1) if not active_company: # Fallback to any company if no active one exists active_company = cls.env['res.company'].with_context(active_test=False).search([], limit=1) # Use the active company environment for all record creation in setup cls.env = cls.env['res.users'].with_company(active_company).env # Create a user with x_hide_margin=True cls.restricted_user = cls.env['res.users'].create({ 'name': 'Restricted POS User', 'login': 'restricted_pos_user', 'email': 'restricted@example.com', 'x_hide_margin': True, 'group_ids': [(6, 0, [ cls.env.ref('point_of_sale.group_pos_user').id, cls.env.ref('base.group_user').id, ])], 'company_id': active_company.id, 'company_ids': [(6, 0, [active_company.id])], }) # Create a normal user with x_hide_margin=False cls.normal_user = cls.env['res.users'].create({ 'name': 'Normal POS User', 'login': 'normal_pos_user', 'email': 'normal@example.com', 'x_hide_margin': False, 'group_ids': [(6, 0, [ cls.env.ref('point_of_sale.group_pos_user').id, cls.env.ref('base.group_user').id, ])], 'company_id': active_company.id, 'company_ids': [(6, 0, [active_company.id])], }) # Create a product and template with cost and list price cls.product = cls.env['product.product'].create({ 'name': 'Margin Test Product', 'list_price': 100.0, 'standard_price': 60.0, # cost = 60 }) # Create a POS Config & Session cls.pos_config = cls.env['pos.config'].create({ 'name': 'Test POS shop', 'company_id': active_company.id, }) cls.pos_session = cls.env['pos.session'].create({ 'config_id': cls.pos_config.id, 'user_id': cls.env.uid, }) # Create a POS Order cls.pos_order = cls.env['pos.order'].create({ 'session_id': cls.pos_session.id, 'partner_id': cls.env.ref('base.partner_admin').id, 'company_id': active_company.id, 'amount_total': 100.0, 'amount_tax': 0.0, 'amount_paid': 100.0, 'amount_return': 0.0, 'lines': [(0, 0, { 'product_id': cls.product.id, 'qty': 1, 'price_unit': 100.0, 'price_subtotal': 100.0, 'price_subtotal_incl': 100.0, 'total_cost': 60.0, 'is_total_cost_computed': True, })] }) # Compute margins cls.pos_order._compute_margin() cls.pos_order.lines._compute_margin() def test_margin_computation_normal_user(self): """Test that margin is correctly calculated for a normal user.""" order = self.pos_order.with_user(self.normal_user) order._compute_margin() # Cost is 60, price is 100 -> margin = 40, margin_percent = 40% (0.4) self.assertAlmostEqual(order.margin, 40.0) self.assertAlmostEqual(order.margin_percent, 0.4) line = self.pos_order.lines[0].with_user(self.normal_user) line._compute_margin() self.assertAlmostEqual(line.margin, 40.0) def test_margin_computation_restricted_user(self): """Test that margin calculations are zeroed out for restricted users.""" order = self.pos_order.with_user(self.restricted_user) order._compute_margin() self.assertEqual(order.margin, 0.0) self.assertEqual(order.margin_percent, 0.0) line = self.pos_order.lines[0].with_user(self.restricted_user) line._compute_margin() self.assertEqual(line.margin, 0.0) self.assertEqual(line.margin_percent, 0.0) def test_fields_get_restrictions(self): """Test fields_get hides margin fields metadata for restricted users.""" # Check for normal user fields_normal = self.env['pos.order'].with_user(self.normal_user).fields_get(['margin', 'margin_percent']) self.assertFalse(fields_normal.get('margin', {}).get('invisible', False)) # Check for restricted user fields_restricted = self.env['pos.order'].with_user(self.restricted_user).fields_get(['margin', 'margin_percent']) self.assertTrue(fields_restricted.get('margin', {}).get('invisible', False)) self.assertFalse(fields_restricted.get('margin', {}).get('searchable', True)) def test_report_pos_order_read_restrictions(self): """Test reading report.pos.order zeros out margins for restricted users.""" # Create a report record via SQL reload self.env['report.pos.order'].init() report_records = self.env['report.pos.order'].search([('order_id', '=', self.pos_order.id)]) self.assertTrue(report_records) # Normal user reads report report_normal = report_records.with_user(self.normal_user).read(['margin']) self.assertAlmostEqual(report_normal[0]['margin'], 40.0) # Restricted user reads report report_restricted = report_records.with_user(self.restricted_user).read(['margin']) self.assertEqual(report_restricted[0]['margin'], 0.0) # Normal user read_group group_normal = self.env['report.pos.order'].with_user(self.normal_user).read_group( [('order_id', '=', self.pos_order.id)], ['margin'], ['product_categ_id'] ) self.assertAlmostEqual(group_normal[0]['margin'], 40.0) # Restricted user read_group group_restricted = self.env['report.pos.order'].with_user(self.restricted_user).read_group( [('order_id', '=', self.pos_order.id)], ['margin'], ['product_categ_id'] ) self.assertEqual(group_restricted[0]['margin'], 0.0) # Normal user _read_group _group_normal = self.env['report.pos.order'].with_user(self.normal_user)._read_group( [('order_id', '=', self.pos_order.id)], ['product_categ_id'], ['margin:sum'] ) self.assertAlmostEqual(_group_normal[0][1], 40.0) # Restricted user _read_group _group_restricted = self.env['report.pos.order'].with_user(self.restricted_user)._read_group( [('order_id', '=', self.pos_order.id)], ['product_categ_id'], ['margin:sum'] ) self.assertEqual(_group_restricted[0][1], 0.0) # Normal user _read_grouping_sets sets_normal = self.env['report.pos.order'].with_user(self.normal_user)._read_grouping_sets( [('order_id', '=', self.pos_order.id)], [['product_categ_id']], ['margin:sum'] ) self.assertAlmostEqual(sets_normal[0][0][1], 40.0) # Restricted user _read_grouping_sets sets_restricted = self.env['report.pos.order'].with_user(self.restricted_user)._read_grouping_sets( [('order_id', '=', self.pos_order.id)], [['product_categ_id']], ['margin:sum'] ) self.assertEqual(sets_restricted[0][0][1], 0.0) def test_pos_order_read_restrictions(self): """Test reading pos.order and pos.order.line zeros out margins for restricted users.""" # Normal user reads order order_normal = self.pos_order.with_user(self.normal_user).read(['margin', 'margin_percent']) self.assertAlmostEqual(order_normal[0]['margin'], 40.0) self.assertAlmostEqual(order_normal[0]['margin_percent'], 0.4) # Restricted user reads order order_restricted = self.pos_order.with_user(self.restricted_user).read(['margin', 'margin_percent']) self.assertEqual(order_restricted[0]['margin'], 0.0) self.assertEqual(order_restricted[0]['margin_percent'], 0.0) # Normal user reads line line_normal = self.pos_order.lines[0].with_user(self.normal_user).read(['margin', 'margin_percent']) self.assertAlmostEqual(line_normal[0]['margin'], 40.0) # Restricted user reads line line_restricted = self.pos_order.lines[0].with_user(self.restricted_user).read(['margin', 'margin_percent']) self.assertEqual(line_restricted[0]['margin'], 0.0) self.assertEqual(line_restricted[0]['margin_percent'], 0.0)