예제 #1
0
 def _search_full_name(self, operator, operand):
     lst = True
     if isinstance(operand, bool):
         domains = [[('name', operator, operand)],
                    [('category_id.name', operator, operand)]]
         if operator in expression.NEGATIVE_TERM_OPERATORS == (not operand):
             return expression.AND(domains)
         else:
             return expression.OR(domains)
     if isinstance(operand, pycompat.string_types):
         lst = False
         operand = [operand]
     where = []
     for group in operand:
         values = [v for v in group.split('/') if v]
         group_name = values.pop().strip()
         category_name = values and '/'.join(values).strip() or group_name
         group_domain = [('name', operator, lst and [group_name]
                          or group_name)]
         category_domain = [('category_id.name', operator,
                             lst and [category_name] or category_name)]
         if operator in expression.NEGATIVE_TERM_OPERATORS and not values:
             category_domain = expression.OR(
                 [category_domain, [('category_id', '=', False)]])
         if (operator
                 in expression.NEGATIVE_TERM_OPERATORS) == (not values):
             sub_where = expression.AND([group_domain, category_domain])
         else:
             sub_where = expression.OR([group_domain, category_domain])
         if operator in expression.NEGATIVE_TERM_OPERATORS:
             where = expression.AND([where, sub_where])
         else:
             where = expression.OR([where, sub_where])
     return where
예제 #2
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
예제 #3
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()
예제 #4
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],
        ]
예제 #5
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
예제 #6
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)
예제 #7
0
 def _get_search_domain(self, search_in, search):
     search_domain = super()._get_search_domain(search_in, search)
     if search_in in ('sol', 'all'):
         search_domain = expression.OR(
             [search_domain, [('so_line', 'ilike', search)]])
     if search_in in ('sol_id', 'invoice_id'):
         search = int(search) if search.isdigit() else 0
     if search_in == 'sol_id':
         search_domain = expression.OR(
             [search_domain, [('so_line.id', '=', search)]])
     if search_in == 'invoice_id':
         invoice = request.env['account.move'].browse(search)
         domain = request.env[
             'account.analytic.line']._timesheet_get_sale_domain(
                 invoice.mapped('invoice_line_ids.sale_line_ids'), invoice)
         search_domain = expression.OR([search_domain, domain])
     return search_domain
예제 #8
0
 def _any_is_configured(self, company_id):
     domain = expression.OR([[
         ('property_tax_payable_account_id', '!=', False)
     ], [('property_tax_receivable_account_id', '!=', False)],
                             [('property_advance_tax_payment_account_id',
                               '!=', False)]])
     group_with_config = self.with_company(company_id).search_count(domain)
     return group_with_config > 0
예제 #9
0
 def _search_ids(model, values):
     ids = set()
     domain = []
     for item in values:
         if isinstance(item, int):
             ids.add(item)
         else:
             domain = expression.OR([[('name', 'ilike', item)], domain])
     if domain:
         ids |= set(self.env[model].search(domain).ids)
     return ids
예제 #10
0
 def get_mention_suggestions(self, search, limit=8):
     """ Return 'limit'-first channels' id, name and public fields such that the name matches a
         'search' string. Exclude channels of type chat (DM), and private channels the current
         user isn't registered to. """
     domain = expression.AND([[('name', 'ilike', search)],
                              [('channel_type', '=', 'channel')],
                              expression.OR(
                                  [[('public', '!=', 'private')],
                                   [('channel_partner_ids', 'in',
                                     [self.env.user.partner_id.id])]])])
     return self.search_read(domain, ['id', 'name', 'public'], limit=limit)
예제 #11
0
    def _retrieve_partner(self, name=None, phone=None, mail=None, vat=None):
        '''Search all partners and find one that matches one of the parameters.

        :param name:    The name of the partner.
        :param phone:   The phone or mobile of the partner.
        :param mail:    The mail of the partner.
        :param vat:     The vat number of the partner.
        :returns:       A partner or an empty recordset if not found.
        '''
        domains = []
        for value, domain in (
            (name, [('name', 'ilike', name)]),
            (phone, expression.OR([[('phone', '=', phone)], [('mobile', '=', phone)]])),
            (mail, [('email', '=', mail)]),
            (vat, [('vat', 'like', vat)]),
        ):
            if value is not None:
                domains.append(domain)

        domain = expression.OR(domains)
        return self.env['res.partner'].search(domain, limit=1)
예제 #12
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()
예제 #13
0
 def _count_attachments(self):
     domains = [[('res_model', '=', 'account.move'),
                 ('res_id', '=', self.id)]]
     statement_ids = self.line_ids.mapped('statement_id')
     payment_ids = self.line_ids.mapped('payment_id')
     if statement_ids:
         domains.append([('res_model', '=', 'account.bank.statement'),
                         ('res_id', 'in', statement_ids)])
     if payment_ids:
         domains.append([('res_model', '=', 'account.payment'),
                         ('res_id', 'in', payment_ids)])
     return self.env['ir.attachment'].search_count(expression.OR(domains))
예제 #14
0
        def search_with_phone_mail(extra_domain):
            domains = []
            if phone:
                domains.append([('phone', '=', phone)])
                domains.append([('mobile', '=', phone)])
            if mail:
                domains.append([('email', '=', mail)])

            if not domains:
                return None

            domain = expression.OR(domains)
            if extra_domain:
                domain = expression.AND([domain, extra_domain])
            return self.env['res.partner'].search(domain, limit=1)
예제 #15
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)
                                    ],
                               ])])
예제 #16
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()
예제 #17
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)]])
예제 #18
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)]])
예제 #19
0
파일: product.py 프로젝트: mausvt/flectra
 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 = list(self._search([('default_code', '=', name)] + args, limit=limit, access_rights_uid=name_get_uid))
             if not product_ids:
                 product_ids = list(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 = list(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 = list(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 = list(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 product_ids
예제 #20
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),
                  ('company_id', 'in', [False] + self.env.companies.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])

        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
예제 #21
0
    def get_mention_suggestions(self, search, limit=8):
        """ Return 'limit'-first partners' id, name and email such that the name or email matches a
            'search' string. Prioritize users, and then extend the research to all partners. """
        search_dom = expression.OR([[('name', 'ilike', search)], [('email', 'ilike', search)]])
        fields = ['id', 'name', 'email']

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

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

        return [users, partners]
예제 #22
0
    def _get_quantity_in_progress(self, location_ids=False, warehouse_ids=False):
        if not location_ids:
            location_ids = []
        if not warehouse_ids:
            warehouse_ids = []

        qty_by_product_location, qty_by_product_wh = super()._get_quantity_in_progress(location_ids, warehouse_ids)
        domain = []
        rfq_domain = [
            ('state', 'in', ('draft', 'sent', 'to approve')),
            ('product_id', 'in', self.ids)
        ]
        if location_ids:
            domain = expression.AND([rfq_domain, [
                '|',
                    ('order_id.picking_type_id.default_location_dest_id', 'in', location_ids),
                    '&',
                        ('move_dest_ids', '=', False),
                        ('orderpoint_id.location_id', 'in', location_ids)
            ]])
        if warehouse_ids:
            wh_domain = expression.AND([rfq_domain, [
                '|',
                    ('order_id.picking_type_id.warehouse_id', 'in', warehouse_ids),
                    '&',
                        ('move_dest_ids', '=', False),
                        ('orderpoint_id.warehouse_id', 'in', warehouse_ids)
            ]])
            domain = expression.OR([domain, wh_domain])
        groups = self.env['purchase.order.line'].read_group(domain,
            ['product_id', 'product_qty', 'order_id', 'product_uom', 'orderpoint_id'],
            ['order_id', 'product_id', 'product_uom', 'orderpoint_id'], lazy=False)
        for group in groups:
            if group.get('orderpoint_id'):
                location = self.env['stock.warehouse.orderpoint'].browse(group['orderpoint_id'][:1]).location_id
            else:
                order = self.env['purchase.order'].browse(group['order_id'][0])
                location = order.picking_type_id.default_location_dest_id
            product = self.env['product.product'].browse(group['product_id'][0])
            uom = self.env['uom.uom'].browse(group['product_uom'][0])
            product_qty = uom._compute_quantity(group['product_qty'], product.uom_id, round=False)
            qty_by_product_location[(product.id, location.id)] += product_qty
            qty_by_product_wh[(product.id, location.get_warehouse().id)] += product_qty
        return qty_by_product_location, qty_by_product_wh
예제 #23
0
    def _retrieve_product(self, name=None, default_code=None, barcode=None):
        '''Search all products and find one that matches one of the parameters.

        :param name:            The name of the product.
        :param default_code:    The default_code of the product.
        :param barcode:         The barcode of the product.
        :returns:               A product or an empty recordset if not found.
        '''
        domains = []
        for value, domain in (
            (name, ('name', 'ilike', name)),
            (default_code, ('default_code', '=', default_code)),
            (barcode, ('barcode', '=', barcode)),
        ):
            if value is not None:
                domains.append([domain])

        domain = expression.OR(domains)
        return self.env['product.product'].search(domain, limit=1)
예제 #24
0
 def action_customize_digest_remove(self):
     ir_model_fields_obj = self.env['ir.model.fields']
     ir_ui_view_obj = self.env['ir.ui.view']
     if self.remove_type == 'group':
         find_view_id = self.available_group_name \
                     and self.available_group_name.split('_', 1)[0] or False
         view_ids = ir_ui_view_obj.search([
             ('inherit_id', 'child_of', int(find_view_id))],
             order="id desc")
         field_list = []
         for view_id in view_ids:
             root = ET.fromstring(view_id.arch_base)
             for child in root.iter('group'):
                 name = child.find('field')
                 if name.attrib and name.attrib.get('name', False):
                     field_list.append(name.attrib.get('name', False))
         field_ids = ir_model_fields_obj.search([
             ('name', 'in', field_list)])
         view_ids.unlink()
         for field_id in field_ids:
             ir_model_fields_obj.search([
                 ('depends', '=', field_id.name)]).unlink()
         field_ids.unlink()
     else:
         domain = expression.OR([('arch_db', 'like', record.name)
                                 ] for record in self.field_id)
         view_ids = ir_ui_view_obj.search(domain)
         for view_id in view_ids:
             root = ET.fromstring(view_id.arch_base)
             for child in root.iter('field'):
                 if child.attrib and child.attrib.get(
                         'name', False) == self.field_id.name:
                     view_id.unlink()
         ir_model_fields_obj.search([
             ('depends', '=', self.field_id.name)]).unlink()
         self.field_id.unlink()
     return {
         'type': 'ir.actions.client',
         'tag': 'reload',
     }
예제 #25
0
    def test_bundle_sends_bus(self):
        """
        Tests two things:
        - Messages are posted to the bus when assets change
          i.e. their hash has been recomputed and differ from the attachment's
        - The interface deals with those bus messages by displaying one notification
        """
        db_name = self.env.registry.db_name
        bundle_xml_ids = ('web.assets_common', 'web.assets_backend')

        domain = []
        for bundle in bundle_xml_ids:
            domain = expression.OR([
                domain,
                [('name', 'ilike', bundle + '%')]
            ])
        # start from a clean slate
        self.env['ir.attachment'].search(domain).unlink()
        self.env.registry._clear_cache()

        sendones = []
        def patched_sendone(self, channel, message):
            """
            Control API and number of messages posted to the bus
            """
            sendones.append((channel, message))

        self.patch(type(self.env['bus.bus']), 'sendone', patched_sendone)

        self.start_tour('/web', "bundle_changed_notification", login='******', timeout=180)

        # One sendone for each asset bundle and for each CSS / JS
        self.assertEqual(len(sendones), 4)
        for sent in sendones:
            channel = sent[0]
            message = sent[1]
            self.assertEqual(channel, (db_name, 'bundle_changed'))
            self.assertEqual(len(message), 2)
            self.assertTrue(message[0] in bundle_xml_ids)
            self.assertTrue(isinstance(message[1], str))
예제 #26
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(
        )
        refund_account_moves = self.order_id.invoice_ids.filtered(
            lambda am: am.state == 'posted' and am.move_type == 'out_refund'
        ).reversed_entry_id
        timesheet_domain = [
            '|', ('timesheet_invoice_id', '=', False),
            ('timesheet_invoice_id.state', '=', 'cancel')
        ]
        if refund_account_moves:
            credited_timesheet_domain = [
                ('timesheet_invoice_id.state', '=', 'posted'),
                ('timesheet_invoice_id', 'in', refund_account_moves.ids)
            ]
            timesheet_domain = expression.OR(
                [timesheet_domain, credited_timesheet_domain])
        domain = expression.AND([domain, timesheet_domain])
        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 _get_ranges(self):
     domain_1 = [
         '&',
         ('type_id', '=', self.date_range_type_id.id),
         '|',
         '&',
         ('date_start', '>=', self.date_start),
         ('date_start', '<=', self.date_end),
         '&',
         ('date_end', '>=', self.date_start),
         ('date_end', '<=', self.date_end),
     ]
     domain_2 = [
         '&',
         ('type_id', '=', self.date_range_type_id.id),
         '&',
         ('date_start', '<=', self.date_start),
         ('date_end', '>=', self.date_start),
     ]
     domain = expression.OR([domain_1, domain_2])
     ranges = self.env['date.range'].search(domain)
     return ranges
예제 #28
0
    def _compute_domain(self, model_name, mode="read"):
        if mode not in self._MODES:
            raise ValueError('Invalid mode: %r' % (mode, ))

        if self._uid == SUPERUSER_ID:
            return None

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

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

        # combine global domains and group domains
        if not group_domains:
            return expression.AND(global_domains)
        return expression.AND(global_domains + [expression.OR(group_domains)])
예제 #29
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)])
예제 #30
0
 def _analytic_compute_delivered_quantity_domain(self):
     domain = super(SaleOrderLine, self)._analytic_compute_delivered_quantity_domain()
     domain = expression.AND([domain, [('project_id', '=', False)]])
     timesheet_domain = self._timesheet_compute_delivered_quantity_domain()
     return expression.OR([domain, timesheet_domain])