Ejemplo n.º 1
0
 def _domain_move_lines(self, search_str):
     """ Returns the domain from the search_str search
         :param search_str: search string
     """
     if not search_str:
         return []
     str_domain = self._str_domain_for_mv_line(search_str)
     if search_str[0] in ['-', '+']:
         try:
             amounts_str = search_str.split('|')
             for amount_str in amounts_str:
                 amount = amount_str[0] == '-' and float(
                     amount_str) or float(amount_str[1:])
                 amount_domain = [
                     '|',
                     ('amount_residual', '=', amount),
                     '|',
                     ('amount_residual_currency', '=', amount),
                     '|',
                     (amount_str[0] == '-' and 'credit'
                      or 'debit', '=', float(amount_str[1:])),
                     ('amount_currency', '=', amount),
                 ]
                 str_domain = expression.OR([str_domain, amount_domain])
         except:
             pass
     else:
         try:
             amount = float(search_str)
             amount_domain = [
                 '|',
                 ('amount_residual', '=', amount),
                 '|',
                 ('amount_residual_currency', '=', amount),
                 '|',
                 ('amount_residual', '=', -amount),
                 '|',
                 ('amount_residual_currency', '=', -amount),
                 '&',
                 ('account_id.internal_type', '=', 'liquidity'),
                 '|',
                 '|',
                 '|',
                 ('debit', '=', amount),
                 ('credit', '=', amount),
                 ('amount_currency', '=', amount),
                 ('amount_currency', '=', -amount),
             ]
             str_domain = expression.OR([str_domain, amount_domain])
         except:
             pass
     return str_domain
Ejemplo n.º 2
0
    def _remove_membership(self, partner_ids):
        """ Unlink (!!!) the relationships between the passed partner_ids
        and the channels and their slides (done in the unlink of slide.channel.partner model).
        Remove earned karma when completed quizz """
        if not partner_ids:
            raise ValueError(
                "Do not use this method with an empty partner_id recordset")

        earned_karma = self._get_earned_karma(partner_ids)
        users = self.env['res.users'].sudo().search([
            ('partner_id', 'in', list(earned_karma)),
        ])
        for user in users:
            if earned_karma[user.partner_id.id]:
                user.add_karma(-1 * earned_karma[user.partner_id.id])

        removed_channel_partner_domain = []
        for channel in self:
            removed_channel_partner_domain = expression.OR([
                removed_channel_partner_domain,
                [('partner_id', 'in', partner_ids),
                 ('channel_id', '=', channel.id)]
            ])
        self.message_unsubscribe(partner_ids=partner_ids)

        if removed_channel_partner_domain:
            self.env['slide.channel.partner'].sudo().search(
                removed_channel_partner_domain).unlink()
Ejemplo n.º 3
0
    def _search_available_today(self, operator, value):
        if (not operator in ['=', '!=']) or (not value in [True, False]):
            return []

        searching_for_true = (operator == '=' and value) or (operator == '!=' and not value)
        today = fields.Date.context_today(self)
        fieldname = 'recurrency_%s' % (WEEKDAY_TO_NAME[today.weekday()])

        return expression.AND([
            [(fieldname, operator, value)],
            expression.OR([
                [('until', '=', False)],
                [('until', '>' if searching_for_true else '<', today)],
            ])
        ])
Ejemplo n.º 4
0
 def unlink(self):
     """
     Override unlink method :
     Remove attendee from a channel, then also remove slide.slide.partner related to.
     """
     removed_slide_partner_domain = []
     for channel_partner in self:
         # find all slide link to the channel and the partner
         removed_slide_partner_domain = expression.OR([
             removed_slide_partner_domain,
             [('partner_id', '=', channel_partner.partner_id.id),
              ('slide_id', 'in', channel_partner.channel_id.slide_ids.ids)]
         ])
     if removed_slide_partner_domain:
         self.env['slide.slide.partner'].search(
             removed_slide_partner_domain).unlink()
     return super(ChannelUsersRelation, self).unlink()
Ejemplo n.º 5
0
    def _search_is_available_at(self, operator, value):
        supported_operators = ['in', 'not in', '=', '!=']

        if not operator in supported_operators:
            return expression.TRUE_DOMAIN

        if isinstance(value, int):
            value = [value]

        if operator in expression.NEGATIVE_TERM_OPERATORS:
            return expression.AND([[
                ('supplier_id.available_location_ids', 'not in', value)
            ], [('supplier_id.available_location_ids', '!=', False)]])

        return expression.OR([[
            ('supplier_id.available_location_ids', 'in', value)
        ], [('supplier_id.available_location_ids', '=', False)]])
Ejemplo n.º 6
0
    def _remove_copied_views(self):
        """ Remove the copies of the views installed by the modules in `self`.

        Those copies do not have an external id so they will not be cleaned by
        `_module_data_uninstall`. This is why we rely on `key` instead.

        It is important to remove these copies because using them will crash if
        they rely on data that don't exist anymore if the module is removed.
        """
        domain = expression.OR([[('key', '=like', m.name + '.%')]
                                for m in self])
        orphans = self.env['ir.ui.view'].with_context(
            **{
                'active_test': False,
                MODULE_UNINSTALL_FLAG: True
            }).search(domain)
        orphans.unlink()
Ejemplo n.º 7
0
    def _search_available_today(self, operator, value):
        if (not operator in ['=', '!=']) or (not value in [True, False]):
            return []

        searching_for_true = (operator == '=' and value) or (operator == '!='
                                                             and not value)

        now = fields.Datetime.now().replace(tzinfo=pytz.UTC).astimezone(
            pytz.timezone(self.env.user.tz or 'UTC'))
        fieldname = 'recurrency_%s' % (WEEKDAY_TO_NAME[now.weekday()])

        recurrency_domain = expression.OR([[
            ('recurrency_end_date', '=', False)
        ], [('recurrency_end_date', '>' if searching_for_true else '<', now)]])

        return expression.AND(
            [recurrency_domain, [(fieldname, operator, value)]])
Ejemplo n.º 8
0
    def _compute_debit_credit_balance(self):
        Curr = self.env['res.currency']
        analytic_line_obj = self.env['account.analytic.line']
        domain = [('account_id', 'in', self.ids)]
        if self._context.get('from_date', False):
            domain.append(('date', '>=', self._context['from_date']))
        if self._context.get('to_date', False):
            domain.append(('date', '<=', self._context['to_date']))
        if self._context.get('tag_ids'):
            tag_domain = expression.OR([[('tag_ids', 'in', [tag])]
                                        for tag in self._context['tag_ids']])
            domain = expression.AND([domain, tag_domain])
        if self._context.get('company_ids'):
            domain.append(('company_id', 'in', self._context['company_ids']))

        user_currency = self.env.company.currency_id
        credit_groups = analytic_line_obj.read_group(
            domain=domain + [('amount', '>=', 0.0)],
            fields=['account_id', 'currency_id', 'amount'],
            groupby=['account_id', 'currency_id'],
            lazy=False,
        )
        data_credit = defaultdict(float)
        for l in credit_groups:
            data_credit[l['account_id'][0]] += Curr.browse(
                l['currency_id'][0])._convert(l['amount'], user_currency,
                                              self.env.company,
                                              fields.Date.today())

        debit_groups = analytic_line_obj.read_group(
            domain=domain + [('amount', '<', 0.0)],
            fields=['account_id', 'currency_id', 'amount'],
            groupby=['account_id', 'currency_id'],
            lazy=False,
        )
        data_debit = defaultdict(float)
        for l in debit_groups:
            data_debit[l['account_id'][0]] += Curr.browse(
                l['currency_id'][0])._convert(l['amount'], user_currency,
                                              self.env.company,
                                              fields.Date.today())

        for account in self:
            account.debit = abs(data_debit.get(account.id, 0.0))
            account.credit = data_credit.get(account.id, 0.0)
            account.balance = account.credit - account.debit
Ejemplo n.º 9
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)
Ejemplo n.º 10
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)]])
        search_dom = expression.AND([[('active', '=', True)], search_dom])
        fields = ['id', 'name', 'email']

        # Search users
        domain = expression.AND([[('user_ids.id', '!=', False),
                                  ('user_ids.active', '=', True)], 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]
Ejemplo n.º 11
0
    def _compute_domain(self, model_name, mode="read"):
        rules = self._get_rules(model_name, mode=mode)
        if not rules:
            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 rules.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
        if not group_domains:
            return expression.AND(global_domains)
        return expression.AND(global_domains + [expression.OR(group_domains)])
Ejemplo n.º 12
0
    def _domain_move_lines_for_reconciliation(self,
                                              st_line,
                                              aml_accounts,
                                              partner_id,
                                              excluded_ids=[],
                                              search_str=False,
                                              mode='rp'):
        """ Return the domain for account.move.line records which can be used for bank statement reconciliation.

            :param aml_accounts:
            :param partner_id:
            :param excluded_ids:
            :param search_str:
            :param mode: 'rp' for receivable/payable or 'other'
        """
        AccountMoveLine = self.env['account.move.line']

        #Always exclude the journal items that have been marked as 'to be checked' in a former bank statement reconciliation
        to_check_excluded = AccountMoveLine.search(
            AccountMoveLine._get_suspense_moves_domain()).ids
        excluded_ids.extend(to_check_excluded)

        domain_reconciliation = [
            '&',
            '&',
            '&',
            ('statement_line_id', '=', False),
            ('account_id', 'in', aml_accounts),
            ('payment_id', '<>', False),
            ('balance', '!=', 0.0),
        ]

        # default domain matching
        domain_matching = [
            '&',
            '&',
            ('reconciled', '=', False),
            ('account_id.reconcile', '=', True),
            ('balance', '!=', 0.0),
        ]

        domain = expression.OR([domain_reconciliation, domain_matching])
        if partner_id:
            domain = expression.AND(
                [domain, [('partner_id', '=', partner_id)]])
        if mode == 'rp':
            domain = expression.AND([
                domain,
                [('account_id.internal_type', 'in',
                  ['receivable', 'payable', 'liquidity'])]
            ])
        else:
            domain = expression.AND([
                domain,
                [('account_id.internal_type', 'not in',
                  ['receivable', 'payable', 'liquidity'])]
            ])

        # Domain factorized for all reconciliation use cases
        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])

        if excluded_ids:
            domain = expression.AND([[('id', 'not in', excluded_ids)], domain])
        # filter on account.move.line having the same company as the statement line
        domain = expression.AND(
            [domain, [('company_id', '=', st_line.company_id.id)]])

        # take only moves in valid state. Draft is accepted only when "Post At" is set
        # to "Bank Reconciliation" in the associated journal
        domain_post_at = [
            '|',
            '&',
            ('move_id.state', '=', 'draft'),
            ('journal_id.post_at', '=', 'bank_rec'),
            ('move_id.state', 'not in', ['draft', 'cancel']),
        ]
        domain = expression.AND([domain, domain_post_at])

        if st_line.company_id.account_bank_reconciliation_start:
            domain = expression.AND([
                domain,
                [('date', '>=',
                  st_line.company_id.account_bank_reconciliation_start)]
            ])
        return domain
Ejemplo n.º 13
0
 def _name_search(self,
                  name,
                  args=None,
                  operator='ilike',
                  limit=100,
                  name_get_uid=None):
     if not args:
         args = []
     if name:
         positive_operators = ['=', 'ilike', '=ilike', 'like', '=like']
         product_ids = []
         if operator in positive_operators:
             product_ids = self._search([('default_code', '=', name)] +
                                        args,
                                        limit=limit,
                                        access_rights_uid=name_get_uid)
             if not product_ids:
                 product_ids = self._search([('barcode', '=', name)] + args,
                                            limit=limit,
                                            access_rights_uid=name_get_uid)
         if not product_ids 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
             product_ids = self._search(args +
                                        [('default_code', operator, name)],
                                        limit=limit)
             if not limit or len(product_ids) < limit:
                 # we may underrun the limit because of dupes in the results, that's fine
                 limit2 = (limit - len(product_ids)) if limit else False
                 product2_ids = self._search(
                     args + [('name', operator, name),
                             ('id', 'not in', product_ids)],
                     limit=limit2,
                     access_rights_uid=name_get_uid)
                 product_ids.extend(product2_ids)
         elif not product_ids 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])
             product_ids = self._search(domain,
                                        limit=limit,
                                        access_rights_uid=name_get_uid)
         if not product_ids and operator in positive_operators:
             ptrn = re.compile('(\[(.*?)\])')
             res = ptrn.search(name)
             if res:
                 product_ids = self._search(
                     [('default_code', '=', res.group(2))] + args,
                     limit=limit,
                     access_rights_uid=name_get_uid)
         # still no results, partner in context: search on supplier info as last hope to find something
         if not product_ids and self._context.get('partner_id'):
             suppliers_ids = self.env['product.supplierinfo']._search(
                 [('name', '=', self._context.get('partner_id')), '|',
                  ('product_code', operator, name),
                  ('product_name', operator, name)],
                 access_rights_uid=name_get_uid)
             if suppliers_ids:
                 product_ids = self._search(
                     [('product_tmpl_id.seller_ids', 'in', suppliers_ids)],
                     limit=limit,
                     access_rights_uid=name_get_uid)
     else:
         product_ids = self._search(args,
                                    limit=limit,
                                    access_rights_uid=name_get_uid)
     return models.lazy_name_get(
         self.browse(product_ids).with_user(name_get_uid))
Ejemplo n.º 14
0
 def _default_sale_line_domain(self):
     domain = super(AccountAnalyticLine, self)._default_sale_line_domain()
     return expression.OR([domain, [('qty_delivered_method', '=', 'timesheet')]])