Exemple #1
0
    def send(self, recipients, sender=None, record=None, record_name=None):
        recipient_partners = []
        for recipient in recipients:
            recipient_partners.append((4, recipient.sudo().partner_id.id))

        subtype = None
        if not sender:
            sender = self.env.ref('message_template.user_messages')
            subtype = self.env.ref('message_template.subtype_system_message')

        base_url = self.env['ir.config_parameter'].get_param('web.base.url')

        def link_to(record):
            """
            Create an absolute link to the given record.
            """
            path = '/web#id={}&model={}'.format(record.id, record._name)
            return urljoin(base_url, path)

        # Enable resolution of ${variables} inside body
        template_context = {
            'record': record,
            'context': self.env.context,
            'base_url': base_url,
            'link_to': link_to,
            'site_name': self.env.user.company_id.name,
            'bleach': filters.bleach,
        }
        body_template = mako_template_env.from_string(tools.ustr(self.body))
        body_rendered = body_template.render(template_context)
        subject_template = mako_template_env.from_string(
            tools.ustr(self.subject))
        subject_rendered = subject_template.render(template_context)

        self.env['mail.message'].sudo().create({
            'type':
            'comment',
            'author_id':
            sender.sudo().partner_id.id,
            'partner_ids':
            recipient_partners,
            'model':
            self.model,
            'res_id':
            record and record.id,
            'record_name':
            record_name or (record and record.display_name),
            'subject':
            subject_rendered,
            'body':
            body_rendered,
            'template':
            self.id,
            'subtype_id':
            subtype and subtype.id
        })
Exemple #2
0
 def render_signature_id(self):
     if not self.signature_id:
         return
     mako = mako_template_env.from_string(tools.ustr(self.signature_id.template))
     html = mako.render({'user': self})
     if html != self.signature:
         self.signature = html
 def render_signature_id(self):
     if not self.signature_id:
         return
     mako = mako_template_env.from_string(tools.ustr(self.signature_id.template))
     html = mako.render({'user':self})
     if html != self.signature:
         self.signature = html
Exemple #4
0
    def render_template(self, cr, uid, template, model, res_id, context=None):
        result = ''
        try:
            mako_template_env.autoescape = False
            result = super(email_template,
                           self).render_template(cr, uid, template, model,
                                                 res_id, context)
        finally:
            mako_template_env.autoescape = True

        if (model == 'newsletter.newsletter' and res_id
                and context.get('newsletter_res_id')):

            newsletter = self.pool.get(model).browse(cr,
                                                     uid,
                                                     res_id,
                                                     context=context)
            user = self.pool.get('res.users').browse(cr,
                                                     uid,
                                                     uid,
                                                     context=context)

            result = mako_template_env.from_string(result).render({
                'object':
                self.pool.get(newsletter.type_id.model.model).browse(
                    cr, uid, context.get('newsletter_res_id'), context),
                'user':
                user,
                'ctx':
                context
            })

        return result
Exemple #5
0
    def send(self, recipients, sender=None, record=None, record_name=None):
        recipient_partners = []
        for recipient in recipients:
            recipient_partners.append(
                (4, recipient.partner_id.id)
            )

        subtype = None
        if not sender:
            sender = self.env.ref('message_template.user_messages')
            subtype = self.env.ref('message_template.subtype_system_message')

        # Enable resolution of ${variables} inside body
        body_template = mako_template_env.from_string(tools.ustr(self.body))
        body_rendered = body_template.render({'record': record})

        self.env['mail.message'].sudo().create({
            'type': 'comment',
            'author_id': sender.partner_id.id,
            'partner_ids': recipient_partners,
            'model': self.model,
            'res_id': record and record.id,
            'record_name': record_name or (record and record.name),
            'subject': self.subject,
            'body': body_rendered,
            'template': self.id,
            'subtype_id': subtype and subtype.id
        })
Exemple #6
0
    def render_template_batch(self, cr, uid, template, model, res_ids,
                              context=None, post_process=False):
        result = {}
        try:
            if model == 'newsletter.newsletter':
                mako_template_env.autoescape = False
                post_process = False
            result = super(email_template, self).render_template_batch(
                cr, uid, template, model, res_ids, context=context,
                post_process=post_process)
        finally:
            if model == 'newsletter.newsletter':
                mako_template_env.autoescape = True

        if model == 'newsletter.newsletter' and res_ids and result and\
                context.get('newsletter_res_id'):
            for res_id, rendered in result.iteritems():
                newsletter = self.pool[model].browse(
                    cr, uid, res_id, context=context)
                user = self.pool['res.users'].browse(
                    cr, uid, uid, context=context)
                template = mako_template_env.from_string(rendered)
                result[res_id] = template.render({
                    'object': self.pool[newsletter.type_id.model.model].browse(
                        cr, uid, context.get('newsletter_res_id'), context),
                    'user': user,
                    'ctx': context,
                    'format_tz': lambda dt, tz=False, fmt=False:
                    format_tz(self.pool, cr, uid, dt, tz, fmt, context),
                })

        return result
Exemple #7
0
    def send(self, recipients, sender=None, record=None, record_name=None):
        recipient_partners = []
        for recipient in recipients:
            recipient_partners.append(
                (4, recipient.sudo().partner_id.id)
            )

        subtype = None
        if not sender:
            sender = self.env.ref('message_template.user_messages')
            subtype = self.env.ref('message_template.subtype_system_message')

        base_url = self.env['ir.config_parameter'].get_param('web.base.url')

        def link_to(record):
            """
            Create an absolute link to the given record.
            """
            path = '/web#id={}&model={}'.format(record.id, record._name)
            return urljoin(base_url, path)

        # Enable resolution of ${variables} inside body
        template_context = {
            'record': record,
            'context': self.env.context,
            'base_url': base_url,
            'link_to': link_to,
            'site_name': self.env.user.company_id.name,
            'bleach': filters.bleach,
        }
        body_template = mako_template_env.from_string(tools.ustr(self.body))
        body_rendered = body_template.render(template_context)
        subject_template = mako_template_env.from_string(tools.ustr(self.subject))
        subject_rendered = subject_template.render(template_context)

        self.env['mail.message'].sudo().create({
            'type': 'comment',
            'author_id': sender.sudo().partner_id.id,
            'partner_ids': recipient_partners,
            'model': self.model,
            'res_id': record and record.id,
            'record_name': record_name or (record and record.display_name),
            'subject': subject_rendered,
            'body': body_rendered,
            'template': self.id,
            'subtype_id': subtype and subtype.id
        })
Exemple #8
0
    def render_mako_template_string(self,
                                    template_string,
                                    template_values=None,
                                    user=None):
        template_string = template_string if template_string else u''
        template_values = template_values if template_values else dict()
        assert isinstance(template_values,
                          dict), "values must be a dictionary!"

        # Load the mako template environment
        # ----------------------------------
        try:
            template = mako_template_env.from_string(
                tools.ustr(template_string))
        except Exception as e:
            _logger.error(
                "Could not render e-mail template! Initialization of mako template failed!\n%s"
                % repr(e))
            return u''

        # Prepare the template_vars
        # -------------------------
        req = request
        pool, cr, uid, ctx = req.env[
            'email.template'].pool, req.cr, req.uid, req.context
        # HINT: This 1.) creates a named tuple object with all attributes from the dict and then
        #            2.) assigns the values of the dict to the named_tuple arguments
        #                *values.values() means we unpack the dict (e.g.: {'key1': '3'} will be key1='3')
        # ATTENTION: A NamedTuple will genereate an ._fields just like a regular odoo record!
        #            therefore you could use this in the mako template if you want to show all fields of the record!
        tvalues_object = namedtuple(
            "TemplateValueObject",
            template_values.keys())(*template_values.values())
        # HINT: These variables should be available to all templates (specified in the addon email_template)
        template_vars = {
            'format_tz':
            lambda dt, tz=False, format=False, context=ctx: format_tz(
                pool, cr, uid, dt, tz, format, context),
            'user':
            user if user else req.env.user,
            'ctx':
            ctx,
            'object':
            tvalues_object
        }

        # Render the mako template
        # ------------------------
        try:
            output = template.render(template_vars)
            output = u'' if (not output or output == u'False') else output
        except Exception as e:
            _logger.error('Could not render email template!\n%s' % repr(e))
            return u''

        return output
Exemple #9
0
    def create(self, cr, uid, vals, context=None):
        record = self.pool.get(vals.get('res_model')).browse(cr, uid, vals.get('res_id'))

        mako = mako_template_env.from_string(tools.ustr(vals.get('website_description')))
        website_description = mako.render({'record':record})
        website_description = website_description.replace('template-only-', '')

        vals['website_description'] = website_description
        new_id = super(website_proposal, self).create(cr, uid, vals, context=context)
        return new_id
Exemple #10
0
    def render_template_batch(self,
                              cr,
                              uid,
                              template,
                              model,
                              res_ids,
                              context=None,
                              post_process=False):
        result = {}
        try:
            if model == 'newsletter.newsletter':
                mako_template_env.autoescape = False
                post_process = False
            result = super(email_template, self).render_template_batch(
                cr,
                uid,
                template,
                model,
                res_ids,
                context=context,
                post_process=post_process)
        finally:
            if model == 'newsletter.newsletter':
                mako_template_env.autoescape = True

        if model == 'newsletter.newsletter' and res_ids and result and\
                context.get('newsletter_res_id'):
            for res_id, rendered in result.iteritems():
                newsletter = self.pool[model].browse(cr,
                                                     uid,
                                                     res_id,
                                                     context=context)
                user = self.pool['res.users'].browse(cr,
                                                     uid,
                                                     uid,
                                                     context=context)
                template = mako_template_env.from_string(rendered)
                result[res_id] = template.render({
                    'object':
                    self.pool[newsletter.type_id.model.model].browse(
                        cr, uid, context.get('newsletter_res_id'), context),
                    'user':
                    user,
                    'ctx':
                    context,
                    'format_tz':
                    lambda dt, tz=False, fmt=False: format_tz(
                        self.pool, cr, uid, dt, tz, fmt, context),
                })

        return result
Exemple #11
0
    def create(self, cr, uid, vals, context=None):
        record = self.pool.get(vals.get('res_model')).browse(
            cr, uid, vals.get('res_id'))

        mako = mako_template_env.from_string(
            tools.ustr(vals.get('website_description')))
        website_description = mako.render({'record': record})
        website_description = website_description.replace('template-only-', '')

        vals['website_description'] = website_description
        new_id = super(website_proposal, self).create(cr,
                                                      uid,
                                                      vals,
                                                      context=context)
        return new_id
Exemple #12
0
    def render_template(self, cr, uid, template, model, res_id, context=None):
        result = ''
        try:
            mako_template_env.autoescape = False
            result = super(email_template, self).render_template(
                    cr, uid, template, model, res_id, context)
        finally:
            mako_template_env.autoescape = True

        if (model == 'newsletter.newsletter' and res_id
            and context.get('newsletter_res_id')):
            
            newsletter = self.pool.get(model).browse(cr, uid, res_id,
                    context=context)
            user = self.pool.get('res.users').browse(cr, uid, uid,
                    context=context)

            result = mako_template_env.from_string(result).render({
                'object': self.pool.get(newsletter.type_id.model.model).browse(
                    cr, uid, context.get('newsletter_res_id'), context),
                'user': user,
                'ctx': context})

        return result
Exemple #13
0
    def send(self, recipients, sender=None, record=None, record_name=None):
        recipient_partners = []
        for recipient in recipients:
            recipient_partners.append((4, recipient.partner_id.id))

        subtype = None
        if not sender:
            sender = self.env.ref('message_template.user_messages')
            subtype = self.env.ref('message_template.subtype_system_message')

        # Enable resolution of ${variables} inside body
        body_template = mako_template_env.from_string(tools.ustr(self.body))
        body_rendered = body_template.render({'record': record})

        self.env['mail.message'].sudo().create({
            'type':
            'comment',
            'author_id':
            sender.partner_id.id,
            'partner_ids':
            recipient_partners,
            'model':
            self.model,
            'res_id':
            record and record.id,
            'record_name':
            record_name or (record and record.name),
            'subject':
            self.subject,
            'body':
            body_rendered,
            'template':
            self.id,
            'subtype_id':
            subtype and subtype.id
        })
Exemple #14
0
    def get_data(self, user):

        domain = safe_eval(self.domain, {'user': user})
        won_domain = safe_eval(self.won_domain or '[]', {'user': user})

        field_date_name = self.field_date_id and self.field_date_id.name
        if self.start_date and field_date_name:
            domain.append((field_date_name, '>=', self.start_date))
        if self.end_date and field_date_name:
            domain.append((field_date_name, '<=', self.end_date))

        res = {
            'name': self.name,
            'type': self.type,
            'model': self.model_id.model,
            'domain': str(domain),
            'precision': self.precision,
        }
        obj = self.env[self.model_id.model]
        if self.type == 'list':
            total_count = obj.search_count(domain)
            groups = [{'test': lambda r: True}]
            if self.agenda:
                today = date.today()
                tomorrow = today + timedelta(days=1)

                def r2date(r):
                    d = getattr(r, field_date_name)
                    if d:
                        d = datetime.strptime(
                            d, self.field_date_id.ttype == 'date'
                            and DEFAULT_SERVER_DATE_FORMAT
                            or DEFAULT_SERVER_DATETIME_FORMAT)
                        d = d.date()
                    else:
                        d = date.today()
                    return d

                groups = [
                    {
                        'label': _('Overdue'),
                        'class': 'overdue',
                        'test': lambda r: r2date(r) < today,
                        'mandatory': False,
                    },
                    {
                        'label': _('Today'),
                        'class': 'today',
                        'test': lambda r: r2date(r) == today,
                        'mandatory': True,
                    },
                    {
                        'label': _('Tomorrow'),
                        'class': 'tomorrow',
                        'test': lambda r: r2date(r) == tomorrow,
                        'mandatory': False,
                    },
                    {
                        'label': _('Later'),
                        'class': 'later',
                        'test': lambda r: r2date(r) > tomorrow,
                        'mandatory': False,
                    },
                ]
            for g in groups:
                g['lines'] = []

            res.update({
                'more': self.limit and self.limit < total_count,
                'total_count': total_count,
                'agenda': self.agenda,
                'groups': groups,
            })
            for r in obj.search(domain, limit=self.limit, order=self.order):
                mako = mako_template_env.from_string(tools.ustr(self.content))
                content = mako.render({'record': r})
                r_json = {
                    'id': r.id,
                    #'fields': dict( (f,getattr(r,f)) for f in fields),
                    'display_mode': 'progress',
                    'state': 'inprogress',
                    'completeness': 0,
                    'name': content,
                    'description': '',
                }
                if self.value_field_id:
                    r_json['current'] = getattr(r, self.value_field_id.name)
                    if self.value_field_monetary:
                        r_json['monetary'] = 1
                for g in groups:
                    if g['test'](r):
                        g['lines'].append(r_json)
                        break
            for g in groups:
                del g['test']
        elif self.type == 'funnel':
            stage_ids = []  # [key]
            for group in obj.read_group(domain, [],
                                        [self.stage_field_id.name]):
                key = group[self.stage_field_id.name]
                if isinstance(key, (list, tuple)):
                    key = key[0]
                stage_ids.append(key)

            stages = []  # [{'name':Name, 'id': key}]
            if self.stage_field_id.ttype == 'selection':
                d = dict(self.stage_field_id.selection)
                stages = [{'id': id, 'name': d[id]} for id in stage_ids]
            else:  # many2one
                stage_model = self.stage_field_id.relation
                for r in self.env[stage_model].browse(stage_ids):
                    stages.append({'id': r.id, 'name': r.name_get()[0][1]})

            value_field_name = self.value_field_id.name
            for stage in stages:
                d = copy.copy(domain)
                d.append((self.stage_field_id.name, '=', stage['id']))
                result = obj.read_group(d, [value_field_name], [])
                stage['closed_value'] = result and result[0][
                    value_field_name] or 0.0
                stage['domain'] = str(d)

            # won value
            d = domain + won_domain
            result = obj.read_group(domain, [value_field_name], [])
            won = {
                'name': _('Won'),
                'id': '__won__',
                'closed_value': result and result[0][value_field_name] or 0.0
            }
            stages.append(won)
            cur = 0
            for stage in reversed(stages):
                cur += stage['closed_value']
                stage['abs_value'] = cur
            total_value = stages[0]['abs_value']
            precision = self.precision
            for s in stages:
                s['rel_value'] = round(
                    100 * s['abs_value'] / total_value /
                    precision) * precision if total_value else 100
                # dummy fields
                s['display_mode'] = 'progress'
                s['monetary'] = 1

            res['stages'] = stages
            res['won'] = won
            res['conversion_rate'] = stages[-1]['rel_value']
        elif self.type == 'slice':
            value_field_name = self.value_field_id.name
            for f, d in [('total', domain), ('won', won_domain)]:
                result = obj.read_group(d, [value_field_name], [])
                res[f] = result and result[0][value_field_name] or 0.0

            res['domain'] = str(domain)
            res['won_domain'] = str(won_domain)

            precision = self.precision
            total_value = res['total']
            res['slice'] = round(
                100 * res['won'] / res['total'] /
                precision) * precision if res['total'] else 100
            # dummy fields
            res['display_mode'] = 'progress'
            res['monetary'] = self.value_field_monetary
        return res
    def render_template(self, cr, uid, template, model, res_id, context=None):
        """Render the given template text, replace mako expressions ``${expr}``
           with the result of evaluating these expressions with
           an evaluation context containing:

                * ``user``: browse_record of the current user
                * ``object``: browse_record of the document record this mail is
                              related to
                * ``context``: the context passed to the mail composition wizard

           :param str template: the template text to render
           :param str model: model name of the document record this mail is related to.
           :param int res_id: id of the document record this mail is related to.
        """
        if not template:
            return u""
        if context is None:
            context = {}
        try:
            template = tools.ustr(template)
            record = None
            if res_id:
                record = self.pool.get(model).browse(cr,
                                                     uid,
                                                     res_id,
                                                     context=context)
            user = self.pool.get('res.users').browse(cr,
                                                     uid,
                                                     uid,
                                                     context=context)
            variables = {
                'object': record,
                'user': user,
                'ctx': context,  # context kw would clash with mako internals
            }
            result = mako_template_env.from_string(template).render(variables)
            if result == u"False":
                result = u""
            return result
        except Exception as e:
            logger.exception("failed to render mako template value %r",
                             template)
            logger.exception(e)
            issue_obj = self.pool.get('project.issue')
            for issue_id in issue_obj.find_resource_issues(
                    cr,
                    uid,
                    model,
                    res_id,
                    tags=['email.template', 'error'],
                    create=True,
                    reopen=True,
                    context=context):
                # A message is trigger in a new/open issue
                issue_obj.message_post(
                    cr,
                    uid,
                    issue_id,
                    _('Exception on email.template<br/><b>{0}</b>:<br/>{1}<br/>{2}'
                      ).format(
                          e,
                          traceback.format_exc(limit=10).replace(
                              '\n', '<br/>'),
                          template.replace('<', '&lt;').replace('\n',
                                                                '<br/>')),
                    context=context)
            return u""
Exemple #16
0
    def get_data(self, user):

        domain = safe_eval(self.domain, {'user': user})
        won_domain = safe_eval(self.won_domain or '[]', {'user': user})

        field_date_name = self.field_date_id and self.field_date_id.name
        if self.start_date and field_date_name:
            domain.append((field_date_name, '>=', self.start_date))
        if self.end_date and field_date_name:
            domain.append((field_date_name, '<=', self.end_date))

        res = {
            'name': self.name,
            'type': self.type,
            'model': self.model_id.model,
            'domain': str(domain),
            'precision': self.precision,
        }
        obj = self.env[self.model_id.model]
        if self.type == 'list':
            total_count = obj.search_count(domain)
            groups = [{'test': lambda r: True}]
            if self.agenda:
                today = date.today()
                tomorrow = today + timedelta(days=1)
                def r2date(r):
                    d = getattr(r, field_date_name)
                    if d:
                        d = datetime.strptime(d, self.field_date_id.ttype=='date' and DEFAULT_SERVER_DATE_FORMAT or DEFAULT_SERVER_DATETIME_FORMAT)
                        d = d.date()
                    else:
                        d = date.today()
                    return d
                groups = [
                    {
                        'label': _('Overdue'),
                        'class': 'overdue',
                        'test': lambda r: r2date(r) < today,
                        'mandatory': False,
                    },
                    {
                        'label': _('Today'),
                        'class': 'today',
                        'test': lambda r: r2date(r) == today,
                        'mandatory': True,
                    },
                    {
                        'label': _('Tomorrow'),
                        'class': 'tomorrow',
                        'test': lambda r: r2date(r) == tomorrow,
                        'mandatory': False,
                    },
                    {
                        'label': _('Later'),
                        'class': 'later',
                        'test': lambda r: r2date(r) > tomorrow,
                        'mandatory': False,
                    },
                ]
            for g in groups:
                g['lines'] = []

            res.update({
                'more': self.limit and self.limit < total_count,
                'total_count': total_count,
                'agenda': self.agenda,
                'groups': groups,
            })
            for r in obj.search(domain, limit=self.limit, order=self.order):
                mako = mako_template_env.from_string(tools.ustr(self.content))
                content = mako.render({'record':r})
                r_json = {
                    'id': r.id,
                    #'fields': dict( (f,getattr(r,f)) for f in fields),
                    'display_mode': 'progress',
                    'state': 'inprogress',
                    'completeness': 0,
                    'name': content,
                    'description': '',
                }
                if self.value_field_id:
                    r_json['current'] = getattr(r, self.value_field_id.name)
                    if self.value_field_monetary:
                        r_json['monetary'] = 1
                for g in groups:
                    if g['test'](r):
                        g['lines'].append(r_json)
                        break
            for g in groups:
                del g['test']
        elif self.type == 'funnel':
            stage_ids = [] # [key]
            for group in obj.read_group(domain, [], [self.stage_field_id.name]):
                key = group[self.stage_field_id.name]
                if isinstance(key, (list, tuple)):
                    key = key[0]
                stage_ids.append(key)

            stages = [] # [{'name':Name, 'id': key}]
            if self.stage_field_id.ttype == 'selection':
                d = dict (self.stage_field_id.selection)
                stages = [ {'id':id, 'name':d[id]} for id in stage_ids ]
            else: # many2one
                stage_model = self.stage_field_id.relation
                for r in self.env[stage_model].browse(stage_ids):
                    stages.append({'id': r.id, 'name':r.name_get()[0][1]})

            value_field_name = self.value_field_id.name
            for stage in stages:
                d = copy.copy(domain)
                d.append( (self.stage_field_id.name, '=', stage['id']) )
                result = obj.read_group(d, [value_field_name], [])
                stage['closed_value'] = result and result[0][value_field_name] or 0.0
                stage['domain'] = str(d)

            # won value
            d = domain + won_domain
            result = obj.read_group(domain, [value_field_name], [])
            won = {'name': _('Won'),
                   'id':'__won__',
                   'closed_value': result and result[0][value_field_name] or 0.0
                   }
            stages.append(won)
            cur = 0
            for stage in reversed(stages):
                cur += stage['closed_value']
                stage['abs_value'] = cur
            total_value = stages[0]['abs_value']
            precision = self.precision
            for s in stages:
                s['rel_value'] = round(100*s['abs_value']/total_value/precision)*precision if total_value else 100
                # dummy fields
                s['display_mode'] = 'progress'
                s['monetary'] = 1

            res['stages'] = stages
            res['won'] = won
            res['conversion_rate'] = stages[-1]['rel_value']
        elif self.type == 'slice':
            value_field_name = self.value_field_id.name
            for f,d  in [('total', domain), ('won', won_domain)]:
                result = obj.read_group(d, [value_field_name], [])
                res[f] = result and result[0][value_field_name] or 0.0

            res['domain'] = str(domain)
            res['won_domain'] = str(won_domain)

            precision = self.precision
            total_value = res['total']
            res['slice'] = round(100*res['won']/res['total']/precision)*precision if res['total'] else 100
            # dummy fields
            res['display_mode'] = 'progress'
            res['monetary'] = self.value_field_monetary
        return res