def _link_timesheets_to_invoice(self, start_date=None, end_date=None): """ Search timesheets from given period and link this timesheets to the invoice When we create an invoice from a sale order, we need to link the timesheets in this sale order to the invoice. Then, we can know which timesheets are invoiced in the sale order. :param start_date: the start date of the period :param end_date: the end date of the period """ for line in self.filtered(lambda i: i.move_type == 'out_invoice' and i. state == 'draft').invoice_line_ids: sale_line_delivery = line.sale_line_ids.filtered( lambda sol: sol.product_id.invoice_policy == 'delivery' and sol .product_id.service_type == 'timesheet') if sale_line_delivery: domain = line._timesheet_domain_get_invoiced_lines( sale_line_delivery) if start_date: domain = expression.AND( [domain, [('date', '>=', start_date)]]) if end_date: domain = expression.AND( [domain, [('date', '<=', end_date)]]) timesheets = self.env['account.analytic.line'].sudo().search( domain) timesheets.write({'timesheet_invoice_id': line.move_id.id})
def activity_search(self, act_type_xmlids='', user_id=None, additional_domain=None): """ Search automated activities on current record set, given a list of activity types xml IDs. It is useful when dealing with specific types involved in automatic activities management. :param act_type_xmlids: list of activity types xml IDs :param user_id: if set, restrict to activities of that user_id; :param additional_domain: if set, filter on that domain; """ if self.env.context.get('mail_activity_automation_skip'): return False Data = self.env['ir.model.data'].sudo() activity_types_ids = [type_id for type_id in (Data.xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids) if type_id] if not any(activity_types_ids): return False domain = [ '&', '&', '&', ('res_model', '=', self._name), ('res_id', 'in', self.ids), ('automated', '=', True), ('activity_type_id', 'in', activity_types_ids) ] if user_id: domain = expression.AND([domain, [('user_id', '=', user_id)]]) if additional_domain: domain = expression.AND([domain, additional_domain]) return self.env['mail.activity'].search(domain)
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 _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 _recompute_qty_to_invoice(self, start_date, end_date): """ Recompute the qty_to_invoice field for product containing timesheets Search the existed timesheets between the given period in parameter. Retrieve the unit_amount of this timesheet and then recompute the qty_to_invoice for each current product. :param start_date: the start date of the period :param end_date: the end date of the period """ lines_by_timesheet = self.filtered( lambda sol: sol.product_id and sol.product_id. _is_delivered_timesheet()) domain = lines_by_timesheet._timesheet_compute_delivered_quantity_domain( ) domain = expression.AND([ domain, [ '|', ('timesheet_invoice_id', '=', False), ('timesheet_invoice_id.state', '=', 'cancel') ] ]) if start_date: domain = expression.AND([domain, [('date', '>=', start_date)]]) if end_date: domain = expression.AND([domain, [('date', '<=', end_date)]]) mapping = lines_by_timesheet.sudo( )._get_delivered_quantity_by_analytic(domain) for line in lines_by_timesheet: line.qty_to_invoice = mapping.get(line.id, 0.0)
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): args = args or [] if self.env.context.get('country_id'): args = expression.AND([ args, [('country_id', '=', self.env.context.get('country_id'))] ]) if operator == 'ilike' and not (name or '').strip(): first_domain = [] domain = [] else: first_domain = [('code', '=ilike', name)] domain = [('name', operator, name)] first_state_ids = self._search( expression.AND([first_domain, args]), limit=limit, access_rights_uid=name_get_uid) if first_domain else [] return list(first_state_ids) + [ state_id for state_id in self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid) if state_id not in first_state_ids ]
def _search_rule(self, route_ids, product_id, warehouse_id, 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 warehouse_id: domain = expression.AND([[ '|', ('warehouse_id', '=', warehouse_id.id), ('warehouse_id', '=', False) ], domain]) Rule = self.env['stock.rule'] res = self.env['stock.rule'] if route_ids: res = Rule.search(expression.AND([[('route_id', 'in', 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 = Rule.search(expression.AND([[ ('route_id', 'in', product_routes.ids) ], domain]), order='route_sequence, sequence', limit=1) if not res and warehouse_id: warehouse_routes = warehouse_id.route_ids if warehouse_routes: res = Rule.search(expression.AND([[ ('route_id', 'in', warehouse_routes.ids) ], domain]), order='route_sequence, sequence', limit=1) return res
def _domain_move_lines_for_manual_reconciliation(self, account_id, partner_id=False, excluded_ids=None, search_str=False): """ Create domain criteria that are relevant to manual reconciliation. """ domain = [ '&', '&', ('reconciled', '=', False), ('account_id', '=', account_id), '|', ('move_id.state', '=', 'posted'), '&', ('move_id.state', '=', 'draft'), ('move_id.journal_id.post_at', '=', 'bank_rec'), ] domain = expression.AND([domain, [('balance', '!=', 0.0)]]) if partner_id: domain = expression.AND( [domain, [('partner_id', '=', partner_id)]]) if excluded_ids: domain = expression.AND([[('id', 'not in', excluded_ids)], domain]) if search_str: str_domain = self._domain_move_lines(search_str=search_str) str_domain = expression.OR( [str_domain, [('partner_id.name', 'ilike', search_str)]]) domain = expression.AND([domain, str_domain]) # filter on account.move.line having the same company as the given account account = self.env['account.account'].browse(account_id) domain = expression.AND( [domain, [('company_id', '=', account.company_id.id)]]) return domain
def get_mention_suggestions(self, search, limit=8, channel_id=None): """ 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. If channel_id is given, only members of this channel are returned. """ search_dom = expression.OR([[('name', 'ilike', search)], [('email', 'ilike', search)]]) search_dom = expression.AND([[('active', '=', True), ('type', '!=', 'private')], search_dom]) if channel_id: search_dom = expression.AND([[('channel_ids', 'in', channel_id)], search_dom]) # Search users domain = expression.AND([[('user_ids.id', '!=', False), ('user_ids.active', '=', True)], search_dom]) users = self.search(domain, limit=limit) # Search partners if less than 'limit' users found partners = self.env['res.partner'] if len(users) < limit: partners = self.search(expression.AND([[('id', 'not in', users.ids) ], search_dom]), limit=limit) return [ [partner.mail_partner_format() for partner in users], [partner.mail_partner_format() for partner in partners], ]
def _compute_allowed_location_ids(self): loc_domain = [('usage', 'in', ('internal', 'view'))] # We want to keep only the locations # - strictly belonging to our warehouse # - not belonging to any warehouses for orderpoint in self: other_warehouses = self.env['stock.warehouse'].search([('id', '!=', orderpoint.warehouse_id.id)]) for view_location_id in other_warehouses.mapped('view_location_id'): loc_domain = expression.AND([loc_domain, ['!', ('id', 'child_of', view_location_id.id)]]) loc_domain = expression.AND([loc_domain, ['|', ('company_id', '=', False), ('company_id', '=', orderpoint.company_id.id)]]) orderpoint.allowed_location_ids = self.env['stock.location'].search(loc_domain)
def render_latest_posts(self, template, domain, limit=None, order='published_date desc'): dom = expression.AND([[('website_published', '=', True), ('post_date', '<=', fields.Datetime.now())], request.website.website_domain()]) if domain: dom = expression.AND([dom, domain]) posts = request.env['blog.post'].search(dom, limit=limit, order=order) return request.website.viewref(template)._render({'posts': posts})
def _get_inventory_kanban_domain(self): domain = [] if self.warehouse_ids: domain = expression.AND( (domain, [('warehouse_id', 'in', self.warehouse_ids.ids)])) if self.product_ids: domain = expression.AND( (domain, [('product_id', 'in', self.product_ids.ids)])) if self.location_ids: domain = expression.AND( (domain, [('location_id', 'in', self.location_ids.ids)])) return domain
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])
def _get_contracts(self, date_from, date_to, states=['open'], kanban_state=False): """ Returns the contracts of the employee between date_from and date_to """ state_domain = [('state', 'in', states)] if kanban_state: state_domain = expression.AND([state_domain, [('kanban_state', 'in', kanban_state)]]) return self.env['hr.contract'].search( expression.AND([[('employee_id', 'in', self.ids)], state_domain, [('date_start', '<=', date_to), '|', ('date_end', '=', False), ('date_end', '>=', date_from)]]))
def _compute_allowed_mo_ids(self): for unbuild in self: domain = [ ('state', '=', 'done'), ('company_id', '=', unbuild.company_id.id) ] if unbuild.bom_id: domain = expression.AND([domain, [('bom_id', '=', unbuild.bom_id.id)]]) elif unbuild.product_id: domain = expression.AND([domain, [('product_id', '=', unbuild.product_id.id)]]) allowed_mos = self.env['mrp.production'].search_read(domain, ['id']) if allowed_mos: unbuild.allowed_mo_ids = [mo['id'] for mo in allowed_mos] else: unbuild.allowed_mo_ids = False
def _get_event_track_visitors(self, force_create=False): self.ensure_one() force_visitor_create = self.env.user._is_public() visitor_sudo = self.env['website.visitor']._get_visitor_from_request( force_create=force_visitor_create) if visitor_sudo: visitor_sudo._update_visitor_last_visit() if self.env.user._is_public(): domain = [('visitor_id', '=', visitor_sudo.id)] elif visitor_sudo: domain = [ '|', ('partner_id', '=', self.env.user.partner_id.id), ('visitor_id', '=', visitor_sudo.id) ] else: domain = [('partner_id', '=', self.env.user.partner_id.id)] track_visitors = self.env['event.track.visitor'].sudo().search( expression.AND([domain, [('track_id', 'in', self.ids)]])) missing = self - track_visitors.track_id if missing and force_create: track_visitors += self.env['event.track.visitor'].sudo().create([{ 'visitor_id': visitor_sudo.id, 'partner_id': self.env.user.partner_id.id if not self.env.user._is_public() else False, 'track_id': track.id, } for track in missing]) return track_visitors
def _event_meeting_rooms_get_values(self, event, lang=None): search_domain = self._get_event_rooms_base_domain(event) meeting_rooms_all = request.env['event.meeting.room'].sudo().search( search_domain) if lang: search_domain = expression.AND( [search_domain, [('room_lang_id', '=', int(lang))]]) meeting_rooms = request.env['event.meeting.room'].sudo().search( search_domain) meeting_rooms = meeting_rooms.sorted(self._sort_event_rooms, reverse=True) is_event_manager = request.env.user.has_group( "event.group_event_manager") if not is_event_manager: meeting_rooms = meeting_rooms.filtered( lambda m: not m.room_is_full) visitor = request.env['website.visitor']._get_visitor_from_request() return { # event information "event": event.sudo(), 'main_object': event, # rooms "meeting_rooms": meeting_rooms, "current_lang": request.env["res.lang"].browse(int(lang)) if lang else False, "available_languages": meeting_rooms_all.mapped("room_lang_id"), "default_lang_code": request.context.get('lang', request.env.user.lang), "default_username": visitor.display_name if visitor else None, # environment "is_event_manager": is_event_manager, }
def _get_failing(self, for_records, mode='read'): """ Returns the rules for the mode for the current user which fail on the specified records. Can return any global rule and/or all local rules (since local rules are OR-ed together, the entire group succeeds or fails, while global rules get AND-ed and can each fail) """ Model = for_records.browse(()).sudo() eval_context = self._eval_context() all_rules = self._get_rules(Model._name, mode=mode).sudo() # first check if the group rules fail for any record (aka if # searching on (records, group_rules) filters out some of the records) group_rules = all_rules.filtered(lambda r: r.groups and r.groups & self.env.user.groups_id) group_domains = expression.OR([ safe_eval(r.domain_force, eval_context) if r.domain_force else [] for r in group_rules ]) # if all records get returned, the group rules are not failing if Model.search_count(expression.AND([[('id', 'in', for_records.ids)], group_domains])) == len(for_records): group_rules = self.browse(()) # failing rules are previously selected group rules or any failing global rule def is_failing(r, ids=for_records.ids): dom = safe_eval(r.domain_force, eval_context) if r.domain_force else [] return Model.search_count(expression.AND([ [('id', 'in', ids)], expression.normalize_domain(dom) ])) < len(ids) return all_rules.filtered(lambda r: r in group_rules or (not r.groups and is_failing(r))).with_user(self.env.user)
def _get_moves_to_assign_domain(self, company_id): moves_domain = [('state', 'in', ['confirmed', 'partially_available']), ('product_uom_qty', '!=', 0.0)] if company_id: moves_domain = expression.AND([[('company_id', '=', company_id)], moves_domain]) return moves_domain
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): if operator not in ('ilike', 'like', '=', '=like', '=ilike'): return super(AccountAnalyticAccount, self)._name_search(name, args, operator, limit, name_get_uid=name_get_uid) args = args or [] if operator == 'ilike' and not (name or '').strip(): domain = [] else: # `partner_id` is in auto_join and the searches using ORs with auto_join fields doesn't work # we have to cut the search in two searches ... https://github.com/flectra/flectra/issues/25175 partner_ids = self.env['res.partner']._search( [('name', operator, name)], limit=limit, access_rights_uid=name_get_uid) domain = [ '|', '|', ('code', operator, name), ('name', operator, name), ('partner_id', 'in', partner_ids) ] return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None): """ For expense, we want to show all sales order but only their name_get (no ir.rule applied), this is the only way to do it. """ if self._context.get('sale_expense_all_order'): domain = expression.AND([ args or [], [ '&', ('state', '=', 'sale'), ('company_id', 'in', self.env.companies.ids) ] ]) return super(SaleOrder, self.sudo())._name_search(name=name, args=domain, operator=operator, limit=limit, name_get_uid=SUPERUSER_ID) return super(SaleOrder, self)._name_search(name=name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
def _rating_get_repartition(self, add_stats=False, domain=None): """ get the repatition of rating grade for the given res_ids. :param add_stats : flag to add stat to the result :type add_stats : boolean :param domain : optional extra domain of the rating to include/exclude in repartition :return dictionnary if not add_stats, the dict is like - key is the rating value (integer) - value is the number of object (res_model, res_id) having the value otherwise, key is the value of the information (string) : either stat name (avg, total, ...) or 'repartition' containing the same dict if add_stats was False. """ base_domain = expression.AND( [self._rating_domain(), [('rating', '>=', 1)]]) if domain: base_domain += domain data = self.env['rating.rating'].read_group(base_domain, ['rating'], ['rating', 'res_id']) # init dict with all posible rate value, except 0 (no value for the rating) values = dict.fromkeys(range(1, 6), 0) values.update((d['rating'], d['rating_count']) for d in data) # add other stats if add_stats: rating_number = sum(values.values()) result = { 'repartition': values, 'avg': sum(float(key * values[key]) for key in values) / rating_number if rating_number > 0 else 0, 'total': sum(it['rating_count'] for it in data), } return result return values
def _filter_registrations(self, registrations): """ Keep registrations matching rule conditions. Those are * if a filter is set: filter registrations based on this filter. This is done like a search, and filter is a domain; * if a company is set on the rule, it must match event's company. Note that multi-company rules apply on event_lead_rule; * if an event category it set, it must match; * if an event is set, it must match; * if both event and category are set, one of them must match (OR). If none of those are set, it is considered as OK; :param registrations: event.registration recordset on which rule filters will be evaluated; :return: subset of registrations matching rules """ self.ensure_one() if self.event_registration_filter and self.event_registration_filter != '[]': registrations = registrations.search( expression.AND([[('id', 'in', registrations.ids)], literal_eval(self.event_registration_filter)])) # check from direct m2o to linked m2o / o2m to filter first without inner search company_ok = lambda registration: registration.company_id == self.company_id if self.company_id else True event_or_event_type_ok = \ lambda registration: \ registration.event_id == self.event_id or registration.event_id.event_type_id in self.event_type_ids \ if (self.event_id or self.event_type_ids) else True return registrations.filtered( lambda r: company_ok(r) and event_or_event_type_ok(r))
def _get_assets_domain_for_already_processed_css(self, assets): res = super(AssetsBundleMultiWebsite, self)._get_assets_domain_for_already_processed_css(assets) current_website = self.env['website'].get_current_website( fallback=False) res = expression.AND([res, current_website.website_domain()]) return res
def action_time_off_analysis(self): domain = [('holiday_type', '=', 'employee')] if self.env.context.get('active_ids'): domain = expression.AND([ domain, [('employee_id', 'in', self.env.context.get('active_ids', []))] ]) return { 'name': _('Time Off Analysis'), 'type': 'ir.actions.act_window', 'res_model': 'hr.leave.report', 'view_mode': 'tree,pivot,form', 'search_view_id': self.env.ref('hr_holidays.view_hr_holidays_filter_report').id, 'domain': domain, 'context': { 'search_default_group_type': True, 'search_default_year': True, 'search_default_validated': True, } }
def _check_current_contract(self): """ Two contracts in state [incoming | open | close] cannot overlap """ for contract in self.filtered(lambda c: ( c.state not in ['draft', 'cancel'] or c.state == 'draft' and c. kanban_state == 'done') and c.employee_id): domain = [ ('id', '!=', contract.id), ('employee_id', '=', contract.employee_id.id), '|', ('state', 'in', ['open', 'close']), '&', ('state', '=', 'draft'), ('kanban_state', '=', 'done') # replaces incoming ] if not contract.date_end: start_domain = [] end_domain = [ '|', ('date_end', '>=', contract.date_start), ('date_end', '=', False) ] else: start_domain = [('date_start', '<=', contract.date_end)] end_domain = [ '|', ('date_end', '>', contract.date_start), ('date_end', '=', False) ] domain = expression.AND([domain, start_domain, end_domain]) if self.search_count(domain): raise ValidationError( _('An employee can only have one contract at the same time. (Excluding Draft and Cancelled contracts)' ))
def _domain_project_id(self): domain = [('allow_timesheets', '=', True)] if not self.user_has_groups('hr_timesheet.group_timesheet_manager'): return expression.AND([domain, ['|', ('privacy_visibility', '!=', 'followers'), ('allowed_internal_user_ids', 'in', self.env.user.ids)] ]) return domain
def _get_quantities(self): """Return quantities group by product_id, location_id, lot_id, package_id and owner_id :return: a dict with keys as tuple of group by and quantity as value :rtype: dict """ self.ensure_one() if self.location_ids: domain_loc = [('id', 'child_of', self.location_ids.ids)] else: domain_loc = [('company_id', '=', self.company_id.id), ('usage', 'in', ['internal', 'transit'])] locations_ids = [l['id'] for l in self.env['stock.location'].search_read(domain_loc, ['id'])] domain = [('company_id', '=', self.company_id.id), ('quantity', '!=', '0'), ('location_id', 'in', locations_ids)] if self.prefill_counted_quantity == 'zero': domain.append(('product_id.active', '=', True)) if self.product_ids: domain = expression.AND([domain, [('product_id', 'in', self.product_ids.ids)]]) fields = ['product_id', 'location_id', 'lot_id', 'package_id', 'owner_id', 'quantity:sum'] group_by = ['product_id', 'location_id', 'lot_id', 'package_id', 'owner_id'] quants = self.env['stock.quant'].read_group(domain, fields, group_by, lazy=False) return {( quant['product_id'] and quant['product_id'][0] or False, quant['location_id'] and quant['location_id'][0] or False, quant['lot_id'] and quant['lot_id'][0] or False, quant['package_id'] and quant['package_id'][0] or False, quant['owner_id'] and quant['owner_id'][0] or False): quant['quantity'] for quant in quants }
def search_panel_select_range(self, field_name, **kwargs): if field_name == 'category_id': enable_counters = kwargs.get('enable_counters', False) domain = [('parent_id', '=', False), ('child_ids.module_ids', '!=', False)] excluded_xmlids = [ 'base.module_category_website_theme', 'base.module_category_theme', ] if not self.user_has_groups('base.group_no_one'): excluded_xmlids.append('base.module_category_hidden') excluded_category_ids = [] for excluded_xmlid in excluded_xmlids: categ = self.env.ref(excluded_xmlid, False) if not categ: continue excluded_category_ids.append(categ.id) if excluded_category_ids: domain = expression.AND([ domain, [('id', 'not in', excluded_category_ids)], ]) Module = self.env['ir.module.module'] records = self.env['ir.module.category'].search_read(domain, ['display_name'], order="sequence") values_range = OrderedDict() for record in records: record_id = record['id'] if enable_counters: model_domain = expression.AND([ kwargs.get('search_domain', []), kwargs.get('category_domain', []), kwargs.get('filter_domain', []), [('category_id', 'child_of', record_id), ('category_id', 'not in', excluded_category_ids)] ]) record['__count'] = Module.search_count(model_domain) values_range[record_id] = record return { 'parent_field': 'parent_id', 'values': list(values_range.values()), } return super(Module, self).search_panel_select_range(field_name, **kwargs)
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'])