Пример #1
0
 def compute_all(self,
                 price_unit,
                 currency=None,
                 quantity=1.0,
                 product=None,
                 partner=None):
     taxes = self.filtered(lambda r: r.amount_type != 'code')
     company = self.env.user.company_id
     for tax in self.filtered(lambda r: r.amount_type == 'code'):
         localdict = {
             'price_unit': price_unit,
             'quantity': quantity,
             'product': product,
             'partner': partner,
             'company': company
         }
         safe_eval(tax.python_applicable,
                   localdict,
                   mode="exec",
                   nocopy=True)
         if localdict.get('result', False):
             taxes += tax
     return super(AccountTaxPython,
                  taxes).compute_all(price_unit, currency, quantity,
                                     product, partner)
Пример #2
0
 def compute_all(self,
                 price_unit,
                 currency=None,
                 quantity=1.0,
                 product=None,
                 partner=None,
                 is_refund=False,
                 handle_price_include=True):
     taxes = self.filtered(lambda r: r.amount_type != 'code')
     company = self.env.company
     if product and product._name == 'product.template':
         product = product.product_variant_id
     for tax in self.filtered(lambda r: r.amount_type == 'code'):
         localdict = self._context.get('tax_computation_context', {})
         localdict.update({
             'price_unit': price_unit,
             'quantity': quantity,
             'product': product,
             'partner': partner,
             'company': company
         })
         safe_eval(tax.python_applicable,
                   localdict,
                   mode="exec",
                   nocopy=True)
         if localdict.get('result', False):
             taxes += tax
     return super(AccountTaxPython, taxes).compute_all(
         price_unit,
         currency,
         quantity,
         product,
         partner,
         is_refund=is_refund,
         handle_price_include=handle_price_include)
Пример #3
0
 def _compute_rule(self, localdict):
     """
     :param localdict: dictionary containing the environement in which to compute the rule
     :return: returns a tuple build as the base/amount computed, the quantity and the rate
     :rtype: (float, float, float)
     """
     self.ensure_one()
     if self.amount_select == 'fix':
         try:
             return self.amount_fix, float(safe_eval(self.quantity, localdict)), 100.0
         except:
             raise UserError(_('Wrong quantity defined for salary rule %s (%s).') % (self.name, self.code))
     elif self.amount_select == 'percentage':
         try:
             return (float(safe_eval(self.amount_percentage_base, localdict)),
                     float(safe_eval(self.quantity, localdict)),
                     self.amount_percentage)
         except:
             raise UserError(_('Wrong percentage base or quantity defined for salary rule %s (%s).') % (self.name, self.code))
     else:
         try:
             safe_eval(self.amount_python_compute, localdict, mode='exec', nocopy=True)
             return float(localdict['result']), 'result_qty' in localdict and localdict['result_qty'] or 1.0, 'result_rate' in localdict and localdict['result_rate'] or 100.0
         except:
             raise UserError(_('Wrong python code defined for salary rule %s (%s).') % (self.name, self.code))
Пример #4
0
 def get_google_drive_config(self, res_model, res_id):
     '''
     Function called by the js, when no google doc are yet associated with a record, with the aim to create one. It
     will first seek for a google.docs.config associated with the model `res_model` to find out what's the template
     of google doc to copy (this is usefull if you want to start with a non-empty document, a type or a name
     different than the default values). If no config is associated with the `res_model`, then a blank text document
     with a default name is created.
       :param res_model: the object for which the google doc is created
       :param ids: the list of ids of the objects for which the google doc is created. This list is supposed to have
         a length of 1 element only (batch processing is not supported in the code, though nothing really prevent it)
       :return: the config id and config name
     '''
     if not res_id:
         raise UserError(_("Creating google drive may only be done by one at a time."))
     # check if a model is configured with a template
     configs = self.search([('model_id', '=', res_model)])
     config_values = []
     for config in configs.sudo():
         if config.filter_id:
             if config.filter_id.user_id and config.filter_id.user_id.id != self.env.user.id:
                 #Private
                 continue
             domain = [('id', 'in', [res_id])] + safe_eval(config.filter_id.domain)
             additionnal_context = safe_eval(config.filter_id.context)
             google_doc_configs = self.env[config.filter_id.model_id].with_context(**additionnal_context).search(domain)
             if google_doc_configs:
                 config_values.append({'id': config.id, 'name': config.name})
         else:
             config_values.append({'id': config.id, 'name': config.name})
     return config_values
Пример #5
0
def transfer_node_to_modifiers(node,
                               modifiers,
                               context=None,
                               in_tree_view=False):
    if node.get('attrs'):
        modifiers.update(safe_eval(node.get('attrs')))

    if node.get('states'):
        if 'invisible' in modifiers and isinstance(modifiers['invisible'],
                                                   list):
            # TODO combine with AND or OR, use implicit AND for now.
            modifiers['invisible'].append(
                ('state', 'not in', node.get('states').split(',')))
        else:
            modifiers['invisible'] = [('state', 'not in',
                                       node.get('states').split(','))]

    for a in ('invisible', 'readonly', 'required'):
        if node.get(a):
            v = bool(safe_eval(node.get(a), {'context': context or {}}))
            if in_tree_view and a == 'invisible':
                # Invisible in a tree view has a specific meaning, make it a
                # new key in the modifiers attribute.
                modifiers['column_invisible'] = v
            elif v or (a not in modifiers
                       or not isinstance(modifiers[a], list)):
                # Don't set the attribute to False if a dynamic value was
                # provided (i.e. a domain from attrs or states).
                modifiers[a] = v
Пример #6
0
 def run_action_code_multi(self, action, eval_context=None):
     safe_eval(action.sudo().code.strip(),
               eval_context,
               mode="exec",
               nocopy=True)  # nocopy allows to return 'action'
     if 'action' in eval_context:
         return eval_context['action']
Пример #7
0
    def _satisfy_condition(self, localdict):
        """
        @param contract_id: id of hr.contract to be tested
        @return: returns True if the given rule match the condition for the given contract. Return False otherwise.
        """
        self.ensure_one()

        if self.condition_select == 'none':
            return True
        elif self.condition_select == 'range':
            try:
                result = safe_eval(self.condition_range, localdict)
                return self.condition_range_min <= result and result <= self.condition_range_max or False
            except:
                raise UserError(
                    _('Wrong range condition defined for salary rule %s (%s).')
                    % (self.name, self.code))
        else:  # python code
            try:
                safe_eval(self.condition_python,
                          localdict,
                          mode='exec',
                          nocopy=True)
                return 'result' in localdict and localdict['result'] or False
            except:
                raise UserError(
                    _('Wrong python condition defined for salary rule %s (%s).'
                      ) % (self.name, self.code))
Пример #8
0
    def _fetch_attachment(self):
        """
        This method will check if we have any existent attachement matching the model
        and res_ids and create them if not found.
        """
        self.ensure_one()
        obj = self.env[self.model].browse(self.res_id)
        if not self.attachment_id:
            report = self.report_template
            if not report:
                report_name = self.env.context.get('report_name')
                report = self.env['ir.actions.report']._get_report_from_name(report_name)
                if not report:
                    return False
                else:
                    self.write({'report_template': report.id})
                # report = self.env.ref('account.account_invoices')
            if report.print_report_name:
                report_name = safe_eval(report.print_report_name, {'object': obj})
            elif report.attachment:
                report_name = safe_eval(report.attachment, {'object': obj})
            else:
                report_name = 'Document'
            filename = "%s.%s" % (report_name, "pdf")
            pdf_bin, _ = report.with_context(snailmail_layout=not self.cover)._render_qweb_pdf(self.res_id)
            attachment = self.env['ir.attachment'].create({
                'name': filename,
                'datas': base64.b64encode(pdf_bin),
                'res_model': 'snailmail.letter',
                'res_id': self.id,
                'type': 'binary',  # override default_type from context, possibly meant for another model!
            })
            self.write({'attachment_id': attachment.id})

        return self.attachment_id
Пример #9
0
    def execute_code(self, code_exec):
        def reconciled_inv():
            """
            returns the list of invoices that are set as reconciled = True
            """
            return self.env['account.invoice'].search([('reconciled', '=',
                                                        True)]).ids

        def order_columns(item, cols=None):
            """
            This function is used to display a dictionary as a string, with its columns in the order chosen.

            :param item: dict
            :param cols: list of field names
            :returns: a list of tuples (fieldname: value) in a similar way that would dict.items() do except that the
                returned values are following the order given by cols
            :rtype: [(key, value)]
            """
            if cols is None:
                cols = list(item)
            return [(col, item.get(col)) for col in cols if col in item]

        localdict = {
            'cr': self.env.cr,
            'uid': self.env.uid,
            'reconciled_inv':
            reconciled_inv,  # specific function used in different tests
            'result': None,  # used to store the result of the test
            'column_order':
            None,  # used to choose the display order of columns (in case you are returning a list of dict)
            '_': _,
        }
        safe_eval(code_exec, localdict, mode="exec", nocopy=True)
        result = localdict['result']
        column_order = localdict.get('column_order', None)

        if not isinstance(result, (tuple, list, set)):
            result = [result]
        if not result:
            result = [_('The test was passed successfully')]
        else:

            def _format(item):
                if isinstance(item, dict):
                    return ', '.join([
                        "%s: %s" % (tup[0], tup[1])
                        for tup in order_columns(item, column_order)
                    ])
                else:
                    return item

            result = [_format(rec) for rec in result]

        return result
Пример #10
0
 def _eval(self, code, locals_dict=None, tsession=None):
     """Prepare data for rendering"""
     _logger.debug("_eval locals_dict: %s" % locals_dict)
     t0 = time.time()
     locals_dict = self._update_locals_dict(locals_dict, tsession)
     globals_dict = self._get_globals_dict()
     if code:
         safe_eval(code, globals_dict, locals_dict, mode="exec", nocopy=True)
         eval_time = time.time() - t0
         _logger.debug('Eval in %.2fs \nlocals_dict:\n%s\nCode:\n%s\n', eval_time, locals_dict, code)
     return locals_dict
Пример #11
0
    def get_action_domain(self, action):
        used_filters = []
        eval_vars = {'uid': self.env.uid}
        filters = self.env['ir.filters'].sudo().get_filters(action.res_model, action.id)
        personal_filter = None

        # get_default_filter function from js:
        for f in filters:
            if f['user_id'] and f['is_default']:
                personal_filter = f
                break

        if not personal_filter:
            for f in filters:
                if not f['user_id'] and f['is_default']:
                    personal_filter = f
                    break

        if personal_filter:
            personal_filter['string'] = personal_filter['name']
            default_domains = [personal_filter['domain']]
            used_filters = [personal_filter]
        else:
            # find filter from context, i.e. the same as UI works
            default_domains = []
            # parse search view
            search_view = self.env[action.res_model].sudo().fields_view_get(view_id=action.search_view_id.id, view_type='search')['arch']
            search_view_filters = {}
            for el in etree.fromstring(search_view):
                if el.tag != 'filter':
                    continue
                f = el.attrib
                search_view_filters[f['name']] = f

            # proceed context
            action_context = safe_eval(action.context, eval_vars)
            for k, v in action_context.items():
                if not k.startswith('search_default'):
                    continue
                filter_name = k.split('search_default_')[1]
                filter = search_view_filters[filter_name]
                default_domains.append(filter['domain'])
                used_filters.append(filter)

        # eval and combine default_domains into one
        domain = []
        for d in default_domains:
            domain += safe_eval(d, eval_vars)
        return domain, used_filters
Пример #12
0
    def _get_price_from_picking(self, total, weight, volume, quantity):
        price = 0.0
        criteria_found = False
        price_dict = {
            'price': total,
            'volume': volume,
            'weight': weight,
            'wv': volume * weight,
            'quantity': quantity
        }
        if self.free_over and total >= self.amount:
            return 0
        for line in self.price_rule_ids:
            test = safe_eval(
                line.variable + line.operator + str(line.max_value),
                price_dict)
            if test:
                price = line.list_base_price + line.list_price * price_dict[
                    line.variable_factor]
                criteria_found = True
                break
        if not criteria_found:
            raise UserError(
                _("No price rule matching this order; delivery cost cannot be computed."
                  ))

        return price
Пример #13
0
    def action_your_pipeline(self):
        action = self.env.ref('crm.crm_lead_opportunities_tree_view').read()[0]
        user_team_id = self.env.user.sale_team_id.id
        if not user_team_id:
            user_team_id = self.search([], limit=1).id
            action[
                'help'] = """<p class='oe_view_nocontent_create'>Click here to add new opportunities</p><p>
    Looks like you are not a member of a sales channel. You should add yourself
    as a member of one of the sales channel.
</p>"""
            if user_team_id:
                action[
                    'help'] += "<p>As you don't belong to any sales channel, Flectra opens the first one by default.</p>"

        action_context = safe_eval(action['context'], {'uid': self.env.uid})
        if user_team_id:
            action_context['default_team_id'] = user_team_id

        tree_view_id = self.env.ref('crm.crm_case_tree_view_oppor').id
        form_view_id = self.env.ref('crm.crm_case_form_view_oppor').id
        kanb_view_id = self.env.ref('crm.crm_case_kanban_view_leads').id
        action['views'] = [[kanb_view_id, 'kanban'], [tree_view_id, 'tree'],
                           [form_view_id, 'form'], [False, 'graph'],
                           [False, 'calendar'], [False, 'pivot']]
        action['context'] = action_context
        return action
Пример #14
0
    def format(self, percent, value, grouping=False, monetary=False):
        """ Format() will return the language-specific output for float values"""
        self.ensure_one()
        if percent[0] != '%':
            raise ValueError(
                _("format() must be given exactly one %char format specifier"))

        formatted = percent % value

        # floats and decimal ints need special action!
        if grouping:
            lang_grouping, thousands_sep, decimal_point = self._data_get(
                monetary)
            eval_lang_grouping = safe_eval(lang_grouping)

            if percent[-1] in 'eEfFgG':
                parts = formatted.split('.')
                parts[0] = intersperse(parts[0], eval_lang_grouping,
                                       thousands_sep)[0]

                formatted = decimal_point.join(parts)

            elif percent[-1] in 'diu':
                formatted = intersperse(formatted, eval_lang_grouping,
                                        thousands_sep)[0]

        return formatted
Пример #15
0
    def assemble_tasks(self, docids, data, report, ctx):
        code = report.out_format.code
        result = self.single_report(docids, data, report, ctx)

        print_report_name = 'report'
        if report.print_report_name and not len(docids) > 1:
            obj = self.env[report.model].browse(docids)
            print_report_name = safe_eval(
                report.print_report_name, {'object': obj, 'time': time})

        if report.in_format == code:
            filename = '%s.%s' % (
                print_report_name, mime_dict[report.in_format])
            return result[0], result[1], filename
        else:
            try:
                self.get_docs_conn()
                result = self._generate_doc(result[0], report)
                filename = '%s.%s' % (
                    print_report_name, mime_dict[report.out_format.code])
                return result, mime_dict[code], filename
            except Exception as e:
                _logger.exception(_("Aeroo DOCS error!\n%s") % str(e))
                if report.disable_fallback:
                    result = None
                    _logger.exception(e[0])
                    raise ConnectionError(_('Could not connect Aeroo DOCS!'))
        # only if fallback
        filename = '%s.%s' % (print_report_name, mime_dict[report.in_format])
        return result[0], result[1], filename
Пример #16
0
    def action_view_task(self):
        self.ensure_one()

        list_view_id = self.env.ref('project.view_task_tree2').id
        form_view_id = self.env.ref('project.view_task_form2').id

        action = {'type': 'ir.actions.act_window_close'}
        task_projects = self.tasks_ids.mapped('project_id')
        if len(task_projects) == 1 and len(self.tasks_ids) > 1:  # redirect to task of the project (with kanban stage, ...)
            action = self.with_context(active_id=task_projects.id).env['ir.actions.actions']._for_xml_id(
                'project.act_project_project_2_project_task_all')
            action['domain'] = [('id', 'in', self.tasks_ids.ids)]
            if action.get('context'):
                eval_context = self.env['ir.actions.actions']._get_eval_context()
                eval_context.update({'active_id': task_projects.id})
                action_context = safe_eval(action['context'], eval_context)
                action_context.update(eval_context)
                action['context'] = action_context
        else:
            action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_task")
            action['context'] = {}  # erase default context to avoid default filter
            if len(self.tasks_ids) > 1:  # cross project kanban task
                action['views'] = [[False, 'kanban'], [list_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'calendar'], [False, 'pivot']]
            elif len(self.tasks_ids) == 1:  # single task -> form view
                action['views'] = [(form_view_id, 'form')]
                action['res_id'] = self.tasks_ids.id
        # filter on the task of the current SO
        action.setdefault('context', {})
        action['context'].update({'search_default_sale_order_id': self.id})
        return action
Пример #17
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)
Пример #18
0
 def get_alias_values(self):
     self.ensure_one()
     values = super(QcTeam, self).get_alias_values()
     values['alias_defaults'] = defaults = safe_eval(
         self.alias_defaults or "{}")
     defaults['qc_team_id'] = self.id
     return values
Пример #19
0
 def print_test_label(self):
     for label in self:
         if label.test_print_mode and label.record_id and label.printer_id:
             record = label._get_record()
             extra = safe_eval(label.extra, {'env': self.env})
             if record:
                 label.print_label(label.printer_id, record, **extra)
Пример #20
0
 def _filter_post(self, records):
     """ Filter the records that satisfy the postcondition of action ``self``. """
     if self.filter_domain and records:
         domain = [('id', 'in', records.ids)] + safe_eval(self.filter_domain, self._get_eval_context())
         return records.search(domain)
     else:
         return records
Пример #21
0
 def test_01_safe_eval(self):
     """ Try a few common expressions to verify they work with safe_eval """
     expected = (1, {"a": 9 * 2}, (True, False, None))
     actual = safe_eval('(1, {"a": 9 * 2}, (True, False, None))')
     self.assertEqual(
         actual, expected,
         "Simple python expressions are not working with safe_eval")
Пример #22
0
    def action_launch(self, context=None):
        """ Launch Action of Wizard"""
        self.ensure_one()

        self.write({'state': 'done'})

        # Load action
        action = self.env[self.action_id.type].browse(self.action_id.id)

        result = action.read()[0]
        if action._name != 'ir.actions.act_window':
            return result
        result.setdefault('context', '{}')

        # Open a specific record when res_id is provided in the context
        ctx = safe_eval(result['context'], {'user': self.env.user})
        if ctx.get('res_id'):
            result['res_id'] = ctx.pop('res_id')

        # disable log for automatic wizards
        ctx['disable_log'] = True

        result['context'] = ctx

        return result
Пример #23
0
    def _postprocess_pdf_report(self, record, buffer):
        '''Hook to handle post processing during the pdf report generation.
        The basic behavior consists to create a new attachment containing the pdf
        base64 encoded.

        :param record_id: The record that will own the attachment.
        :param pdf_content: The optional name content of the file to avoid reading both times.
        :return: A modified buffer if the previous one has been modified, None otherwise.
        '''
        attachment_name = safe_eval(self.attachment, {
            'object': record,
            'time': time
        })
        if not attachment_name:
            return None
        attachment_vals = {
            'name': attachment_name,
            'raw': buffer.getvalue(),
            'res_model': self.model,
            'res_id': record.id,
            'type': 'binary',
        }
        try:
            self.env['ir.attachment'].create(attachment_vals)
        except AccessError:
            _logger.info("Cannot save PDF report %r as attachment",
                         attachment_vals['name'])
        else:
            _logger.info('The PDF document %s is now saved in the database',
                         attachment_vals['name'])
        return buffer
Пример #24
0
    def postprocess_pdf_report(self, record, buffer):
        '''Hook to handle post processing during the pdf report generation.
        The basic behavior consists to create a new attachment containing the pdf
        base64 encoded.

        :param record_id: The record that will own the attachment.
        :param pdf_content: The optional name content of the file to avoid reading both times.
        :return: The newly generated attachment if no AccessError, else None.
        '''
        attachment_name = safe_eval(self.attachment, {
            'object': record,
            'time': time
        })
        if not attachment_name:
            return None
        attachment_vals = {
            'name': attachment_name,
            'datas': base64.encodestring(buffer.getvalue()),
            'datas_fname': attachment_name,
            'res_model': self.model,
            'res_id': record.id,
        }
        attachment = None
        try:
            attachment = self.env['ir.attachment'].create(attachment_vals)
        except AccessError:
            _logger.info("Cannot save PDF report %r as attachment",
                         attachment_vals['name'])
        else:
            _logger.info('The PDF document %s is now saved in the database',
                         attachment_vals['name'])
        return attachment
Пример #25
0
    def action_your_pipeline(self):
        action = self.env["ir.actions.actions"]._for_xml_id(
            "crm.crm_lead_action_pipeline")
        user_team_id = self.env.user.sale_team_id.id
        if user_team_id:
            # To ensure that the team is readable in multi company
            user_team_id = self.search([('id', '=', user_team_id)], limit=1).id
        else:
            user_team_id = self.search([], limit=1).id
            action['help'] = _(
                """<p class='o_view_nocontent_smiling_face'>Add new opportunities</p><p>
    Looks like you are not a member of a Sales Team. You should add yourself
    as a member of one of the Sales Team.
</p>""")
            if user_team_id:
                action['help'] += _(
                    "<p>As you don't belong to any Sales Team, Flectra opens the first one by default.</p>"
                )

        action_context = safe_eval(action['context'], {'uid': self.env.uid})
        if user_team_id:
            action_context['default_team_id'] = user_team_id

        action['context'] = action_context
        return action
Пример #26
0
 def message_get_email_values(self, notif_mail=None):
     self.ensure_one()
     res = super(Channel,
                 self).message_get_email_values(notif_mail=notif_mail)
     headers = {}
     if res.get('headers'):
         try:
             headers.update(safe_eval(res['headers']))
         except Exception:
             pass
     headers['Precedence'] = 'list'
     # avoid out-of-office replies from MS Exchange
     # http://blogs.technet.com/b/exchange/archive/2006/10/06/3395024.aspx
     headers['X-Auto-Response-Suppress'] = 'OOF'
     if self.alias_domain and self.alias_name:
         headers['List-Id'] = '<%s.%s>' % (self.alias_name,
                                           self.alias_domain)
         headers['List-Post'] = '<mailto:%s@%s>' % (self.alias_name,
                                                    self.alias_domain)
         # Avoid users thinking it was a personal message
         # X-Forge-To: will replace To: after SMTP envelope is determined by ir.mail.server
         list_to = '"%s" <%s@%s>' % (self.name, self.alias_name,
                                     self.alias_domain)
         headers['X-Forge-To'] = list_to
     res['headers'] = repr(headers)
     return res
Пример #27
0
 def action_view_project_ids(self):
     self.ensure_one()
     if len(self.project_ids) == 1:
         if self.env.user.has_group("hr_timesheet.group_hr_timesheet_user"):
             action = self.project_ids.action_view_timesheet_plan()
         else:
             action = self.env.ref(
                 "project.act_project_project_2_project_task_all").read()[0]
             action['context'] = safe_eval(
                 action.get('context', '{}'), {
                     'active_id': self.project_ids.id,
                     'active_ids': self.project_ids.ids
                 })
     else:
         view_form_id = self.env.ref('project.edit_project').id
         view_kanban_id = self.env.ref('project.view_project_kanban').id
         action = {
             'type': 'ir.actions.act_window',
             'domain': [('id', 'in', self.project_ids.ids)],
             'views': [(view_kanban_id, 'kanban'), (view_form_id, 'form')],
             'view_mode': 'kanban,form',
             'name': _('Projects'),
             'res_model': 'project.project',
         }
     return action
Пример #28
0
 def _check_alias_defaults(self):
     try:
         dict(safe_eval(self.alias_defaults))
     except Exception:
         raise ValidationError(
             _('Invalid expression, it must be a literal python dictionary definition e.g. "{\'field\': \'value\'}"'
               ))
Пример #29
0
 def action_view_all_rating(self):
     """ return the action to see all the rating of the project, and activate default filters """
     action = self.env['ir.actions.act_window'].for_xml_id('rating_project', 'rating_rating_action_view_project_rating')
     action['name'] = _('Ratings of %s') % (self.name,)
     action_context = safe_eval(action['context']) if action['context'] else {}
     action_context.update(self._context)
     action_context['search_default_rating_tasks'] = 1
     return dict(action, context=action_context)
Пример #30
0
 def _get_cache_key(self, req):
     # Always call me with super() AT THE END to have cache_key_expr appended as last element
     # It is the only way for end user to not use cache via expr.
     # E.g  (None if 'token' in request.params else 1,)  will bypass cache_time
     cache_key = (req.website.id, req.lang, req.httprequest.path)
     if self.cache_key_expr:  # e.g. (request.session.geoip.get('country_code'),)
         cache_key += safe_eval(self.cache_key_expr, {'request': req})
     return cache_key