Karl Hunt
Karl Hunt

Reputation: 163

Adding Odoo server action to custom module

I have a custom module that I have written for Odoo V8 that adds various fields etc to different forms and adds a few controllers etc.

I now need to add a server action but the documentation seems really poor in this regard.

I have a function in my models.py under an inherited class.

class res_partner(osv.osv):
#update Jira customer list (called on update/save of res.partner)
def updatejira(self):
    r = requests.post('http://10.10.15.39:4000',data='Worked!')

I want to be able to call this function to make a request out to Jira to update its customer list if a customer is created or update.

I have add this to my templates.xml

<record model="ir.actions.server" id="update_jira">
    <field name="name">Res Partner Server Action</field>
    <field name="model_id" ref="model_res_partner"/>
    <field name="condition">True</field>
    <field name="code">
        self.updatejira()
    </field>
</record>

Am I going about this in the right way? I wan't to do this in a module rather than in the UI. But again the documentation is sparse and does not really include much in the way of examples.

Thanks

@miw

like this?

import requests
from openerp import models, api


class res_partner(models.Model):
    #_name = "ResPartnerChange"
    _inherit = "res.partner"

    def update_jira(self):
        r = requests.post('http://10.10.15.39:4000',data='Worked!')
        f = open("test.log","a")
        f.write(r.text)
        return r.text

    def write(self, vals):
        res = super(extendedProject, self).write(vals)
        for p in self:
            self.update_jira()
        return res

res_partner()

This Doesn't appear to work either.

EDIT --------

Thanks for your help so far. This is my latest attempt. I can get the server to call the update_jira function if I decorate it with @api.onchange although that gets called all the time. So I tried to overwrite the write function to call update_jira. But it doesn't seem to get called. What am I doing wrong?

__author__ = 'karl'
import requests
import json
from openerp import models, api

class ResPartnerChange(models.Model):

    _inherit = "res.partner"

    def update_jira(self):
        if self.jira_id == 0: #If the ID is 0 then the customer does not exist so create it
            H = {'Content-Type':'application/json'}
            customer = {
              "optionvalue": str(self.name),
              "id": 0,
              "sequence": 0,
              "disabled": 'false',
              "childOptions": [
                {}
              ]
            }
            req = requests.post('https://jira.example.com/rest/jiracustomfieldeditorplugin/1.1/user/customfieldoption/customfield_10128', auth=('user','pass'), headers=H, data=json.dumps(customer))

            #store the json responce from Jira
            jdata = json.loads(req.text)

            #Change the Jira ID value to the received one
            # res = {
            # 'value': {
            #
            #     'jira_id': jdata['id']
            #         }
            # }
            vals = []
            vals['jira_id'] = jdata['id']

        else:
            #update jira customer
            data = self.name, self.jira_id, self.active
            pass
        return vals

    def write(self):
        vals = self.update_jira()
        res = super(ResPartnerChange, self).write(vals)
        return res

ResPartnerChange()

Upvotes: 2

Views: 4829

Answers (2)

Karl Hunt
Karl Hunt

Reputation: 163

So I figured it all out. I am not overriding the write method. Instead I am using the @api.constrains method decorator which is only activated if the create or write methods are called.

If anyone is interested here is my code. On saving of an Odoo customer my method gets called then verifies that it is a customer and not a supplier,user etc (they all use res.partner). Then it does a quick logic test to see if the customer is new (jira id 0) or existing (something other than 0). Depending on which it is, it calls the relevant Jira API to create or update the custom fields that store my customer details.

thanks to @miw who pointed me in the right direction.

 __author__ = 'karl'
import requests
import json
from openerp import models, api
import logging
_logger = logging.getLogger(__name__)

    class ResPartnerChange(models.Model):

        _inherit = "res.partner"
        @api.constrains('name','active')
        def update_jira(self):
            #Only apply to customers not suppliers users etc as they all use the res.partner model
            if self.customer == True:

                if self.jira_id == 0: #If the ID is 0 then the jira customer does not exist so create it
                    _logger.info('Not a Customer yet - Creating Jira Customer')
                    H = {'Content-Type':'application/json'}
                    customer = {
                      "optionvalue": str(self.name),
                      "id": 0,
                      "sequence": 0,
                      "disabled": 'false',
                      "childOptions": [
                        {}
                      ]
                    }
                    req = requests.post('https://example.com/rest/jiracustomfieldeditorplugin/1.1/user/customfieldoption/customfield_10128', auth=('apiuser','apipass'), headers=H, data=json.dumps(customer))
                    _logger.info(req.text)
                    #store the json responce from Jira
                    jdata = json.loads(req.text)

                    #create values dictionary
                    vals = {}
                    vals['jira_id'] = jdata['id']
                    self.write(vals)

                else:
                    #update jira customer
                    _logger.info('Existing Customer - Updating Jira Customer')
                    vals = {}
                    vals['name'] = self.name
                    vals['active'] = self.active
                    if self.active:
                        disabled = "false"
                    else:
                        disabled = "true"
                    H = {'Content-Type':'application/json'}
                    customer = {
                      "optionvalue": str(self.name),
                      "id": str(self.jira_id),
                      "sequence": 0,
                      "disabled": disabled,
                      "childOptions": [
                        {}
                      ]
                    }
                    req = requests.put('https://example.com/rest/jiracustomfieldeditorplugin/1.1/user/customfieldoption/customfield_10128/'+str(self.jira_id), auth=('apiuser','apipass'), headers=H, data=json.dumps(customer))
                    _logger.info(req.text)

                return True


            else:
                return True


    ResPartnerChange()

Upvotes: 2

miw
miw

Reputation: 764

I'm not sure you are going into the right direction. Any python code (well, most...) is executed in the Odoo server, not in the Browser/UI. So it may make more sense for you to create a button of type "object" with name="method_name", which will then do your trick to call to Jira.

Another option is to override the write() method in your subclass to add your call like so:

    def write(self, vals):
        res = super(extendedProject, self).write(vals)
        for p in self:
            # do the call to JIRA here for each partner p, using p.field1, p.field2 etc. 
        return res

vals is a dictionary with the modified values to store; self is a recordset with all records to store the values to. Note that the transaction in Odoo may still be rolled back after returning from your call to write.

Lastly, you can try creating a server action under Settings > Technical > Actions > Server Actions first, interactively. This would allow for immediate feedback / testing. Note that server actions are executed without a specific object context, but based on timers.

Here's a snippet of documentation from that form:

# Available locals:
#  - time, datetime, dateutil: Python libraries
#  - env: Odoo Environement
#  - model: Model of the record on which the action is triggered
#  - object: Record on which the action is triggered if there is one, otherwise None
#  - workflow: Workflow engine
#  - Warning: Warning Exception to use with raise

With that you will need to modify your code such that it first locates the res.partners which to push to Jira, then loop on them and push to Jira for each partner.

Upvotes: 1

Related Questions