Example #1
0
 def _compute_line_ids(self):
     for record in self:
         if not record.foo:
             continue
         if any(line.foo == record.foo for line in record.line_ids):
             continue
         # add a line with the same value as 'foo'
         record.line_ids = [Command.create({'foo': record.foo})]
Example #2
0
 def _compute_user_ids(self):
     for portal_wizard in self:
         portal_wizard.user_ids = [
             Command.create({
                 'partner_id': partner.id,
                 'email': partner.email,
             }) for partner in portal_wizard.partner_ids
         ]
Example #3
0
 def _get_demo_data_reconcile_model(self):
     cid = self.env.company.id
     return ('account.reconcile.model', {
         f'{cid}_reconcile_from_label': {
             'name':
             'Line with Bank Fees',
             'rule_type':
             'writeoff_suggestion',
             'match_label':
             'contains',
             'match_label_param':
             'BRT',
             'decimal_separator':
             ',',
             'line_ids': [
                 Command.create({
                     'label':
                     'Due amount',
                     'account_id':
                     self._get_demo_account(
                         'income',
                         'account.data_account_type_revenue',
                         self.env.company,
                     ).id,
                     'amount_type':
                     'regex',
                     'amount_string':
                     r'BRT: ([\d,]+)',
                 }),
                 Command.create({
                     'label':
                     'Bank Fees',
                     'account_id':
                     self._get_demo_account(
                         'cost_of_goods_sold',
                         'account.data_account_type_direct_costs',
                         self.env.company,
                     ).id,
                     'amount_type':
                     'percentage',
                     'amount_string':
                     '100',
                 }),
             ]
         },
     })
Example #4
0
    def test_portal_user_cannot_see_all_assignees(self):
        """ Test when the portal sees a task he cannot see all the assignees.

            Because of a ir.rule in res.partner filters the assignees, the portal
            can only see the assignees in the same company than him.

            Test Cases:
            ==========
            1) add many assignees in a task
            2) check the portal user can read no assignee in this task. Should have an AccessError exception
        """
        self.task_cow.write(
            {'user_ids': [Command.link(self.user_projectmanager.id)]})
        with self.assertRaises(
                AccessError,
                msg=
                "Should not accept the portal user to access to a task he does not follow it and its project."
        ):
            self.task_cow.with_user(self.user_portal).read(
                ['portal_user_names'])
        self.assertEqual(len(self.task_cow.user_ids), 2,
                         '2 users should be assigned in this task.')

        project_share_wizard = self.env['project.share.wizard'].create({
            'access_mode':
            'edit',
            'res_model':
            'project.project',
            'res_id':
            self.project_cows.id,
            'partner_ids': [
                Command.link(self.user_portal.partner_id.id),
            ],
        })
        project_share_wizard.action_send_mail()

        self.assertFalse(
            self.task_cow.with_user(self.user_portal).user_ids,
            'the portal user should see no assigness in the task.')
        task_portal_read = self.task_cow.with_user(self.user_portal).read(
            ['portal_user_names'])
        self.assertEqual(
            self.task_cow.portal_user_names,
            task_portal_read[0]['portal_user_names'],
            'the portal user should see assignees name in the task via the `portal_user_names` field.'
        )
Example #5
0
 def _timesheet_preprocess(self, vals):
     """ Deduce other field values from the one given.
         Overrride this to compute on the fly some field that can not be computed fields.
         :param values: dict values for `create`or `write`.
     """
     # task implies analytic account and tags
     if vals.get('task_id') and not vals.get('account_id'):
         task = self.env['project.task'].browse(vals.get('task_id'))
         task_analytic_account_id = task._get_task_analytic_account_id()
         vals['account_id'] = task_analytic_account_id.id
         vals['company_id'] = task_analytic_account_id.company_id.id or task.company_id.id
         if vals.get('tag_ids'):
             vals['tag_ids'] += [Command.link(tag_id.id) for tag_id in task.analytic_tag_ids]
         else:
             vals['tag_ids'] = [Command.set(task.analytic_tag_ids.ids)]
         if not task_analytic_account_id.active:
             raise UserError(_('You cannot add timesheets to a project or a task linked to an inactive analytic account.'))
     # project implies analytic account
     if vals.get('project_id') and not vals.get('account_id'):
         project = self.env['project.project'].browse(vals.get('project_id'))
         vals['account_id'] = project.analytic_account_id.id
         vals['company_id'] = project.analytic_account_id.company_id.id or project.company_id.id
         if vals.get('tag_ids'):
             vals['tag_ids'] += [Command.link(tag_id.id) for tag_id in project.analytic_tag_ids]
         else:
             vals['tag_ids'] = [Command.set(project.analytic_tag_ids.ids)]
         if not project.analytic_account_id.active:
             raise UserError(_('You cannot add timesheets to a project linked to an inactive analytic account.'))
     # employee implies user
     if vals.get('employee_id') and not vals.get('user_id'):
         employee = self.env['hr.employee'].browse(vals['employee_id'])
         vals['user_id'] = employee.user_id.id
     # force customer partner, from the task or the project
     if (vals.get('project_id') or vals.get('task_id')) and not vals.get('partner_id'):
         partner_id = False
         if vals.get('task_id'):
             partner_id = self.env['project.task'].browse(vals['task_id']).partner_id.id
         else:
             partner_id = self.env['project.project'].browse(vals['project_id']).partner_id.id
         if partner_id:
             vals['partner_id'] = partner_id
     # set timesheet UoM from the AA company (AA implies uom)
     if 'product_uom_id' not in vals and all(v in vals for v in ['account_id', 'project_id']):  # project_id required to check this is timesheet flow
         analytic_account = self.env['account.analytic.account'].sudo().browse(vals['account_id'])
         vals['product_uom_id'] = analytic_account.company_id.project_time_mode_id.id
     return vals
Example #6
0
    def test_warn_company_no_company_field(self):
        """ If one of the failing rules mentions company_id, add a note that
        this might be a multi-company issue, but the record doesn't have company_id field
        then no information about the company is showed.
        """
        self.env.ref('base.group_no_one').write(
            {'users': [Command.link(self.user.id)]})
        self.env.ref('base.group_user').write(
            {'users': [Command.link(self.user.id)]})
        ChildModel = self.env['test_access_right.child'].sudo()
        self.env['ir.rule'].create({
            'name':
            'rule 0',
            'model_id':
            self.env['ir.model'].search([('model', '=', ChildModel._name)]).id,
            'groups': [],
            'domain_force':
            '[("parent_id.company_id", "=", user.company_id.id)]',
            'perm_read':
            True,
        })
        self.record.sudo().company_id = self.env['res.company'].create(
            {'name': 'Brosse Inc.'})
        self.user.sudo().company_ids = [
            Command.link(self.record.company_id.id)
        ]
        child_record = ChildModel.create({
            'parent_id': self.record.id
        }).with_user(self.user)
        with self.assertRaises(AccessError) as ctx:
            _ = child_record.parent_id
        self.assertEqual(
            ctx.exception.args[0],
            """Due to security restrictions, you are not allowed to access 'Object for testing company ir rule' (test_access_right.child) records.

Records: %s (id=%s)
User: %s (id=%s)

This restriction is due to the following rules:
- rule 0

Note: this might be a multi-company issue.

Contact your administrator to request access if necessary.""" %
            (child_record.display_name, child_record.id, self.user.name,
             self.user.id))
Example #7
0
 def _create_liquidity_journal_suspense_account(self, company, code_digits):
     account = super()._create_liquidity_journal_suspense_account(
         company, code_digits)
     if company.account_fiscal_country_id.code == 'NL':
         account.tag_ids = [
             Command.link(self.env.ref('l10n_nl.account_tag_25').id)
         ]
     return account
Example #8
0
 def test_project_sharing_access(self):
     """ Check if the different user types can access to project sharing feature as expected. """
     with self.assertRaises(AccessError, msg='The public user should not have any access to project sharing feature of the portal project.'):
         self.project_portal.with_user(self.user_public)._check_project_sharing_access()
     self.assertTrue(self.project_portal.with_user(self.user_projectuser)._check_project_sharing_access(), 'The internal user should have all accesses to project sharing feature of the portal project.')
     self.assertFalse(self.project_portal.with_user(self.user_portal)._check_project_sharing_access(), 'The portal user should not have any access to project sharing feature of the portal project.')
     self.project_portal.write({'collaborator_ids': [Command.create({'partner_id': self.user_portal.partner_id.id})]})
     self.assertTrue(self.project_portal.with_user(self.user_portal)._check_project_sharing_access(), 'The portal user can access to project sharing feature of the portal project.')
Example #9
0
    def test_export_import(self):
        """ Ensure export+import gives the same result as loading a language """
        # load language and generate missing terms to create missing empty terms
        with mute_logger('odoo.addons.base.models.ir_translation'):
            self.env["base.language.install"].create({
                'lang': 'fr_FR',
                'overwrite': True
            }).lang_install()
        self.env["base.update.translations"].create({
            'lang': 'fr_FR'
        }).act_update()

        translations = self.env["ir.translation"].search([
            ('lang', '=', 'fr_FR'),
            ('module', '=', 'test_translation_import'),
            ('value', '!=', ''),
        ])

        # minus 3 as the original fr.po contains 3 fake code translations (cf
        # test_no_duplicate test) which are not found by babel_extract_terms
        init_translation_count = len(translations) - 3

        module = self.env.ref('base.module_test_translation_import')
        export = self.env["base.language.export"].create({
            'lang':
            'fr_FR',
            'format':
            'po',
            'modules': [Command.set([module.id])]
        })
        export.act_getfile()
        po_file = export.data
        self.assertIsNotNone(po_file)

        translations.unlink()

        import_fr = self.env["base.language.import"].create({
            'name':
            'French',
            'code':
            'fr_FR',
            'data':
            export.data,
            'filename':
            export.name,
            'overwrite':
            False,
        })
        with mute_logger('odoo.addons.base.models.res_lang'):
            import_fr.import_lang()

        import_translation = self.env["ir.translation"].search([
            ('lang', '=', 'fr_FR'),
            ('module', '=', 'test_translation_import'),
            ('value', '!=', ''),
        ])

        self.assertEqual(init_translation_count, len(import_translation))
Example #10
0
    def test_08_purchases_multi_linkages(self):
        """Directly link POs to each other as 'Alternatives': check linking/unlinking
        POs that are already linked correctly work."""
        pos = []
        for _ in range(5):
            pos += self.env['purchase.order'].create({
                'partner_id':
                self.res_partner_1.id,
            }).ids
        pos = self.env['purchase.order'].browse(pos)
        po_1, po_2, po_3, po_4, po_5 = pos

        po_1.alternative_po_ids |= po_2
        po_3.alternative_po_ids |= po_4
        groups = self.env['purchase.order.group'].search([('order_ids', 'in',
                                                           pos.ids)])
        self.assertEqual(len(po_1.alternative_po_ids), 2,
                         "PO1 and PO2 should only be linked to each other")
        self.assertEqual(len(po_3.alternative_po_ids), 2,
                         "PO3 and PO4 should only be linked to each other")
        self.assertEqual(
            len(groups), 2,
            "There should only be 2 groups: (PO1,PO2) and (PO3,PO4)")

        # link non-linked PO to already linked PO
        po_5.alternative_po_ids |= po_4
        groups = self.env['purchase.order.group'].search([('order_ids', 'in',
                                                           pos.ids)])
        self.assertEqual(len(po_3.alternative_po_ids), 3,
                         "PO3 should now be linked to PO4 and PO5")
        self.assertEqual(len(po_4.alternative_po_ids), 3,
                         "PO4 should now be linked to PO3 and PO5")
        self.assertEqual(len(po_5.alternative_po_ids), 3,
                         "PO5 should now be linked to PO3 and PO4")
        self.assertEqual(
            len(groups), 2,
            "There should only be 2 groups: (PO1,PO2) and (PO3,PO4,PO5)")

        # link already linked PO to already linked PO
        po_5.alternative_po_ids |= po_1
        groups = self.env['purchase.order.group'].search([('order_ids', 'in',
                                                           pos.ids)])
        self.assertEqual(len(po_1.alternative_po_ids), 5,
                         "All 5 POs should be linked to each other now")
        self.assertEqual(
            len(groups), 1,
            "There should only be 1 group containing all 5 POs (other group should have auto-deleted"
        )

        # remove all links, make sure group auto-deletes
        (pos - po_5).alternative_po_ids = [Command.clear()]
        groups = self.env['purchase.order.group'].search([('order_ids', 'in',
                                                           pos.ids)])
        self.assertEqual(
            len(po_5.alternative_po_ids), 0,
            "Last PO should auto unlink from itself since group should have auto-deleted"
        )
        self.assertEqual(len(groups), 0, "The group should have auto-deleted")
Example #11
0
    def test_40_multi(self):
        # Data: 2 server actions that will be nested
        action1 = self.action.create({
            'name': 'Subaction1',
            'sequence': 1,
            'model_id': self.res_partner_model.id,
            'state': 'code',
            'code': 'action = {"type": "ir.actions.act_window"}',
        })
        action2 = self.action.create({
            'name': 'Subaction2',
            'sequence': 2,
            'model_id': self.res_partner_model.id,
            'crud_model_id': self.res_partner_model.id,
            'state': 'object_create',
            'fields_lines': [Command.create({'col1': self.res_partner_name_field.id, 'value': 'RaoulettePoiluchette'}),
                             Command.create({'col1': self.res_partner_city_field.id, 'value': 'TestingCity'})],
        })
        action3 = self.action.create({
            'name': 'Subaction3',
            'sequence': 3,
            'model_id': self.res_partner_model.id,
            'state': 'code',
            'code': 'action = {"type": "ir.actions.act_url"}',
        })
        self.action.write({
            'state': 'multi',
            'child_ids': [Command.set([action1.id, action2.id, action3.id])],
        })

        # Do: run the action
        res = self.action.with_context(self.context).run()

        # Test: new partner created
        # currently res_partner overrides default['name'] whatever its value
        partner = self.test_partner.search([('name', 'ilike', 'RaoulettePoiluchette')])
        self.assertEqual(len(partner), 1)
        # Test: action returned
        self.assertEqual(res.get('type'), 'ir.actions.act_url')

        # Test loops
        with self.assertRaises(ValidationError):
            self.action.write({
                'child_ids': [Command.set([self.action.id])]
            })
Example #12
0
    def test_60_prefetch_model(self):
        """ Check the prefetching model. """
        partners = self.env['res.partner'].search([('id', 'in', self.partners.ids)], limit=models.PREFETCH_MAX)
        self.assertTrue(partners)

        def same_prefetch(a, b):
            self.assertEqual(set(a._prefetch_ids), set(b._prefetch_ids))

        def diff_prefetch(a, b):
            self.assertNotEqual(set(a._prefetch_ids), set(b._prefetch_ids))

        # the recordset operations below use different prefetch sets
        diff_prefetch(partners, partners.browse())
        diff_prefetch(partners, partners[0])
        diff_prefetch(partners, partners[:5])

        # the recordset operations below share the prefetch set
        same_prefetch(partners, partners.browse(partners.ids))
        same_prefetch(partners, partners.with_user(self.user_demo))
        same_prefetch(partners, partners.with_context(active_test=False))
        same_prefetch(partners, partners[:10].with_prefetch(partners._prefetch_ids))

        # iteration and relational fields should use the same prefetch set
        self.assertEqual(type(partners).country_id.type, 'many2one')
        self.assertEqual(type(partners).bank_ids.type, 'one2many')
        self.assertEqual(type(partners).category_id.type, 'many2many')

        vals0 = {
            'name': 'Empty relational fields',
            'country_id': False,
            'bank_ids': [],
            'category_id': [],
        }
        vals1 = {
            'name': 'Non-empty relational fields',
            'country_id': self.ref('base.be'),
            'bank_ids': [Command.create({'acc_number': 'FOO42'})],
            'category_id': [Command.link(self.partner_category.id)],
        }
        partners = partners.create(vals0) + partners.create(vals1)
        for partner in partners:
            same_prefetch(partner, partners)
            same_prefetch(partner.country_id, partners.country_id)
            same_prefetch(partner.bank_ids, partners.bank_ids)
            same_prefetch(partner.category_id, partners.category_id)
Example #13
0
    def test_res_group_recursion(self):
        # four groups with no cycle, check them all together
        a = self.env['res.groups'].create({'name': 'A'})
        b = self.env['res.groups'].create({'name': 'B'})
        c = self.env['res.groups'].create({
            'name':
            'G',
            'implied_ids': [Command.set((a + b).ids)]
        })
        d = self.env['res.groups'].create({
            'name': 'D',
            'implied_ids': [Command.set(c.ids)]
        })
        self.assertTrue((a + b + c + d)._check_m2m_recursion('implied_ids'))

        # create a cycle and check
        a.implied_ids = d
        self.assertFalse(a._check_m2m_recursion('implied_ids'))
Example #14
0
    def test_activity_calendar_event_id(self):
        """Test the computed field "activity_calendar_event_id" which is the event of the
        next activity. It must evaluate to False if the next activity is not related to an event"""
        def create_event(name, event_date):
            return self.env['calendar.event'].create({
                'name':
                name,
                'start':
                datetime.combine(event_date, time(12, 0, 0)),
                'stop':
                datetime.combine(event_date, time(14, 0, 0)),
            })

        def schedule_meeting_activity(record,
                                      date_deadline,
                                      calendar_event=False):
            meeting = record.activity_schedule(
                'calendar.calendar_activity_test_default',
                date_deadline=date_deadline)
            meeting.calendar_event_id = calendar_event
            return meeting

        group_partner_manager = self.env['ir.model.data']._xmlid_to_res_id(
            'base.group_partner_manager')
        self.user_employee.write({
            'tz':
            self.user_admin.tz,
            'groups_id': [Command.link(group_partner_manager)]
        })
        with self.with_user('employee'):
            test_record = self.env['res.partner'].browse(self.test_record.id)
            self.assertEqual(test_record.activity_ids,
                             self.env['mail.activity'])

            now_utc = datetime.now(pytz.UTC)
            now_user = now_utc.astimezone(
                pytz.timezone(self.env.user.tz or 'UTC'))
            today_user = now_user.date()

            date1 = today_user + relativedelta(days=1)
            date2 = today_user + relativedelta(days=2)

            ev1 = create_event('ev1', date1)
            ev2 = create_event('ev2', date2)

            act1 = schedule_meeting_activity(test_record, date1)
            schedule_meeting_activity(test_record, date2, ev2)

            self.assertFalse(
                test_record.activity_calendar_event_id,
                "The next activity does not have a calendar event")

            act1.calendar_event_id = ev1

            self.assertEqual(
                test_record.activity_calendar_event_id.name, ev1.name,
                "This should be the calendar event of the next activity")
Example #15
0
 def _set_count(self):
     for r in self:
         r.write({
             'm2m': [
                 Command.create({'name': str(n)})
                 for n, v in zip_longest(range(r.count), r.m2m or [])
                 if v is None
             ]
         })
Example #16
0
 def test_create_base_with_lines(self):
     """ Create records with one2many lines. """
     with self.assertQueryCount(__system__=12, demo=12):
         self.env['test_performance.base'].create({
             'name':
             'X',
             'line_ids':
             [Command.create({'value': val}) for val in range(10)],
         })
Example #17
0
 def _compute_invalid_addresses(self):
     for wizard in self:
         if any(not invoice.partner_id for invoice in wizard.invoice_ids):
             raise UserError(_('You cannot send an invoice which has no partner assigned.'))
         invalid_invoices = wizard.invoice_ids.filtered(lambda i: not self.env['snailmail.letter']._is_valid_address(i.partner_id))
         wizard.invalid_invoices = len(invalid_invoices)
         invalid_partner_ids = invalid_invoices.partner_id.ids
         wizard.invalid_addresses = len(invalid_partner_ids)
         wizard.invalid_partner_ids = [Command.set(invalid_partner_ids)]
    def _merge(self, partner_ids, dst_partner=None, extra_checks=True):
        """ private implementation of merge partner
            :param partner_ids : ids of partner to merge
            :param dst_partner : record of destination res.partner
            :param extra_checks: pass False to bypass extra sanity check (e.g. email address)
        """
        # super-admin can be used to bypass extra checks
        if self.env.is_admin():
            extra_checks = False

        Partner = self.env['res.partner']
        partner_ids = Partner.browse(partner_ids).exists()
        if len(partner_ids) < 2:
            return

        if len(partner_ids) > 3:
            raise UserError(_("For safety reasons, you cannot merge more than 3 contacts together. You can re-open the wizard several times if needed."))

        # check if the list of partners to merge contains child/parent relation
        child_ids = self.env['res.partner']
        for partner_id in partner_ids:
            child_ids |= Partner.search([('id', 'child_of', [partner_id.id])]) - partner_id
        if partner_ids & child_ids:
            raise UserError(_("You cannot merge a contact with one of his parent."))

        if extra_checks and len(set(partner.email for partner in partner_ids)) > 1:
            raise UserError(_("All contacts must have the same email. Only the Administrator can merge contacts with different emails."))

        # remove dst_partner from partners to merge
        if dst_partner and dst_partner in partner_ids:
            src_partners = partner_ids - dst_partner
        else:
            ordered_partners = self._get_ordered_partner(partner_ids.ids)
            dst_partner = ordered_partners[-1]
            src_partners = ordered_partners[:-1]
        _logger.info("dst_partner: %s", dst_partner.id)

        # FIXME: is it still required to make and exception for account.move.line since accounting v9.0 ?
        if extra_checks and 'account.move.line' in self.env and self.env['account.move.line'].sudo().search([('partner_id', 'in', [partner.id for partner in src_partners])]):
            raise UserError(_("Only the destination contact may be linked to existing Journal Items. Please ask the Administrator if you need to merge several contacts linked to existing Journal Items."))

        # Make the company of all related users consistent with destination partner company
        if dst_partner.company_id:
            partner_ids.mapped('user_ids').sudo().write({
                'company_ids': [Command.link(dst_partner.company_id.id)],
                'company_id': dst_partner.company_id.id
            })

        # call sub methods to do the merge
        self._update_foreign_keys(src_partners, dst_partner)
        self._update_reference_fields(src_partners, dst_partner)
        self._update_values(src_partners, dst_partner)

        self._log_merge_operation(src_partners, dst_partner)

        # delete source partner, since they are merged
        src_partners.unlink()
    def test_broken_configuration(self):
        percent_tax = self.env['account.tax'].create({
            'name': "percent_tax",
            'amount_type': 'percent',
            'amount': 10.0,
        })

        invoice = self.env['account.move'].create({
            'move_type':
            'out_invoice',
            'partner_id':
            self.partner_a.id,
            'invoice_date':
            '2019-01-01',
            'invoice_line_ids': [
                Command.create({
                    'name':
                    'line1',
                    'account_id':
                    self.company_data['default_account_revenue'].id,
                    'price_unit':
                    1000.0,
                    'tax_ids': [Command.set(percent_tax.ids)],
                }),
            ]
        })
        base_lines, tax_lines = self._dispatch_move_lines(invoice)

        # Break the configuration
        tax_lines.account_id = self.company_data['default_account_assets']

        tax_details = self._get_tax_details(fallback=True)
        self.assertTaxDetailsValues(
            tax_details,
            [
                {
                    'base_line_id': base_lines[0].id,
                    'tax_line_id': tax_lines[0].id,
                    'base_amount': -1000.0,
                    'tax_amount': -100.0,
                },
            ],
        )
        self.assertTotalAmounts(invoice, tax_details)
Example #20
0
    def test_onchange_one2many_with_domain_on_related_field(self):
        """ test the value of the one2many field when defined with a domain on a related field"""
        discussion = self.env.ref('test_new_api.discussion_0')
        demo = self.user_demo

        # mimic UI behaviour, so we get subfields
        # (we need at least subfield: 'important_emails.important')
        view_info = self.Discussion.get_view(self.env.ref('test_new_api.discussion_form').id, 'form')
        field_onchange = self.Discussion._onchange_spec(view_info=view_info)
        self.assertEqual(field_onchange.get('messages'), '1')

        BODY = "What a beautiful day!"
        USER = self.env.user

        # create standalone email
        email = self.EmailMessage.create({
            'discussion': discussion.id,
            'name': "[%s] %s" % ('', USER.name),
            'body': BODY,
            'author': USER.id,
            'important': False,
            'email_to': demo.email,
        })

        # check if server-side cache is working correctly
        self.env.cache.invalidate()
        self.assertIn(email, discussion.emails)
        self.assertNotIn(email, discussion.important_emails)
        email.important = True
        self.assertIn(email, discussion.important_emails)

        # check that when trigger an onchange, we don't reset important emails
        # (force `invalidate` as but appear in onchange only when we get a cache
        # miss)
        self.env.cache.invalidate()
        self.assertEqual(len(discussion.messages), 4)
        values = {
            'name': "Foo Bar",
            'moderator': demo.id,
            'categories': [Command.link(cat.id) for cat in discussion.categories],
            'messages': [Command.link(msg.id) for msg in discussion.messages],
            'participants': [Command.link(usr.id) for usr in discussion.participants],
            'important_messages': [Command.link(msg.id) for msg in discussion.important_messages],
            'important_emails': [Command.link(eml.id) for eml in discussion.important_emails],
        }
        self.env.cache.invalidate()
        result = discussion.onchange(values, 'name', field_onchange)

        self.assertEqual(
            result['value']['important_emails'],
            [Command.clear(), Command.update(email.id, {
                'name': u'[Foo Bar] %s' % USER.name,
                'body': BODY,
                'author': USER.name_get()[0],
                'size': len(BODY),
                'important': True,
                'email_to': demo.email,
            })],
        )
Example #21
0
    def unstar_all(self):
        """ Unstar messages for the current partner. """
        partner_id = self.env.user.partner_id.id

        starred_messages = self.search([('starred_partner_ids', 'in', partner_id)])
        starred_messages.write({'starred_partner_ids': [Command.unlink(partner_id)]})

        ids = [m.id for m in starred_messages]
        notification = {'type': 'toggle_star', 'message_ids': ids, 'starred': False}
        self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', self.env.user.partner_id.id), notification)
Example #22
0
 def test_write_4_one2many(self):
     """ Check that we can write on an inherited one2many field. """
     box = self.env.ref('test_inherits.box_a')
     box.write({'line_ids': [Command.create({'name': 'Line 1'})]})
     self.assertTrue(all(box.line_ids._ids))
     self.assertEqual(box.line_ids.mapped('name'), ['Line 1'])
     self.assertEqual(box.line_ids, box.unit_id.line_ids)
     box.flush()
     box.invalidate_cache(['line_ids'])
     box.write({'line_ids': [Command.create({'name': 'Line 2'})]})
     self.assertTrue(all(box.line_ids._ids))
     self.assertEqual(box.line_ids.mapped('name'), ['Line 1', 'Line 2'])
     self.assertEqual(box.line_ids, box.unit_id.line_ids)
     box.flush()
     box.invalidate_cache(['line_ids'])
     box.write({'line_ids': [Command.update(box.line_ids[0].id, {'name': 'First line'})]})
     self.assertTrue(all(box.line_ids._ids))
     self.assertEqual(box.line_ids.mapped('name'), ['First line', 'Line 2'])
     self.assertEqual(box.line_ids, box.unit_id.line_ids)
    def test_amounts_sign(self):
        for tax_sign in (1, -1):
            tax = self.env['account.tax'].create({
                'name': "tax",
                'amount_type': 'percent',
                'amount': tax_sign * 10.0,
            })

            amounts_list = [
                (-1000.0, 7000.0, -2000.0),
                (1000.0, -7000.0, 2000.0),
                (-1000.0, -7000.0, 2000.0),
                (1000.0, 7000.0, -2000.0),
            ]
            for amounts in amounts_list:
                with self.subTest(tax_sign=tax_sign, amounts=amounts):
                    invoice = self.env['account.move'].create({
                        'move_type': 'in_invoice',
                        'partner_id': self.partner_a.id,
                        'invoice_date': '2019-01-01',
                        'invoice_line_ids': [
                            Command.create({
                                'name': 'line2',
                                'account_id': self.company_data['default_account_revenue'].id,
                                'price_unit': amount,
                                'tax_ids': [Command.set(tax.ids)],
                            })
                        for amount in amounts],
                    })
                    _base_lines, tax_lines = self._dispatch_move_lines(invoice)

                    tax_details = self._get_tax_details(extra_domain=[('move_id', '=', invoice.id)])
                    self.assertTaxDetailsValues(
                        tax_details,
                        [
                            {
                                'tax_line_id': tax_lines[0].id,
                                'base_amount': amount,
                                'tax_amount': tax_sign * amount * 0.1,
                            }
                        for amount in amounts],
                    )
                    self.assertTotalAmounts(invoice, tax_details)
Example #24
0
 def restart_google_synchronization(self):
     self.ensure_one()
     if not self.google_cal_account_id:
         self.google_cal_account_id = self.env[
             'google.calendar.credentials'].sudo().create([{
                 'user_ids': [Command.set(self.ids)]
             }])
     self.google_synchronization_stopped = False
     self.env['calendar.recurrence']._restart_google_sync()
     self.env['calendar.event']._restart_google_sync()
Example #25
0
    def setUpClass(cls):
        super(TestMailGroupModeration, cls).setUpClass()

        cls.test_group_2 = cls.env['mail.group'].create({
            'access_mode': 'members',
            'alias_name': 'test.mail.group.2',
            'moderation': True,
            'moderator_ids': [Command.link(cls.user_employee.id)],
            'name': 'Test group 2',
        })
Example #26
0
 def _get_livechat_mail_channel_vals(self,
                                     anonymous_name,
                                     operator,
                                     user_id=None,
                                     country_id=None):
     # partner to add to the mail.channel
     operator_partner_id = operator.partner_id.id
     channel_partner_to_add = [
         Command.create({
             'partner_id': operator_partner_id,
             'is_pinned': False
         })
     ]
     visitor_user = False
     if user_id:
         visitor_user = self.env['res.users'].browse(user_id)
         if visitor_user and visitor_user.active and visitor_user != operator:  # valid session user (not public)
             channel_partner_to_add.append(
                 Command.create({'partner_id': visitor_user.partner_id.id}))
     return {
         'channel_last_seen_partner_ids':
         channel_partner_to_add,
         'livechat_active':
         True,
         'livechat_operator_id':
         operator_partner_id,
         'livechat_channel_id':
         self.id,
         'anonymous_name':
         False if user_id else anonymous_name,
         'country_id':
         country_id,
         'channel_type':
         'livechat',
         'name':
         ' '.join([
             visitor_user.display_name if visitor_user else anonymous_name,
             operator.livechat_username
             if operator.livechat_username else operator.name
         ]),
         'public':
         'private',
     }
Example #27
0
    def test_frozendict_hash(self):
        """ Ensure that a frozendict is hashable. """
        # dict with simple values
        hash(frozendict({'name': 'Joe', 'age': 42}))

        # dict with tuples, lists, and embedded dicts
        hash(frozendict({
            'user_id': (42, 'Joe'),
            'line_ids': [Command.create({'values': [42]})],
        }))
Example #28
0
 def _get_backorder_move_vals(self):
     self.ensure_one()
     return {
         'state':
         'confirmed',
         'reservation_date':
         self.reservation_date,
         'date_deadline':
         self.date_deadline,
         'manual_consumption':
         self.bom_line_id.manual_consumption
         or self.product_id.tracking != 'none',
         'move_orig_ids':
         [Command.link(m.id) for m in self.mapped('move_orig_ids')],
         'move_dest_ids':
         [Command.link(m.id) for m in self.mapped('move_dest_ids')],
         'procure_method':
         self.procure_method,
     }
    def test_read(self):
        """ because of prefetching, read() goes through a different codepath
        to apply rules
        """
        self.env.ref('base.group_no_one').write(
            {'users': [Command.link(self.user.id)]})
        self.env.ref('base.group_user').write(
            {'users': [Command.link(self.user.id)]})
        self._make_rule('rule 0',
                        "[('company_id', '=', user.company_id.id)]",
                        attr='read')
        self._make_rule('rule 1',
                        '[("val", "=", 1)]',
                        global_=True,
                        attr='read')
        with self.assertRaises(AccessError) as ctx:
            _ = self.record.val
        self.assertEqual(
            ctx.exception.args[0],
            """Due to security restrictions, you are not allowed to access 'Object For Test Access Right' (test_access_right.some_obj) records.

Records: %s (id=%s)
User: %s (id=%s)

This restriction is due to the following rules:
- rule 0
- rule 1

Note: this might be a multi-company issue.

Contact your administrator to request access if necessary.""" %
            (self.record.display_name, self.record.id, self.user.name,
             self.user.id))

        p = self.env['test_access_right.parent'].create(
            {'obj_id': self.record.id})
        p.flush()
        p.invalidate_cache()
        with self.assertRaisesRegex(
                AccessError,
                r"Implicitly accessed through 'Object for testing related access rights' \(test_access_right.parent\)\.",
        ):
            p.with_user(self.user).val
Example #30
0
 def setUpClass(cls):
     super().setUpClass()
     # use a single value for today throughout the tests to avoid weird scenarios around midnight
     cls.today = date.today()
     baseUser = cls.env['res.users'].create({
         'email':
         '*****@*****.**',
         'groups_id': [Command.link(cls.env.ref('base.group_user').id)],
         'login':
         '******',
         'name':
         'Ernest Employee',
         'notification_type':
         'inbox',
         'signature':
         '--\nErnest',
     })
     cls.partner = baseUser.partner_id
     cls.users = baseUser + cls.env['res.users'].create(
         {
             'name': 'test1',
             'login': '******',
             'email': '*****@*****.**',
             'partner_id': cls.partner.id,
         })
     cls.employees = cls.env['hr.employee'].create([{
         'user_id': user.id,
     } for user in cls.users])
     cls.leave_type = cls.env['hr.leave.type'].create({
         'requires_allocation':
         'no',
         'name':
         'Legal Leaves',
         'time_type':
         'leave',
     })
     cls.leaves = cls.env['hr.leave'].create([{
         'date_from':
         cls.today + relativedelta(days=-2),
         'date_to':
         cls.today + relativedelta(days=2),
         'employee_id':
         cls.employees[0].id,
         'holiday_status_id':
         cls.leave_type.id,
     }, {
         'date_from':
         cls.today + relativedelta(days=-2),
         'date_to':
         cls.today + relativedelta(days=3),
         'employee_id':
         cls.employees[1].id,
         'holiday_status_id':
         cls.leave_type.id,
     }])