Ejemplo n.º 1
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 = 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:
                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))
Ejemplo n.º 2
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(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(eval(self.amount_percentage_base, localdict)),
                     float(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:
             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))
Ejemplo n.º 3
0
 def _compute_price_unit(self,
                         prix_gpl=0.0,
                         remise_fournisseur=0.0,
                         marge=0.0,
                         frais_approche=0.0,
                         discount=0.0,
                         tva=0.0):
     data = {}
     if self.type_methode == 'pourcentage':
         print self.type_methode
         data['price_unit'] = 0
     elif self.type_methode == 'fixed':
         data['price_unit'] = 0
         print self.type_methode
     elif self.type_methode == 'code_python':
         localdict = {
             'prix_gpl': prix_gpl,
             'remise_fournisseur': remise_fournisseur,
             'marge': marge,
             'frais_approche': frais_approche,
             'discount': discount,
             'tva': tva
         }
         # print "[!] Displaying dictionary we got as parameter: {}".format(
         #     encapsulated_dictionary)
         eval(self.code_python, localdict, mode="exec", nocopy=True)
         print "[! ] Before returning, got data_to_return: {}".format(
             localdict)
         data['price_unit'] = localdict['result']
     return data
Ejemplo n.º 4
0
 def _check_condition_code(btn):
     locals_dict = {
         'env': this.env,
         'model': this.env[model],
         'obj': None,
         'user': this.env['res.users'].browse(this.env.uid),
         'datetime': datetime,
         'time': time,
         'date': date,
         'timedelta': timedelta,
         'workflow': this.env['odoo.workflow'],
         'warning': this.warning,
         'syslog': this.syslog,
     }
     try:
         eval(btn.condition_code,
              locals_dict=locals_dict,
              mode='exec',
              nocopy=True)
         result = 'result' in locals_dict and locals_dict[
             'result'] or False
         return result
     except Warning as ex:
         raise ex
     except:
         raise UserError(_("Wrong python condition defined."))
Ejemplo n.º 5
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:
         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])] + eval(config.filter_id.domain)
             additionnal_context = 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
Ejemplo n.º 6
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(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(eval(self.amount_percentage_base, localdict)),
                     float(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:
             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))
Ejemplo n.º 7
0
    def button_to_get_approve_list(self):
        """计算当前RFQ的签核角色信息列表"""

        expressions = self.env['iac.rfq.qh'].search([])

        # 遍历选中的RFQ计算规则
        for rfq_line in self:
            role_list = []
            proc_ex_list = []
            rule_name_list = []
            for exp in expressions:
                eval_context = {"r": rfq_line}
                # 判断规则是否判断通过
                try:
                    if eval(exp.key, eval_context):
                        role_list += eval(exp.value)
                        rule_name_list.append(exp.name)
                except:
                    traceback.print_exc()
                    err_msg = "rule eval error,name is (%s);\n error info is %s" % (
                        exp.name, traceback.format_exc())
                    proc_ex_list.append(err_msg)
            # 写入获取角色列表信息
            approve_role_list = {
                "role_list": sorted(list(set(role_list))),
                "rule_name_list": rule_name_list
            }
            vals = {
                "approve_role_list": approve_role_list,
                "webflow_result": proc_ex_list,
            }
            rfq_line.write(vals)
Ejemplo n.º 8
0
 def _execute(self):
     self.ensure_one()
     model_obj = self.env[self.import_tmpl_id.model_id.model]
     if self._context.get('original_cr'):
         new_env = self.env(cr=self._context['original_cr'])
         model_obj = model_obj.with_env(new_env)
     args = eval(self.args or '[]')
     kwargs = eval(self.import_tmpl_id.method_args or '{}')
     return getattr(model_obj, self.import_tmpl_id.method)(*args, **kwargs)
Ejemplo n.º 9
0
 def check_condition(self, document):
     self.ensure_one()
     result = False
     localdict = self._get_localdict(document)
     try:
         eval(self.domain, localdict, mode="exec", nocopy=True)
         result = localdict["result"]
     except:
         result = False
     return result
Ejemplo n.º 10
0
    def get_needaction_data(self):
        """ Return for each menu entry in ``self``:
            - whether it uses the needaction mechanism (needaction_enabled)
            - the needaction counter of the related action, taking into account
              the action domain
        """
        menu_ids = set()
        for menu in self:
            menu_ids.add(menu.id)
            ctx = {}
            if menu.action and menu.action.type in (
                    'ir.actions.act_window',
                    'ir.actions.client') and menu.action.context:
                with tools.ignore(Exception):
                    # use magical UnquoteEvalContext to ignore undefined client-side variables such as `active_id`
                    eval_ctx = tools.UnquoteEvalContext(self._context)
                    ctx = eval(menu.action.context,
                               locals_dict=eval_ctx,
                               nocopy=True) or {}
            menu_refs = ctx.get('needaction_menu_ref')
            if menu_refs:
                if not isinstance(menu_refs, list):
                    menu_refs = [menu_refs]
                for menu_ref in menu_refs:
                    record = self.env.ref(menu_ref, False)
                    if record and record._name == 'ir.ui.menu':
                        menu_ids.add(record.id)

        res = {}
        for menu in self.browse(menu_ids):
            res[menu.id] = {
                'needaction_enabled': False,
                'needaction_counter': False,
            }
            if menu.action and menu.action.type in (
                    'ir.actions.act_window',
                    'ir.actions.client') and menu.action.res_model:
                if menu.action.res_model in self.env:
                    model = self.env[menu.action.res_model]
                    if model._needaction:
                        if menu.action.type == 'ir.actions.act_window':
                            eval_context = self.env[
                                'ir.actions.act_window']._get_eval_context()
                            dom = eval(menu.action.domain or '[]',
                                       eval_context)
                        else:
                            dom = eval(menu.action.params_store or '{}', {
                                'uid': self._uid
                            }).get('domain')
                        res[menu.id]['needaction_enabled'] = model._needaction
                        res[menu.id][
                            'needaction_counter'] = model._needaction_count(
                                dom)
        return res
Ejemplo n.º 11
0
 def _filter_post(self, records):
     """ Filter the records that satisfy the postcondition of action ``self``. """
     if self.filter_id and records:
         domain = [('id', 'in', records.ids)] + eval(self.filter_id.domain, self._get_eval_context())
         ctx = eval(self.filter_id.context)
         return records.with_context(**ctx).search(domain).with_env(records.env)
     elif self.filter_domain and records:
         domain = [('id', 'in', records.ids)] + eval(self.filter_domain, self._get_eval_context())
         return records.search(domain)
     else:
         return records
 def satisfy_condition(self, localdict):
     """
     @return: returns True if the given rule matches.
              Return False otherwise.
     """
     self.ensure_one()
     try:
         eval(self.condition_python, localdict, mode="exec", nocopy=True)
         return "result" in localdict and localdict["result"] or False
     except Exception as e:
         raise UserError("Wrong python condition defined for disbursement "
                         "exception rule %s. \n %s" % (self.name, str(e)))
Ejemplo n.º 13
0
 def get_avance(p, code, is_interest, categories, inputs):
     if p.simulation_ok:
         if not p.simulate_elements_ok:
             return 0.0
     plafond = False
     rate = False
     if is_interest:
         localdict = {
             'categories': categories,
             'inputs': inputs,
             'self': self,
         }
         expression_id = self.search([('code', '=', 'NET_IMPOSABLE')],
                                     limit=1)
         expression = expression_id
         expression = expression and expression.amount_python_compute or False
         eval(expression, localdict, mode='exec', nocopy=True)
         result = 'result' in localdict and localdict['result'] or 0.0
         plafond = result
     somme = 0.0
     # Avances
     line_obj = self.env['hr.avance.line.line']
     # Domain linked to saisie.py
     domain = [
         ('state', '=', 'done'),
         ('avance_line_id.code', '=', code),
         ('avance_line_id.employee_id', '=', p.employee_id),
         ('date', '>=', p.date_from),
         ('date', '<=', p.date_to),
     ]
     line_ids = line_obj.search(domain)
     lines = line_ids
     somme += sum([x.amount for x in lines])
     # Rates
     for line in lines:
         rate = line.avance_line_id.avance_id.interest_rate
         break
     # Notes de frais
     line_obj = self.env['hr.expense']
     domain = [
         ('state', '=', 'paid'),
         ('avance_id.code', '=', code),
         ('employee_id', '=', p.employee_id),
         ('payroll_date', '<=', p.date_to),
         ('payroll_date', '>=', p.date_from),
     ]
     line_ids = line_obj.search(domain)
     lines = line_ids
     somme += sum([x.total_amount for x in lines])
     if rate and plafond:
         if somme > plafond * rate / 100.:
             return plafond * rate / 100.
     return somme
Ejemplo n.º 14
0
 def _get_sequence_id(self, document):
     self.ensure_one()
     result = False
     localdict = self._get_localdict(document)
     try:
         eval(self.sequence_computation_code,
              localdict,
              mode="exec",
              nocopy=True)
         result = localdict["result"]
     except:
         raise UserError(_("Error on get sequence"))
     return result
Ejemplo n.º 15
0
 def _execute(self):
     self.ensure_one()
     if not self.record_ids:
         raise UserError(_("You cannot regenerate this export because records to export didn't store"))
     record_ids = eval(self.record_ids)
     if record_ids or self.export_tmpl_id.force_execute_action:
         records = self.env[self.export_tmpl_id.model_id.model].browse(record_ids)
         if self.export_tmpl_id.method:
             if self._context.get('original_cr'):
                 new_env = self.env(cr=self._context['original_cr'])
                 records = records.with_env(new_env)
             args = eval(self.args or '[]')
             kwargs = eval(self.export_tmpl_id.method_args or '{}')
             return getattr(records, self.export_tmpl_id.method)(*args, **kwargs)
Ejemplo n.º 16
0
    def _check(self, automatic=False, use_new_cursor=False):
        """ This Function is called by scheduler. """
        if '__action_done' not in self._context:
            self = self.with_context(__action_done={})

        # retrieve all the action rules to run based on a timed condition
        eval_context = self._get_eval_context()
        for action in self.with_context(active_test=True).search([('kind', '=', 'on_time')]):
            last_run = fields.Datetime.from_string(action.last_run) or datetime.datetime.utcfromtimestamp(0)

            # retrieve all the records that satisfy the action's condition
            domain = []
            context = dict(self._context)
            if action.filter_domain:
                domain = eval(action.filter_domain, eval_context)
            elif action.filter_id:
                domain = eval(action.filter_id.domain, eval_context)
                context.update(eval(action.filter_id.context))
                if 'lang' not in context:
                    # Filters might be language-sensitive, attempt to reuse creator lang
                    # as we are usually running this as super-user in background
                    filter_meta = action.filter_id.get_metadata()[0]
                    user_id = (filter_meta['write_uid'] or filter_meta['create_uid'])[0]
                    context['lang'] = self.env['res.users'].browse(user_id).lang
            records = self.env[action.model].with_context(context).search(domain)

            # determine when action should occur for the records
            if action.trg_date_id.name == 'date_action_last' and 'create_date' in records._fields:
                get_record_dt = lambda record: record[action.trg_date_id.name] or record.create_date
            else:
                get_record_dt = lambda record: record[action.trg_date_id.name]

            # process action on the records that should be executed
            now = datetime.datetime.now()
            for record in records:
                record_dt = get_record_dt(record)
                if not record_dt:
                    continue
                action_dt = self._check_delay(action, record, record_dt)
                if last_run <= action_dt < now:
                    try:
                        action._process(record)
                    except Exception:
                        _logger.error(traceback.format_exc())

            action.write({'last_run': fields.Datetime.now()})

            if automatic:
                # auto-commit for batch processing
                self._cr.commit()
Ejemplo n.º 17
0
 def amount_to_text(self, value):
     val = {}
     self.ensure_one()
     val = "-"
     if self.python_amount2text:
         try:
             localdict = {'value': value}
             eval(self.python_amount2text,
                  localdict,
                  mode='exec',
                  nocopy=True)
             val = localdict['result']
         except:
             pass
     return val
Ejemplo n.º 18
0
    def add_terms_and_conditions(self, res_id, original_report_pdf):
        model = self.model
        object = self.env[model].browse(res_id)
        company = object.company_id
        if not company.terms_and_conditions:
            return original_report_pdf

        language_field = self.terms_conditions_language_field

        localdict = {'o': object}
        eval('document_language = o.%s' % language_field, localdict,
             mode='exec', nocopy=True)
        document_language = localdict.get('document_language',
                                          self._context.get('lang'))

        # Try to find the terms and condition matching the document_language
        terms_and_conditions = company.terms_and_conditions.filtered(
            lambda t: t.language_id.code == document_language)
        if not terms_and_conditions:
            # Try to find the default terms and conditions (no language set)
            terms_and_conditions = company.terms_and_conditions.filtered(
                lambda t: not t.language_id)
            if not terms_and_conditions:
                return original_report_pdf

        terms_and_conditions_decoded = base64.b64decode(terms_and_conditions.datas)

        if terms_and_conditions_decoded:
            writer = PdfFileWriter()
            stream_original_report = io.BytesIO(original_report_pdf[0])
            reader_original_report = PdfFileReader(stream_original_report)
            stream_terms_and_conditions = io.BytesIO(
                terms_and_conditions_decoded)
            reader_terms_and_conditions = PdfFileReader(
                stream_terms_and_conditions)
            for page in range(0, reader_original_report.getNumPages()):
                writer.addPage(reader_original_report.getPage(page))

            for page in range(0, reader_terms_and_conditions.getNumPages()):
                writer.addPage(reader_terms_and_conditions.getPage(page))

            stream_to_write = io.BytesIO()
            writer.write(stream_to_write)

            combined_pdf = stream_to_write.getvalue()
            return combined_pdf, 'pdf'
        else:
            return original_report_pdf
Ejemplo n.º 19
0
 def _compute_data(self):
     for tile in self:
         if not tile.model_id or not tile.active:
             return
         model = self.env[tile.model_id.model]
         eval_context = self._get_eval_context()
         domain = tile.domain or "[]"
         try:
             count = model.search_count(eval(domain, eval_context))
         except Exception as e:
             tile.primary_value = 0.0
             tile.primary_formated_value =\
                 tile.secondary_formated_value = _("Error")
             tile.error = str(e)
             return
         fields = [
             f.name
             for f in [tile.primary_field_id, tile.secondary_field_id] if f
         ]
         read_vals = (fields and model.search_read(
             eval(domain, eval_context), fields) or [])
         for f in ["primary_", "secondary_"]:
             f_function = f + "function"
             f_field_id = f + "field_id"
             f_format = f + "format"
             f_value = f + "value"
             f_formated_value = f + "formated_value"
             value = 0
             if not tile[f_function]:
                 tile[f_value] = 0.0
                 tile[f_formated_value] = False
             else:
                 if tile[f_function] == "count":
                     value = count
                 else:
                     func = FIELD_FUNCTIONS[tile[f_function]]["func"]
                     vals = [x[tile[f_field_id].name] for x in read_vals]
                     value = func(vals or [0.0])
                 try:
                     tile[f_value] = value
                     tile[f_formated_value] = (tile[f_format]
                                               or "{:,}").format(value)
                     if tile.hide_if_null and not value:
                         tile.hidden = True
                 except ValueError as e:
                     tile[f_value] = 0.0
                     tile[f_formated_value] = _("Error")
                     tile.error = str(e)
Ejemplo n.º 20
0
 def run(self):
     for rec in self:
         # Check Condition Before Executing Action
         result = False
         cx = self.env.context.copy() or {}
         locals_dict = {
             'env':
             self.env,
             'model':
             self.env[cx.get('active_model', False)],
             'obj':
             self.env[cx.get('active_model',
                             False)].browse(cx.get('active_id', 0)),
             'user':
             self.env.user,
             'datetime':
             datetime,
             'time':
             time,
             'date':
             date,
             'timedelta':
             timedelta,
             'workflow':
             self.env['odoo.workflow'],
             'warning':
             self.warning,
             'syslog':
             self.syslog,
         }
         try:
             eval(rec.condition_code,
                  locals_dict=locals_dict,
                  mode='exec',
                  nocopy=True)
             result = 'result' in locals_dict and locals_dict[
                 'result'] or False
         except ValidationError as ex:
             raise ex
         except SyntaxError as ex:
             raise UserError(
                 _("Wrong python code defined.\n\nError: %s\nLine: %s, Column: %s\n\n%s"
                   % (ex.args[0], ex.args[1][1], ex.args[1][2],
                      ex.args[1][3])))
         if result:
             # Run Proper Action
             func = getattr(self, "_run_%s" % rec.action_type)
             return func()
Ejemplo n.º 21
0
 def many2one_search(self, word, model, domain):
     return request.make_response(
         simplejson.dumps([{
             'id': record[0],
             'value': record[1]
         } for record in request.env[model].name_search(
             word, args=eval(domain), limit=20)]))
Ejemplo n.º 22
0
 def _get_res_ids(self, *args):
     model_obj = self.env[self.model_id.model]
     if self._context.get('original_cr'):
         model_obj = model_obj.with_env(self.env(cr=self._context['original_cr']))
     if self.filter_type == 'domain':
         domain = eval(self.filter_domain or '[]', self._get_eval_context())
         res_ids = set(model_obj.search(domain, order=self.order or '')._ids)
     else:  # elif self.filter_type == 'method':
         if not (self.filter_method and hasattr(model_obj, self.filter_method)):
             raise UserError(_("Can't find method: %s on object: %s") % (self.filter_method, self.model_id.model))
         res_ids = set(getattr(model_obj, self.filter_method)(*args))
     if 'active_ids' in self._context:
         res_ids &= set(self._context['active_ids'])
     if self.unique:
         res_ids -= set(sum([eval(export.record_ids) for export in self.export_ids], []))
     return list(res_ids)
Ejemplo n.º 23
0
 def _get_upgrades(self):
     upgrades_path = upgrade_config.get('upgrades_path')
     if not upgrades_path:
         return []
     if not self.db_in_creation:
         self._try_lock('Upgrade in progress')
     upgrades = []
     for dir in os.listdir(upgrades_path):
         dir_path = os.path.join(upgrades_path, dir)
         if os.path.isdir(dir_path):
             file_path = os.path.join(dir_path, '__upgrade__.py')
             if not os.path.exists(file_path):
                 _logger.warning(u"%s doesn't exist", file_path)
                 continue
             if not os.path.isfile(file_path):
                 _logger.warning(u'%s is not a file', file_path)
                 continue
             with open(file_path) as f:
                 try:
                     upgrade_infos = eval(f.read())
                     upgrade = Upgrade(dir_path, upgrade_infos)
                     if (not upgrade.databases or self.db_name in upgrade.databases) \
                             and self.db_version < upgrade.version <= self.code_version:
                         upgrades.append(upgrade)
                 except Exception, e:
                     _logger.error('%s is not valid: %s', file_path,
                                   repr(e))
Ejemplo n.º 24
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 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, Odoo opens the first one by default.</p>"

        action_context = 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
Ejemplo n.º 25
0
    def _get_formatted_template(self, w):
        payload = w.template_id.template.strip()
        v = re.findall(r'(\$\{\s.+\s\})', payload)
        v += re.findall(r'(\$\{.+\})', payload)
        v += re.findall(r'(\$\{[\w\s.]+\})', payload)
        v = list(set(v))
        employee = w.employee_id
        contract_id = self.env['hr.contract'].search([
            ('employee_id', '=', employee.id),
            ('is_contract_valid_by_context', '=', w.action_date)
        ])
        contract = contract_id and self.env['hr.contract'].browse(
            contract_id[0]) or False
        company = contract and contract.company_id or employee.company_id
        for element in v:
            localdict = {
                'object': w,
                'contract': contract,
                'employee': employee,
                'company': company,
            }
            try:
                m = eval(element[2:-1].strip(),
                         localdict,
                         mode='eval',
                         nocopy=True)
                payload = payload.replace(element, m)
            except:
                pass

        return payload
Ejemplo n.º 26
0
 def construction_action_url_list(self, action, action_url_list):
     """
     把所有的数据整合,经过深度处理放进 action_url_list
     :param action: [home.page]对象,数据的来源。
     :param action_url_list: 存放数据的处理结果。
     :return:
     """
     action_vals = self.constract_action_vals(action)
     if action.menu_type == 'all_business':
         action_url_list['main'].append(action_vals)
     elif action.menu_type == 'amount_summary':
         # 金额汇总类
         compute_domain = eval(action.domain or '[]')
         res_model_objs = self.env[action.action.res_model].search(compute_domain)
         field_compute = action.compute_field_one.name
         # 最新的金额
         compute_value = sum([res_model_obj[field_compute] for res_model_obj in res_model_objs])
         # 返回结果
         action_vals[0] = "%s  %s" % (action_vals[0], compute_value)
         action_url_list['top'].append(action_vals)
     else:
         action_vals[0] = "%s   " % action_vals[0]
         type_sequence_str = "%s;%s" % (action.report_type_id.sequence, action.report_type_id.name)
         if action_url_list['right'].get(type_sequence_str):
             action_url_list['right'][type_sequence_str].append(action_vals)
         else:
             action_url_list['right'].update({type_sequence_str: [action_vals]})
Ejemplo n.º 27
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 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, Odoo opens the first one by default.</p>"

        action_context = 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
Ejemplo n.º 28
0
 def construction_action_url_list(self, action, action_url_list):
     """
     把所有的数据整合,经过深度处理放进 action_url_list
     :param action: [home.page]对象,数据的来源。
     :param action_url_list: 存放数据的处理结果。
     :return:
     """
     action_vals = self.constract_action_vals(action)
     if action.menu_type == 'all_business':
         action_url_list['main'].append(action_vals)
     elif action.menu_type == 'amount_summary':
         # 性能如果急需提升,就只有sum计算和那个search 是瓶颈了。 这个功能可以尽量少的用,或者用在小数据量的数据字段统计。
         # 如果数据量很大就不要用这种方式。
         res_model_objs = self.env[action.action.res_model].search(eval(action.domain or '[]'))
         field_compute = action.compute_field_one.name
         action_vals[0] = "%s  %s" % (action_vals[0], sum([res_model_obj[field_compute]
                                                           for res_model_obj in res_model_objs]))
         action_url_list['top'].append(action_vals)
     else:
         action_vals[0] = "%s   " % action_vals[0]
         type_sequence_str = "%s;%s" % (action.report_type_id.sequence, action.report_type_id.name)
         if action_url_list['right'].get(type_sequence_str):
             action_url_list['right'][type_sequence_str].append(action_vals)
         else:
             action_url_list['right'].update({type_sequence_str: [action_vals]})
Ejemplo n.º 29
0
 def get_alias_values(self):
     has_group_use_lead = self.env.user.has_group('crm.group_use_lead')
     values = super(Team, self).get_alias_values()
     values['alias_defaults'] = defaults = eval(self.alias_defaults or "{}")
     defaults['type'] = 'lead' if has_group_use_lead and self.use_leads else 'opportunity'
     defaults['team_id'] = self.id
     return values
Ejemplo n.º 30
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 = eval(lang_grouping)

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

                formatted = decimal_point.join(parts)

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

        return formatted
Ejemplo n.º 31
0
 def construction_action_url_list(self, action, action_url_list):
     """
     把所有的数据整合,经过深度处理放进 action_url_list
     :param action: [home.page]对象,数据的来源。
     :param action_url_list: 存放数据的处理结果。
     :return:
     """
     action_vals = self.constract_action_vals(action)
     if action.menu_type == 'all_business':
         action_url_list['main'].append(action_vals)
     elif action.menu_type == 'amount_summary':
         # 性能如果急需提升,就只有sum计算和那个search 是瓶颈了。 这个功能可以尽量少的用,或者用在小数据量的数据字段统计。
         # 如果数据量很大就不要用这种方式。
         res_model_objs = self.env[action.action.res_model].search(eval(action.domain or '[]'))
         field_compute = action.compute_field_one.name
         action_vals[0] = "%s  %s" % (action_vals[0], sum([res_model_obj[field_compute]
                                                           for res_model_obj in res_model_objs]))
         action_url_list['top'].append(action_vals)
     else:
         action_vals[0] = "%s   " % action_vals[0]
         type_sequence_str = "%s;%s" % (action.report_type_id.sequence, action.report_type_id.name)
         if action_url_list['right'].get(type_sequence_str):
             action_url_list['right'][type_sequence_str].append(action_vals)
         else:
             action_url_list['right'].update({type_sequence_str: [action_vals]})
Ejemplo n.º 32
0
 def _force_domain(self):
     eval_context = self._eval_context()
     for rule in self:
         if rule.domain_force:
             rule.domain = expression.normalize_domain(eval(rule.domain_force, eval_context))
         else:
             rule.domain = []
 def construction_action_url_list(self, action, action_url_list):
     """
     把所有的数据整合,经过深度处理放进 action_url_list
     :param action: [home.page]对象,数据的来源。
     :param action_url_list: 存放数据的处理结果。
     :return:
     """
     action_vals = self.constract_action_vals(action)
     if action.menu_type == 'all_business':
         action_url_list['main'].append(action_vals)
     elif action.menu_type == 'amount_summary':
         # 金额汇总类
         compute_domain = eval(action.domain or '[]')
         res_model_objs = self.env[action.action.res_model].search(
             compute_domain)
         field_compute = action.compute_field_one.name
         # 最新的金额
         compute_value = sum([
             res_model_obj[field_compute]
             for res_model_obj in res_model_objs
         ])
         # 返回结果
         action_vals[0] = "%s  %s" % (action_vals[0], compute_value)
         action_url_list['top'].append(action_vals)
     else:
         action_vals[0] = "%s   " % action_vals[0]
         type_sequence_str = "%s;%s" % (action.report_type_id.sequence,
                                        action.report_type_id.name)
         if action_url_list['right'].get(type_sequence_str):
             action_url_list['right'][type_sequence_str].append(action_vals)
         else:
             action_url_list['right'].update(
                 {type_sequence_str: [action_vals]})
Ejemplo n.º 34
0
 def _run_code(self):
     # Variables
     cx = self.env.context.copy() or {}
     locals_dict = {
         'env':
         self.env,
         'model':
         self.env[cx.get('active_model', False)],
         'obj':
         self.env[cx.get('active_model',
                         False)].browse(cx.get('active_id', 0)),
         'user':
         self.env.user,
         'datetime':
         datetime,
         'time':
         time,
         'date':
         date,
         'timedelta':
         timedelta,
         'workflow':
         self.env['odoo.workflow'],
         'warning':
         self.warning,
         'syslog':
         self.syslog,
     }
     # Run Code
     for rec in self:
         try:
             eval(rec.code,
                  locals_dict=locals_dict,
                  mode='exec',
                  nocopy=True)
             action = 'action' in locals_dict and locals_dict[
                 'action'] or False
             if action:
                 return action
         except Warning as ex:
             raise ex
         except SyntaxError as ex:
             raise UserError(
                 _("Wrong python code defined.\n\nError: %s\nLine: %s, Column: %s\n\n%s"
                   % (ex.args[0], ex.args[1][1], ex.args[1][2],
                      ex.args[1][3])))
     return True
Ejemplo n.º 35
0
    def _get_format_domain(self, name, domain):
        view = request.env['mobile.view'].search([('name', '=', name)])
        res = view.domain and eval(view.domain) or []
        res.extend([(item.get('name'), item.get('operator') or 'ilike',
                     item.get('operator') and float(item.get('word'))
                     or item.get('word')) for item in domain])

        return res
Ejemplo n.º 36
0
 def get_alias_values(self):
     has_group_use_lead = self.env.user.has_group('crm.group_use_lead')
     values = super(Team, self).get_alias_values()
     values['alias_defaults'] = defaults = eval(self.alias_defaults or "{}")
     defaults[
         'type'] = 'lead' if has_group_use_lead and self.use_leads else 'opportunity'
     defaults['team_id'] = self.id
     return values
Ejemplo n.º 37
0
 def _force_domain(self):
     eval_context = self._eval_context()
     for rule in self:
         if rule.domain_force:
             rule.domain = expression.normalize_domain(
                 eval(rule.domain_force, eval_context))
         else:
             rule.domain = []
Ejemplo n.º 38
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 = item.keys()
            return [(col, item.get(col)) for col in cols if col in item.keys()]

        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)
        }
        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
Ejemplo n.º 39
0
    def get_needaction_data(self):
        """ Return for each menu entry in ``self``:
            - whether it uses the needaction mechanism (needaction_enabled)
            - the needaction counter of the related action, taking into account
              the action domain
        """
        menu_ids = set()
        for menu in self:
            menu_ids.add(menu.id)
            ctx = {}
            if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.context:
                with tools.ignore(Exception):
                    # use magical UnquoteEvalContext to ignore undefined client-side variables such as `active_id`
                    eval_ctx = tools.UnquoteEvalContext(self._context)
                    ctx = eval(menu.action.context, locals_dict=eval_ctx, nocopy=True) or {}
            menu_refs = ctx.get('needaction_menu_ref')
            if menu_refs:
                if not isinstance(menu_refs, list):
                    menu_refs = [menu_refs]
                for menu_ref in menu_refs:
                    record = self.env.ref(menu_ref, False)
                    if record and record._name == 'ir.ui.menu':
                        menu_ids.add(record.id)

        res = {}
        for menu in self.browse(menu_ids):
            res[menu.id] = {
                'needaction_enabled': False,
                'needaction_counter': False,
            }
            if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.res_model:
                if menu.action.res_model in self.env:
                    model = self.env[menu.action.res_model]
                    if model._needaction:
                        if menu.action.type == 'ir.actions.act_window':
                            eval_context = self.env['ir.actions.act_window']._get_eval_context()
                            dom = eval(menu.action.domain or '[]', eval_context)
                        else:
                            dom = eval(menu.action.params_store or '{}', {'uid': self._uid}).get('domain')
                        res[menu.id]['needaction_enabled'] = model._needaction
                        res[menu.id]['needaction_counter'] = model._needaction_count(dom)
        return res
Ejemplo n.º 40
0
 def _check_grouping(self):
     warning = _('The Separator Format should be like [,n] where 0 < n :starting from Unit digit. '
                 '-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be 1,06,500;'
                 '[1,2,-1] will represent it to be 106,50,0;[3] will represent it as 106,500. '
                 'Provided as the thousand separator in each case.')
     for lang in self:
         try:
             if not all(isinstance(x, int) for x in eval(lang.grouping)):
                 raise ValidationError(warning)
         except Exception:
             raise ValidationError(warning)
Ejemplo n.º 41
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 = 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:
                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))
Ejemplo n.º 42
0
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname, docids=docids, converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(url.split('?')[1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname, converter='pdf', **dict(data))

                report = request.env['report']._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, "pdf")
                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        filename = eval(report.print_report_name, {'object': obj, 'time': time})
                response.headers.add('Content-Disposition', content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception, e:
            se = _serialize_exception(e)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return request.make_response(html_escape(json.dumps(error)))
Ejemplo n.º 43
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}
        for line in self.price_rule_ids:
            test = 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(_("Selected product in the delivery method doesn't fulfill any of the delivery carrier(s) criteria."))

        return price
Ejemplo n.º 44
0
 def _search_qty_available_new(self, operator, value, lot_id=False, owner_id=False, package_id=False):
     # TDE FIXME: should probably clean the search methods
     product_ids = set()
     domain_quant = self._get_domain_locations()[0]
     if lot_id:
         domain_quant.append(('lot_id', '=', lot_id))
     if owner_id:
         domain_quant.append(('owner_id', '=', owner_id))
     if package_id:
         domain_quant.append(('package_id', '=', package_id))
     quants_groupby = self.env['stock.quant'].read_group(domain_quant, ['product_id', 'qty'], ['product_id'])
     for quant in quants_groupby:
         if eval('%s %s %s' % (quant['qty'], operator, value)):
             product_ids.add(quant['product_id'][0])
     return list(product_ids)
Ejemplo n.º 45
0
 def message_get_email_values(self, notif_mail=None):
     self.ensure_one()
     res = super(MailGroup, self).message_get_email_values(notif_mail=notif_mail)
     base_url = self.env['ir.config_parameter'].get_param('web.base.url')
     headers = {}
     if res.get('headers'):
         try:
             headers = eval(res['headers'])
         except Exception:
             pass
     headers.update({
         'List-Archive': '<%s/groups/%s>' % (base_url, slug(self)),
         'List-Subscribe': '<%s/groups>' % (base_url),
         'List-Unsubscribe': '<%s/groups?unsubscribe>' % (base_url,),
     })
     res['headers'] = repr(headers)
     return res
Ejemplo n.º 46
0
    def process_segment(self):
        Workitems = self.env['marketing.campaign.workitem']
        Activities = self.env['marketing.campaign.activity']
        if not self:
            self = self.search([('state', '=', 'running')])

        action_date = fields.Datetime.now()
        campaigns = self.env['marketing.campaign']
        for segment in self:
            if segment.campaign_id.state != 'running':
                continue

            campaigns |= segment.campaign_id
            activity_ids = Activities.search([('start', '=', True), ('campaign_id', '=', segment.campaign_id.id)]).ids

            criteria = []
            if segment.sync_last_date and segment.sync_mode != 'all':
                criteria += [(segment.sync_mode, '>', segment.sync_last_date)]
            if segment.ir_filter_id:
                criteria += eval(segment.ir_filter_id.domain)

            # XXX TODO: rewrite this loop more efficiently without doing 1 search per record!
            for record in self.env[segment.object_id.model].search(criteria):
                # avoid duplicate workitem for the same resource
                if segment.sync_mode in ('write_date', 'all'):
                    if segment.campaign_id._find_duplicate_workitems(record):
                        continue

                wi_vals = {
                    'segment_id': segment.id,
                    'date': action_date,
                    'state': 'todo',
                    'res_id': record.id
                }

                partner = segment.campaign_id._get_partner_for(record)
                if partner:
                    wi_vals['partner_id'] = partner.id

                for activity_id in activity_ids:
                    wi_vals['activity_id'] = activity_id
                    Workitems.create(wi_vals)

            segment.write({'sync_last_date': action_date})
        Workitems.process_all(campaigns.ids)
        return True
Ejemplo n.º 47
0
 def message_get_email_values(self, notif_mail=None):
     self.ensure_one()
     res = super(ProjectIssue, self).message_get_email_values(notif_mail=notif_mail)
     headers = {}
     if res.get('headers'):
         try:
             headers.update(eval(res['headers']))
         except Exception:
             pass
     if self.project_id:
         current_objects = filter(None, headers.get('X-Odoo-Objects', '').split(','))
         current_objects.insert(0, 'project.project-%s, ' % self.project_id.id)
         headers['X-Odoo-Objects'] = ','.join(current_objects)
     if self.tag_ids:
         headers['X-Odoo-Tags'] = ','.join(self.tag_ids.mapped('name'))
     res['headers'] = repr(headers)
     return res
Ejemplo n.º 48
0
    def _search_product_quantity(self, operator, value, field):
        # TDE FIXME: should probably clean the search methods
        # to prevent sql injections
        if field not in ('qty_available', 'virtual_available', 'incoming_qty', 'outgoing_qty'):
            raise UserError('Invalid domain left operand')
        if operator not in ('<', '>', '=', '!=', '<=', '>='):
            raise UserError('Invalid domain operator')
        if not isinstance(value, (float, int)):
            raise UserError('Invalid domain right operand')

        if operator == '=':
            operator = '=='

        # TODO: Still optimization possible when searching virtual quantities
        ids = []
        for product in self.search([]):
            if eval(str(product[field]) + operator + str(value)):
                ids.append(product.id)
        return [('id', 'in', ids)]
Ejemplo n.º 49
0
    def get_recipients(self):
        if self.mailing_domain:
            domain = eval(self.mailing_domain)
            res_ids = self.env[self.mailing_model].search(domain).ids
        else:
            res_ids = []
            domain = [('id', 'in', res_ids)]

        # randomly choose a fragment
        if self.contact_ab_pc < 100:
            contact_nbr = self.env[self.mailing_model].search_count(domain)
            topick = int(contact_nbr / 100.0 * self.contact_ab_pc)
            if self.mass_mailing_campaign_id and self.mass_mailing_campaign_id.unique_ab_testing:
                already_mailed = self.mass_mailing_campaign_id.get_recipients()[self.mass_mailing_campaign_id.id]
            else:
                already_mailed = set([])
            remaining = set(res_ids).difference(already_mailed)
            if topick > len(remaining):
                topick = len(remaining)
            res_ids = random.sample(remaining, topick)
        return res_ids
Ejemplo n.º 50
0
 def construction_action_url_list(self,action,action_url_list):
     if action.menu_type == 'all_business':
         action_url_list['main'].append([action.note_one, action.action.view_mode, action.action.res_model,
                                         action.action.domain, action.id, action.action.context,
                                         action.view_id.id, action.action.name, action.action.target])
     elif action.menu_type == 'amount_summary':
         res_model_objs = self.env[action.action.res_model].search(eval(action.domain or '[]'))
         field_compute = action.compute_field_one.name
         note = action.note_one
         note = "%s  %s" % (note, sum([res_model_obj[field_compute] for res_model_obj in res_model_objs]))
         action_url_list['top'].append([note, action.action.view_mode, action.action.res_model, action.domain,
                                        action.context, action.view_id.id, action.action.name, action.action.target])
     else:
         vals_list = ["%s   " % (action.note_one),
                      action.action.view_mode, action.action.res_model,
                      action.domain, action.context, action.view_id.id, action.action.name, action.action.target]
         type_sequence_str = "%s;%s" % (action.report_type_id.sequence, action.report_type_id.name)
         if action_url_list['right'].get(type_sequence_str):
             action_url_list['right'][type_sequence_str].append(vals_list)
         else:
             action_url_list['right'].update({type_sequence_str: [vals_list]})
Ejemplo n.º 51
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(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
Ejemplo n.º 52
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 = eval(lang_grouping)

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

                formatted = decimal_point.join(parts)

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

        return formatted
Ejemplo n.º 53
0
def str2tuple(s):
    return eval('tuple(%s)' % (s or ''))
Ejemplo n.º 54
0
 def _attachment_filename(self, records, report):
     return dict((record.id, eval(report.attachment, {'object': record, 'time': time})) for record in records)
Ejemplo n.º 55
0
    def send(self, auto_commit=False, raise_exception=False):
        """ Sends the selected emails immediately, ignoring their current
            state (mails that have already been sent should not be passed
            unless they should actually be re-sent).
            Emails successfully delivered are marked as 'sent', and those
            that fail to be deliver are marked as 'exception', and the
            corresponding error mail is output in the server logs.

            :param bool auto_commit: whether to force a commit of the mail status
                after sending each mail (meant only for scheduler processing);
                should never be True during normal transactions (default: False)
            :param bool raise_exception: whether to raise an exception if the
                email sending process has failed
            :return: True
        """
        IrMailServer = self.env['ir.mail_server']

        for mail in self:
            try:
                # TDE note: remove me when model_id field is present on mail.message - done here to avoid doing it multiple times in the sub method
                if mail.model:
                    model = self.env['ir.model'].sudo().search([('model', '=', mail.model)])[0]
                else:
                    model = None
                if model:
                    mail = mail.with_context(model_name=model.name)

                # load attachment binary data with a separate read(), as prefetching all
                # `datas` (binary field) could bloat the browse cache, triggerring
                # soft/hard mem limits with temporary data.
                attachments = [(a['datas_fname'], base64.b64decode(a['datas']))
                               for a in mail.attachment_ids.sudo().read(['datas_fname', 'datas'])]

                # specific behavior to customize the send email for notified partners
                email_list = []
                if mail.email_to:
                    email_list.append(mail.send_get_email_dict())
                for partner in mail.recipient_ids:
                    email_list.append(mail.send_get_email_dict(partner=partner))

                # headers
                headers = {}
                bounce_alias = self.env['ir.config_parameter'].get_param("mail.bounce.alias")
                catchall_domain = self.env['ir.config_parameter'].get_param("mail.catchall.domain")
                if bounce_alias and catchall_domain:
                    if mail.model and mail.res_id:
                        headers['Return-Path'] = '%s-%d-%s-%d@%s' % (bounce_alias, mail.id, mail.model, mail.res_id, catchall_domain)
                    else:
                        headers['Return-Path'] = '%s-%d@%s' % (bounce_alias, mail.id, catchall_domain)
                if mail.headers:
                    try:
                        headers.update(eval(mail.headers))
                    except Exception:
                        pass

                # Writing on the mail object may fail (e.g. lock on user) which
                # would trigger a rollback *after* actually sending the email.
                # To avoid sending twice the same email, provoke the failure earlier
                mail.write({
                    'state': 'exception',
                    'failure_reason': _('Error without exception. Probably due do sending an email without computed recipients.'),
                })
                mail_sent = False

                # build an RFC2822 email.message.Message object and send it without queuing
                res = None
                for email in email_list:
                    msg = IrMailServer.build_email(
                        email_from=mail.email_from,
                        email_to=email.get('email_to'),
                        subject=mail.subject,
                        body=email.get('body'),
                        body_alternative=email.get('body_alternative'),
                        email_cc=tools.email_split(mail.email_cc),
                        reply_to=mail.reply_to,
                        attachments=attachments,
                        message_id=mail.message_id,
                        references=mail.references,
                        object_id=mail.res_id and ('%s-%s' % (mail.res_id, mail.model)),
                        subtype='html',
                        subtype_alternative='plain',
                        headers=headers)
                    try:
                        res = IrMailServer.send_email(msg, mail_server_id=mail.mail_server_id.id)
                    except AssertionError as error:
                        if error.message == IrMailServer.NO_VALID_RECIPIENT:
                            # No valid recipient found for this particular
                            # mail item -> ignore error to avoid blocking
                            # delivery to next recipients, if any. If this is
                            # the only recipient, the mail will show as failed.
                            _logger.info("Ignoring invalid recipients for mail.mail %s: %s",
                                         mail.message_id, email.get('email_to'))
                        else:
                            raise
                if res:
                    mail.write({'state': 'sent', 'message_id': res, 'failure_reason': False})
                    mail_sent = True

                # /!\ can't use mail.state here, as mail.refresh() will cause an error
                # see revid:[email protected] in 6.1
                if mail_sent:
                    _logger.info('Mail with ID %r and Message-Id %r successfully sent', mail.id, mail.message_id)
                mail._postprocess_sent_message(mail_sent=mail_sent)
            except MemoryError:
                # prevent catching transient MemoryErrors, bubble up to notify user or abort cron job
                # instead of marking the mail as failed
                _logger.exception(
                    'MemoryError while processing mail with ID %r and Msg-Id %r. Consider raising the --limit-memory-hard startup option',
                    mail.id, mail.message_id)
                raise
            except psycopg2.Error:
                # If an error with the database occurs, chances are that the cursor is unusable.
                # This will lead to an `psycopg2.InternalError` being raised when trying to write
                # `state`, shadowing the original exception and forbid a retry on concurrent
                # update. Let's bubble it.
                raise
            except Exception as e:
                failure_reason = tools.ustr(e)
                _logger.exception('failed sending mail (id: %s) due to %s', mail.id, failure_reason)
                mail.write({'state': 'exception', 'failure_reason': failure_reason})
                mail._postprocess_sent_message(mail_sent=False)
                if raise_exception:
                    if isinstance(e, AssertionError):
                        # get the args of the original error, wrap into a value and throw a MailDeliveryException
                        # that is an except_orm, with name and value as arguments
                        value = '. '.join(e.args)
                        raise MailDeliveryException(_("Mail Delivery Failed"), value)
                    raise

            if auto_commit is True:
                self._cr.commit()
        return True
Ejemplo n.º 56
0
    def get_diagram_info(self, req, id, model, node, connector,
                         src_node, des_node, label, **kw):

        visible_node_fields = kw.get('visible_node_fields',[])
        invisible_node_fields = kw.get('invisible_node_fields',[])
        node_fields_string = kw.get('node_fields_string',[])
        connector_fields = kw.get('connector_fields',[])
        connector_fields_string = kw.get('connector_fields_string',[])

        bgcolors = {}
        shapes = {}
        bgcolor = kw.get('bgcolor','')
        shape = kw.get('shape','')

        if bgcolor:
            for color_spec in bgcolor.split(';'):
                if color_spec:
                    colour, color_state = color_spec.split(':')
                    bgcolors[colour] = color_state

        if shape:
            for shape_spec in shape.split(';'):
                if shape_spec:
                    shape_colour, shape_color_state = shape_spec.split(':')
                    shapes[shape_colour] = shape_color_state

        ir_view = req.session.model('ir.ui.view')
        graphs = ir_view.graph_get(
            int(id), model, node, connector, src_node, des_node, label,
            (140, 180), req.session.context)
        nodes = graphs['nodes']
        transitions = graphs['transitions']
        isolate_nodes = {}
        for blnk_node in graphs['blank_nodes']:
            isolate_nodes[blnk_node['id']] = blnk_node
        else:
            y = map(lambda t: t['y'],filter(lambda x: x['y'] if x['x']==20 else None, nodes.values()))
            y_max = (y and max(y)) or 120

        connectors = {}
        list_tr = []

        for tr in transitions:
            list_tr.append(tr)
            connectors.setdefault(tr, {
                'id': int(tr),
                's_id': transitions[tr][0],
                'd_id': transitions[tr][1]
            })
        connector_tr = req.session.model(connector)
        connector_ids = connector_tr.search([('id', 'in', list_tr)], context=req.session.context)

        data_connectors =connector_tr.read(connector_ids, connector_fields, req.session.context)

        for tr in data_connectors:
            transition_id = str(tr['id'])
            _sourceid, label = graphs['label'][transition_id]
            t = connectors[transition_id]
            t.update(
                source=tr[src_node][1],
                destination=tr[des_node][1],
                options={},
                signal=label
            )

            for i, fld in enumerate(connector_fields):
                t['options'][connector_fields_string[i]] = tr[fld]

        fields = req.session.model('ir.model.fields')
        field_ids = fields.search([('model', '=', model), ('relation', '=', node)], context=req.session.context)
        field_data = fields.read(field_ids, ['relation_field'], req.session.context)
        node_act = req.session.model(node)
        search_acts = node_act.search([(field_data[0]['relation_field'], '=', id)], context=req.session.context)
        data_acts = node_act.read(search_acts, invisible_node_fields + visible_node_fields, req.session.context)

        for act in data_acts:
            n = nodes.get(str(act['id']))
            if not n:
                n = isolate_nodes.get(act['id'], {})
                y_max += 140
                n.update(x=20, y=y_max)
                nodes[act['id']] = n

            n.update(
                id=act['id'],
                color='white',
                options={}
            )
            for color, expr in bgcolors.items():
                if eval(expr, act):
                    n['color'] = color

            for shape, expr in shapes.items():
                if eval(expr, act):
                    n['shape'] = shape

            for i, fld in enumerate(visible_node_fields):
                n['options'][node_fields_string[i]] = act[fld]

        _id, name = req.session.model(model).name_get([id], req.session.context)[0]
        return dict(nodes=nodes,
                    conn=connectors,
                    name=name,
                    parent_field=graphs['node_parent_field'])
Ejemplo n.º 57
0
    def _process_one(self):
        self.ensure_one()
        if self.state != 'todo':
            return False

        activity = self.activity_id
        resource = self.env[self.object_id.model].browse(self.res_id)

        eval_context = {
            'activity': activity,
            'workitem': self,
            'object': resource,
            'resource': resource,
            'transitions': activity.to_ids,
            're': re,
        }
        try:
            condition = activity.condition
            campaign_mode = self.campaign_id.mode
            if condition:
                if not eval(condition, eval_context):
                    if activity.keep_if_condition_not_met:
                        self.write({'state': 'cancelled'})
                    else:
                        self.unlink()
                    return
            result = True
            if campaign_mode in ('manual', 'active'):
                result = activity.process(self)

            values = {'state': 'done'}
            if not self.date:
                values['date'] = fields.Datetime.now()
            self.write(values)

            if result:
                # process _chain
                self.refresh()  # reload
                execution_date = fields.Datetime.from_string(self.date)

                for transition in activity.to_ids:
                    if transition.trigger == 'cosmetic':
                        continue
                    launch_date = False
                    if transition.trigger == 'auto':
                        launch_date = execution_date
                    elif transition.trigger == 'time':
                        launch_date = execution_date + transition._delta()

                    if launch_date:
                        launch_date = fields.Datetime.to_string(launch_date)
                    values = {
                        'date': launch_date,
                        'segment_id': self.segment_id.id,
                        'activity_id': transition.activity_to_id.id,
                        'partner_id': self.partner_id.id,
                        'res_id': self.res_id,
                        'state': 'todo',
                    }
                    workitem = self.create(values)

                    # Now, depending on the trigger and the campaign mode
                    # we know whether we must run the newly created workitem.
                    #
                    # rows = transition trigger \ colums = campaign mode
                    #
                    #           test    test_realtime     manual      normal (active)
                    # time       Y            N             N           N
                    # cosmetic   N            N             N           N
                    # auto       Y            Y             N           Y
                    #

                    run = (transition.trigger == 'auto' and campaign_mode != 'manual') or (transition.trigger == 'time' and campaign_mode == 'test')
                    if run:
                        workitem._process_one()

        except Exception:
            tb = "".join(format_exception(*exc_info()))
            self.write({'state': 'exception', 'error_msg': tb})
Ejemplo n.º 58
0
    def send_mail(self, auto_commit=False):
        """ Process the wizard content and proceed with sending the related
            email(s), rendering any template patterns on the fly if needed. """
        for wizard in self:
            # Duplicate attachments linked to the email.template.
            # Indeed, basic mail.compose.message wizard duplicates attachments in mass
            # mailing mode. But in 'single post' mode, attachments of an email template
            # also have to be duplicated to avoid changing their ownership.
            if wizard.attachment_ids and wizard.composition_mode != 'mass_mail' and wizard.template_id:
                new_attachment_ids = []
                for attachment in wizard.attachment_ids:
                    if attachment in wizard.template_id.attachment_ids:
                        new_attachment_ids.append(attachment.copy({'res_model': 'mail.compose.message', 'res_id': wizard.id}).id)
                    else:
                        new_attachment_ids.append(attachment.id)
                    wizard.write({'attachment_ids': [(6, 0, new_attachment_ids)]})

            # Mass Mailing
            mass_mode = wizard.composition_mode in ('mass_mail', 'mass_post')

            Mail = self.env['mail.mail']
            ActiveModel = self.env[wizard.model if wizard.model else 'mail.thread']
            if wizard.template_id:
                # template user_signature is added when generating body_html
                # mass mailing: use template auto_delete value -> note, for emails mass mailing only
                Mail = Mail.with_context(mail_notify_user_signature=False)
                ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete)
            if not hasattr(ActiveModel, 'message_post'):
                ActiveModel = self.env['mail.thread'].with_context(thread_model=wizard.model)
            if wizard.composition_mode == 'mass_post':
                # do not send emails directly but use the queue instead
                # add context key to avoid subscribing the author
                ActiveModel = ActiveModel.with_context(mail_notify_force_send=False, mail_create_nosubscribe=True)
            # wizard works in batch mode: [res_id] or active_ids or active_domain
            if mass_mode and wizard.use_active_domain and wizard.model:
                res_ids = self.env[wizard.model].search(eval(wizard.active_domain)).ids
            elif mass_mode and wizard.model and self._context.get('active_ids'):
                res_ids = self._context['active_ids']
            else:
                res_ids = [wizard.res_id]

            batch_size = int(self.env['ir.config_parameter'].sudo().get_param('mail.batch_size')) or self._batch_size
            sliced_res_ids = [res_ids[i:i + batch_size] for i in range(0, len(res_ids), batch_size)]

            if wizard.composition_mode == 'mass_mail' or wizard.is_log or (wizard.composition_mode == 'mass_post' and not wizard.notify):  # log a note: subtype is False
                subtype_id = False
            elif wizard.subtype_id:
                subtype_id = wizard.subtype_id.id
            else:
                subtype_id = self.sudo().env.ref('mail.mt_comment', raise_if_not_found=False).id

            for res_ids in sliced_res_ids:
                batch_mails = Mail
                all_mail_values = wizard.get_mail_values(res_ids)
                for res_id, mail_values in all_mail_values.iteritems():
                    if wizard.composition_mode == 'mass_mail':
                        batch_mails |= Mail.create(mail_values)
                    else:
                        ActiveModel.browse(res_id).message_post(
                            message_type=wizard.message_type,
                            subtype_id=subtype_id,
                            **mail_values)

                if wizard.composition_mode == 'mass_mail':
                    batch_mails.send(auto_commit=auto_commit)

        return {'type': 'ir.actions.act_window_close'}