Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create program for sending mail automatically from openerp using python

Tags:

email

openerp

How to create program for sending mail automatically from openerp using python?

I have created openerp module. I am trying to send mail to a client, when client id is generated.

In sale folder in sale.py. When convert lead into client, I want to send mail to client. So in sale.py. I have added following line of code.

self.pool.get('email.template').send_mail(cr, uid, email_template_id, object_id,False, context=context)

I am getting email_Template_id from email_template database.

Explain what is email_template_id, object_id? What is template? What is message?

I am totally confused. Is there any other way to send mail automatically?

Thanks in advance.

like image 791
Bala Avatar asked May 28 '14 09:05

Bala


2 Answers

You can use a server action for that purpose. You can create a server action in OpenERP by accessing Settings »» Technical »» Actions »» Server Actions or creating a XML on your module.

I'll leave here an example of a server action I'm using to send an email to user when an object reaches a certain status on a module I'm developing:

<?xml version="1.0" encoding="UTF-8"?>
<openerp>
    <data>
        <record id="ir_actions_server_send_email_when_closed_nconf" model="ir.actions.server">
            <field name="name">Auto-email when request is closed, not confirmed</field>
            <field name="model_id" ref="model_generic_request"/>
            <field name="state">email</field>
            <field name="type">ir.actions.server</field>
            <field name="condition">True</field>
            <field name="email">object.requestor.email</field>
            <field name="subject">Your request object.name has been closed (not confirmed)</field>
            <field name="message"><![CDATA[
THIS IS AN AUTOMATED EMAIL. DO NOT REPLY.

Hello,

We are here to inform you that the request [[object.name]] you submitted on [[object.request_date]] with the following data:

        | Request - Details
        |=========================
        | Number: [[object.id]]
        |=========================
        | Responsible Person: [[object.responsible_name.name]]
        | Request description: [[object.request_description]]
        | Stating reasons: [[object.stating_reasons]]
        |=========================
        | Notes: [[object.notes]]


Has not been confirmed and is closed.

If you have any question, do not hesitate to contact your supervisor.

Thank you!]]>
            </field>            
        </record>
    </data>
</openerp>

This action is called from workflow. In your case, you can call it when your form is saved (state = draft, maybe?).

So you have to add the call to the server action in your workflow activity definition:

    <record model="workflow.activity" id="act_closed_nconf">
        <field name="wkf_id" ref="wkf_request" />
        <field name="name">request_closed_nconf</field>
        <field name="action_id" ref="ir_actions_server_send_email_when_closed_nconf"/>
        <field name="kind">function</field>
        <field name="action">close_nconf_request()</field>
        <field name="flow_stop">True</field>
    </record>

Hope this helps!

------ A little edit to a more extended answer -----

Ok, I'll try to make a short almost functional example.

In your python file if not already, you'll have to add some states in order to put the workflow working.

class whatever(osv.osv):
    _name='whatever'
    _description='whatever'
    _columns={
        'name': fields.char('whatever', size=64, required=True),
        'state': fields.selection([('draft','Draft'),
            ('sent','Sent'),
            ('closed','Closed'),
            ],
            'Status', readonly=True, track_visibility='onchange',
        ),
        (... some other fields in here...)
    }
    _defaults={
        'state': 'draft',
    }

    #these 3 functions are called by the workflow
    def draft(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'draft'})
        return True

    def send(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'sent'})
        return True

    def close(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'closed'})
        return True    
whatever()

Then, you will have to have a workflow definition that will work on your object, this will be the content of your xml:

<?xml version="1.0"?>
<openerp>
    <data>
        <record model="workflow" id="wkf_whatever">
            <field name="name">whatever.wkf</field>
            <field name="osv">whatever</field>
            <field name="on_create">True</field>
        </record>

        <!-- activities -->
        <record model="workflow.activity" id="act_draft">
            <field name="wkf_id" ref="wkf_whatever" />
            <field name="flow_start">True</field>
            <field name="name">draft</field>
            <field name="action_id" ref="send_automatic_email"/>
            <field name="kind">function</field>
            <field name="action">draft()</field>
        </record>
        <record model="workflow.activity" id="act_send">
            <field name="wkf_id" ref="wkf_whatever" />
            <field name="name">send</field>
            <field name="kind">function</field>
            <field name="action">send()</field>
        </record>
        <record model="workflow.activity" id="act_close">
            <field name="wkf_id" ref="wkf_whatever" />
            <field name="flow_stop">True</field>
            <field name="name">close</field>
            <field name="kind">function</field>
            <field name="action">close()</field>
        </record>

        <!-- transitions -->
        <record model="workflow.transition" id="whatever_t1">
            <field name="act_from" ref="act_draft" />
            <field name="act_to" ref="act_send" />
            <field name="signal">draft</field>
        </record>
        <record model="workflow.transition" id="whatever_t2">
            <field name="act_from" ref="act_send" />
            <field name="act_to" ref="act_close" />
            <field name="signal">close</field>
        </record>
    </data>
</openerp>

The line <field name="action_id" ref="send_automatic_email"/> in the declaration of the activity calls the server action with id "send_automatic_email"

And your action server:

<?xml version="1.0" encoding="UTF-8"?>
<openerp>
    <data>
        <record id="send_automatic_email" model="ir.actions.server">
            <field name="name">Send automatic email</field>
            <field name="model_id" ref="model_whatever"/>
            <field name="state">email</field>
            <field name="type">ir.actions.server</field>
            <field name="condition">True</field>
            <field name="email">object.requestor.email</field>
            <field name="subject">Your whatever: object.name has been created</field>
            <field name="message"><![CDATA[
THIS IS AN AUTOMATED EMAIL. DO NOT REPLY.

Hello,

bla bla bla bla

In here you will write whatever you want, and can access to data stored in your database with, for example [[object.name]] to access the field "name"

            </field>            
        </record>
    </data>
</openerp>

With these 3 files (and some changes in it!) you should be able to do what you want.

Don't forget that, you have to restart OpenERP server (in order to recompile your changes in python files) and to update your module to load the XML files!

Good luck!

-- Almost forgot!

In your xml view file you have to add these buttons in your form view to call the workflow actions:

<header>
    <button name="send" class="oe_highlight" string="Send" type="workflow" states="draft"/>
    <button name="close" class="oe_highlight" string="Close" type="workflow" states="sent"/>
    <field name="state" widget="statusbar" statusbar_visible="draft,sent,closed" />
</header>
like image 98
Filipe Castanheira Avatar answered Sep 19 '22 04:09

Filipe Castanheira


If you want to send an HTML email, the only way I have found is to send an email template via a server action.

Once you have the template created, discover it's template id by viewing the template and seeing what the id parameter is in the URL.

Then create a new server action, set the object to match the template and set the type to python code. Insert the following code:

self.pool.get('email.template').send_mail(
    cr, uid, <TEMPLATE_ID>, context['active_id'],True, context=context)

Replacing <TEMPLATE_ID> with the appropriate template id.

Just explaining some of the other fields

  • context['active_id'] gives the current id of the lead/invoice/etc being used to create the template with
  • The 5th value True forces the email to be sent immediately rather than adding it to the queue. It would be better to leave as False but due to a bug in version 7, it can lose email addresses when being added to the queue.

You can look in addons/email_template/email_template.py and search for the send_mail function for further information.

like image 44
Daryl Van Sittert Avatar answered Sep 23 '22 04:09

Daryl Van Sittert