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
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
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)])
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'])
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)
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
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)
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]) return self.search(domain, order=removal_strategy_order)
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]
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 domain += field_domain(request.env[res_model]) if callable(field_domain) else field_domain 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) }
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 } }
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)}