Example #1
0
 def _search_full_name(self, operator, operand):
     lst = True
     if isinstance(operand, bool):
         domains = [[('name', operator, operand)], [('category_id.name', operator, operand)]]
         if operator in expression.NEGATIVE_TERM_OPERATORS == (not operand):
             return expression.AND(domains)
         else:
             return expression.OR(domains)
     if isinstance(operand, pycompat.string_types):
         lst = False
         operand = [operand]
     where = []
     for group in operand:
         values = [v for v in group.split('/') if v]
         group_name = values.pop().strip()
         category_name = values and '/'.join(values).strip() or group_name
         group_domain = [('name', operator, lst and [group_name] or group_name)]
         category_domain = [('category_id.name', operator, lst and [category_name] or category_name)]
         if operator in expression.NEGATIVE_TERM_OPERATORS and not values:
             category_domain = expression.OR([category_domain, [('category_id', '=', False)]])
         if (operator in expression.NEGATIVE_TERM_OPERATORS) == (not values):
             sub_where = expression.AND([group_domain, category_domain])
         else:
             sub_where = expression.OR([group_domain, category_domain])
         if operator in expression.NEGATIVE_TERM_OPERATORS:
             where = expression.AND([where, sub_where])
         else:
             where = expression.OR([where, sub_where])
     return where
Example #2
0
 def _search_rule(self, product_id, values, domain):
     """ First find a rule among the ones defined on the procurement
     group; then try on the routes defined for the product; finally fallback
     on the default behavior """
     if values.get('warehouse_id', False):
         domain = expression.AND([[
             '|', ('warehouse_id', '=', values['warehouse_id'].id),
             ('warehouse_id', '=', False)
         ], domain])
     Pull = self.env['procurement.rule']
     res = self.env['procurement.rule']
     if values.get('route_ids', False):
         res = Pull.search(expression.AND([[
             ('route_id', 'in', values['route_ids'].ids)
         ], domain]),
                           order='route_sequence, sequence',
                           limit=1)
     if not res:
         product_routes = product_id.route_ids | product_id.categ_id.total_route_ids
         if product_routes:
             res = Pull.search(expression.AND([[
                 ('route_id', 'in', product_routes.ids)
             ], domain]),
                               order='route_sequence, sequence',
                               limit=1)
     if not res:
         warehouse_routes = values['warehouse_id'].route_ids
         if warehouse_routes:
             res = Pull.search(expression.AND([[
                 ('route_id', 'in', warehouse_routes.ids)
             ], domain]),
                               order='route_sequence, sequence',
                               limit=1)
     return res
Example #3
0
    def _gather(self, product_id, location_id, lot_id=None, package_id=None, owner_id=None, strict=False):
        removal_strategy = self._get_removal_strategy(product_id, location_id)
        removal_strategy_order = self._get_removal_strategy_order(removal_strategy)
        domain = [
            ('product_id', '=', product_id.id),
        ]
        if not strict:
            if lot_id:
                domain = expression.AND([[('lot_id', '=', lot_id.id)], domain])
            if package_id:
                domain = expression.AND([[('package_id', '=', package_id.id)], domain])
            if owner_id:
                domain = expression.AND([[('owner_id', '=', owner_id.id)], domain])
            domain = expression.AND([[('location_id', 'child_of', location_id.id)], domain])
        else:
            domain = expression.AND([[('lot_id', '=', lot_id and lot_id.id or False)], domain])
            domain = expression.AND([[('package_id', '=', package_id and package_id.id or False)], domain])
            domain = expression.AND([[('owner_id', '=', owner_id and owner_id.id or False)], domain])
            domain = expression.AND([[('location_id', '=', location_id.id)], domain])

        # Copy code of _search for special NULLS FIRST/LAST order
        self.sudo(self._uid).check_access_rights('read')
        query = self._where_calc(domain)
        self._apply_ir_rules(query, 'read')
        from_clause, where_clause, where_clause_params = query.get_sql()
        where_str = where_clause and (" WHERE %s" % where_clause) or ''
        query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + " ORDER BY "+ removal_strategy_order
        self._cr.execute(query_str, where_clause_params)
        res = self._cr.fetchall()
        # No uniquify list necessary as auto_join is not applied anyways...
        return self.browse([x[0] for x in res])
Example #4
0
 def channel_search_to_join(self, name=None, domain=None):
     """ Return the channel info of the channel the current partner can join
         :param name : the name of the researched channels
         :param domain : the base domain of the research
         :returns dict : channel dict
     """
     if not domain:
         domain = []
     domain = expression.AND([[('channel_type', '=', 'channel')],
                              [('channel_partner_ids', 'not in',
                                [self.env.user.partner_id.id])],
                              [('public', '!=', 'private')], domain])
     if name:
         domain = expression.AND(
             [domain, [('name', 'ilike', '%' + name + '%')]])
     return self.search(domain).read(
         ['name', 'public', 'uuid', 'channel_type'])
Example #5
0
 def get_website_translations(self, lang, mods=None):
     Modules = request.env['ir.module.module'].sudo()
     IrHttp = request.env['ir.http'].sudo()
     domain = IrHttp._get_translation_frontend_modules_domain()
     modules = Modules.search(
         expression.AND([domain, [('state', '=', 'installed')]])
     ).mapped('name')
     if mods:
         modules += mods
     return WebClient().translations(mods=modules, lang=lang)
Example #6
0
 def get_mention_suggestions(self, search, limit=8):
     """ Return 'limit'-first channels' id, name and public fields such that the name matches a
         'search' string. Exclude channels of type chat (DM), and private channels the current
         user isn't registered to. """
     domain = expression.AND([[('name', 'ilike', search)],
                              [('channel_type', '=', 'channel')],
                              expression.OR(
                                  [[('public', '!=', 'private')],
                                   [('channel_partner_ids', 'in',
                                     [self.env.user.partner_id.id])]])])
     return self.search_read(domain, ['id', 'name', 'public'], limit=limit)
Example #7
0
    def portal_message_fetch(self, res_model, res_id, domain=False, limit=10, offset=0, **kw):
        if not domain:
            domain = []
        # Only search into website_message_ids, so apply the same domain to perform only one search
        # extract domain from the 'website_message_ids' field
        field_domain = request.env[res_model]._fields['website_message_ids'].domain
        if callable(field_domain):
            field_domain = field_domain(request.env[res_model])
        domain = expression.AND([domain, field_domain, [('res_id', '=', res_id)]])

        # Check access
        Message = request.env['mail.message']
        if kw.get('token'):
            access_as_sudo = _has_token_access(res_model, res_id, token=kw.get('token'))
            if not access_as_sudo:  # if token is not correct, raise Forbidden
                raise Forbidden()
            # Non-employee see only messages with not internal subtype (aka, no internal logs)
            if not request.env['res.users'].has_group('base.group_user'):
                domain = expression.AND([['&', ('subtype_id', '!=', False), ('subtype_id.internal', '=', False)], domain])
            Message = request.env['mail.message'].sudo()
        return {
            'messages': Message.search(domain, limit=limit, offset=offset).portal_message_format(),
            'message_count': Message.search_count(domain)
        }
Example #8
0
 def name_search(self, name='', args=None, operator='ilike', limit=100):
     # TDE FIXME: currently overriding the domain; however as it includes a
     # search on a m2o and one on a m2m, probably this will quickly become
     # difficult to compute - check if performance optimization is required
     if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
         args = args or []
         domain = [
             '|', ('attribute_id', operator, name),
             ('value_ids', operator, name)
         ]
         return self.search(expression.AND([domain, args]),
                            limit=limit).name_get()
     return super(ProductAttributeLine, self).name_search(name=name,
                                                          args=args,
                                                          operator=operator,
                                                          limit=limit)
Example #9
0
    def mark_all_as_read(self, channel_ids=None, domain=None):
        """ Remove all needactions of the current partner. If channel_ids is
            given, restrict to messages written in one of those channels. """
        partner_id = self.env.user.partner_id.id
        delete_mode = not self.env.user.share  # delete employee notifs, keep customer ones
        if not domain and delete_mode:
            query = "DELETE FROM mail_message_res_partner_needaction_rel WHERE res_partner_id IN %s"
            args = [(partner_id,)]
            if channel_ids:
                query += """
                    AND mail_message_id in
                        (SELECT mail_message_id
                        FROM mail_message_mail_channel_rel
                        WHERE mail_channel_id in %s)"""
                args += [tuple(channel_ids)]
            query += " RETURNING mail_message_id as id"
            self._cr.execute(query, args)
            self.invalidate_cache()

            ids = [m['id'] for m in self._cr.dictfetchall()]
        else:
            # not really efficient method: it does one db request for the
            # search, and one for each message in the result set to remove the
            # current user from the relation.
            msg_domain = [('needaction_partner_ids', 'in', partner_id)]
            if channel_ids:
                msg_domain += [('channel_ids', 'in', channel_ids)]
            unread_messages = self.search(expression.AND([msg_domain, domain]))
            notifications = self.env['mail.notification'].sudo().search([
                ('mail_message_id', 'in', unread_messages.ids),
                ('res_partner_id', '=', self.env.user.partner_id.id),
                ('is_read', '=', False)])
            if delete_mode:
                notifications.unlink()
            else:
                notifications.write({'is_read': True})
            ids = unread_messages.mapped('id')

        notification = {'type': 'mark_as_read', 'message_ids': ids, 'channel_ids': channel_ids}
        self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', self.env.user.partner_id.id), notification)

        return ids
Example #10
0
    def _search(self,
                args,
                offset=0,
                limit=None,
                order=None,
                count=False,
                access_rights_uid=None):
        """ Override that adds specific access rights of mail.message, to restrict
        messages to published messages for public users. """
        if self.user_has_groups('base.group_public'):
            args = expression.AND([[('website_published', '=', True)],
                                   list(args)])

        return super(MailMessage,
                     self)._search(args,
                                   offset=offset,
                                   limit=limit,
                                   order=order,
                                   count=count,
                                   access_rights_uid=access_rights_uid)
Example #11
0
    def get_mention_suggestions(self, search, limit=8):
        """ Return 'limit'-first partners' id, name and email such that the name or email matches a
            'search' string. Prioritize users, and then extend the research to all partners. """
        search_dom = expression.OR([[('name', 'ilike', search)],
                                    [('email', 'ilike', search)]])
        fields = ['id', 'name', 'email']

        # Search users
        domain = expression.AND([[('user_ids.id', '!=', False)], search_dom])
        users = self.search_read(domain, fields, limit=limit)

        # Search partners if less than 'limit' users found
        partners = []
        if len(users) < limit:
            partners = self.search_read(search_dom, fields, limit=limit)
            # Remove duplicates
            partners = [
                p for p in partners
                if not len([u for u in users if u['id'] == p['id']])
            ]

        return [users, partners]
Example #12
0
 def _change_model_id(self):
     """Force domain for the `field_id` and `field_date_id` fields"""
     if not self.model_id:
         return {
             'domain': {
                 'field_id': expression.FALSE_DOMAIN,
                 'field_date_id': expression.FALSE_DOMAIN
             }
         }
     model_fields_domain = [('store', '=', True), '|',
                            ('model_id', '=', self.model_id.id),
                            ('model_id', 'in',
                             self.model_id.inherited_model_ids.ids)]
     model_date_fields_domain = expression.AND([[
         ('ttype', 'in', ('date', 'datetime'))
     ], model_fields_domain])
     return {
         'domain': {
             'field_id': model_fields_domain,
             'field_date_id': model_date_fields_domain
         }
     }
Example #13
0
    def _compute_domain(self, model_name, mode="read"):
        if mode not in self._MODES:
            raise ValueError('Invalid mode: %r' % (mode, ))

        if self._uid == SUPERUSER_ID:
            return None

        query = """ SELECT r.id FROM ir_rule r JOIN ir_model m ON (r.model_id=m.id)
                    WHERE m.model=%s AND r.active AND r.perm_{mode}
                    AND (r.id IN (SELECT rule_group_id FROM rule_group_rel rg
                                  JOIN res_groups_users_rel gu ON (rg.group_id=gu.gid)
                                  WHERE gu.uid=%s)
                         OR r.global)
                """.format(mode=mode)
        self._cr.execute(query, (model_name, self._uid))
        rule_ids = [row[0] for row in self._cr.fetchall()]
        if not rule_ids:
            return []

        # browse user and rules as SUPERUSER_ID to avoid access errors!
        eval_context = self._eval_context()
        user_groups = self.env.user.groups_id
        global_domains = []  # list of domains
        group_domains = []  # list of domains
        for rule in self.browse(rule_ids).sudo():
            # evaluate the domain for the current user
            dom = safe_eval(rule.domain_force,
                            eval_context) if rule.domain_force else []
            dom = expression.normalize_domain(dom)
            if not rule.groups:
                global_domains.append(dom)
            elif rule.groups & user_groups:
                group_domains.append(dom)

        # combine global domains and group domains
        return expression.AND(global_domains + [expression.OR(group_domains)])
Example #14
0
 def name_search(self, name='', args=None, operator='ilike', limit=100):
     if not args:
         args = []
     if name:
         positive_operators = ['=', 'ilike', '=ilike', 'like', '=like']
         products = self.env['product.product']
         if operator in positive_operators:
             products = self.search([('default_code', '=', name)] + args,
                                    limit=limit)
             if not products:
                 products = self.search([('barcode', '=', name)] + args,
                                        limit=limit)
         if not products and operator not in expression.NEGATIVE_TERM_OPERATORS:
             # Do not merge the 2 next lines into one single search, SQL search performance would be abysmal
             # on a database with thousands of matching products, due to the huge merge+unique needed for the
             # OR operator (and given the fact that the 'name' lookup results come from the ir.translation table
             # Performing a quick memory merge of ids in Python will give much better performance
             products = self.search(args +
                                    [('default_code', operator, name)],
                                    limit=limit)
             if not limit or len(products) < limit:
                 # we may underrun the limit because of dupes in the results, that's fine
                 limit2 = (limit - len(products)) if limit else False
                 products += self.search(args +
                                         [('name', operator, name),
                                          ('id', 'not in', products.ids)],
                                         limit=limit2)
         elif not products and operator in expression.NEGATIVE_TERM_OPERATORS:
             domain = expression.OR([
                 [
                     '&', ('default_code', operator, name),
                     ('name', operator, name)
                 ],
                 [
                     '&', ('default_code', '=', False),
                     ('name', operator, name)
                 ],
             ])
             domain = expression.AND([args, domain])
             products = self.search(domain, limit=limit)
         if not products and operator in positive_operators:
             ptrn = re.compile('(\[(.*?)\])')
             res = ptrn.search(name)
             if res:
                 products = self.search(
                     [('default_code', '=', res.group(2))] + args,
                     limit=limit)
         # still no results, partner in context: search on supplier info as last hope to find something
         if not products and self._context.get('partner_id'):
             suppliers = self.env['product.supplierinfo'].search([
                 ('name', '=', self._context.get('partner_id')), '|',
                 ('product_code', operator, name),
                 ('product_name', operator, name)
             ])
             if suppliers:
                 products = self.search(
                     [('product_tmpl_id.seller_ids', 'in', suppliers.ids)],
                     limit=limit)
     else:
         products = self.search(args, limit=limit)
     return products.name_get()
Example #15
0
 def plan(self, domain):
     domain = expression.AND([domain, [('project_id', '!=', False)]
                              ])  # force timesheet and not AAL
     values = self._prepare_plan_values(domain)
     view = request.env.ref('sale_timesheet.timesheet_plan')
     return {'html_content': view.render(values)}
Example #16
0
 def _analytic_compute_delivered_quantity_domain(self):
     domain = super(SaleOrderLine, self)._analytic_compute_delivered_quantity_domain()
     domain = expression.AND([domain, [('project_id', '=', False)]])
     timesheet_domain = self._timesheet_compute_delivered_quantity_domain()
     return expression.OR([domain, timesheet_domain])