Beispiel #1
0
    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})
Beispiel #2
0
    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)
Beispiel #3
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
Beispiel #4
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
Beispiel #5
0
    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)
Beispiel #6
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
        ]
Beispiel #7
0
 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
Beispiel #8
0
 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
Beispiel #9
0
    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],
        ]
Beispiel #10
0
 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)
Beispiel #11
0
 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})
Beispiel #12
0
 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
Beispiel #13
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])
Beispiel #14
0
    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)]]))
Beispiel #15
0
 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
Beispiel #16
0
    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
Beispiel #17
0
    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,
        }
Beispiel #18
0
    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)
Beispiel #19
0
 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
Beispiel #20
0
 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)
Beispiel #21
0
 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)
Beispiel #22
0
 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
Beispiel #23
0
    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))
Beispiel #24
0
 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
Beispiel #25
0
    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,
            }
        }
Beispiel #26
0
    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)'
                      ))
Beispiel #27
0
 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
Beispiel #28
0
    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
        }
Beispiel #29
0
    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)
Beispiel #30
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'])