You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							670 lines
						
					
					
						
							31 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							670 lines
						
					
					
						
							31 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								################################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
							 | 
						|
								#    Author: Gokul P I (odoo@cybrosys.com)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
							 | 
						|
								#
							 | 
						|
								#    This program is distributed in the hope that it will be useful,
							 | 
						|
								#    but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
								#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						|
								#    GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								################################################################################
							 | 
						|
								import base64
							 | 
						|
								import json
							 | 
						|
								from datetime import datetime
							 | 
						|
								import requests
							 | 
						|
								from requests.auth import HTTPBasicAuth
							 | 
						|
								from odoo import api, fields, models, _
							 | 
						|
								from odoo.exceptions import ValidationError
							 | 
						|
								from odoo.tools import html2plaintext
							 | 
						|
								
							 | 
						|
								# The Header parameters
							 | 
						|
								HEADERS = {'Accept': 'application/json', 'Content-Type': 'application/json'}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class ProjectProject(models.Model):
							 | 
						|
								    """
							 | 
						|
								    This class is inherited for adding some extra field and override the
							 | 
						|
								    create and write function also to add function to show sprint
							 | 
						|
								    Methods:
							 | 
						|
								        create(vals_list):
							 | 
						|
								            extends create() to export project to Jira
							 | 
						|
								        write(vals):
							 | 
						|
								            extends write() to update corresponding project in Jira
							 | 
						|
								    """
							 | 
						|
								    _inherit = 'project.project'
							 | 
						|
								
							 | 
						|
								    project_id_jira = fields.Integer(string='Jira Project ID',
							 | 
						|
								                                     help='Corresponding project id of Jira.',
							 | 
						|
								                                     readonly=True)
							 | 
						|
								    jira_project_key = fields.Char(string='Jira Project Key',
							 | 
						|
								                                   help='Corresponding project key of Jira.',
							 | 
						|
								                                   readonly=True)
							 | 
						|
								    sprint_active = fields.Boolean(string='Sprint active',
							 | 
						|
								                                   help='To show sprint smart button.')
							 | 
						|
								    board_id_jira = fields.Integer(string='Jira Board ID',
							 | 
						|
								                                   help='Corresponding Board id of Jira.',
							 | 
						|
								                                   readonly=True)
							 | 
						|
								
							 | 
						|
								    def action_get_sprint(self):
							 | 
						|
								        """Getting sprint inside the project"""
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'name': 'Sprints',
							 | 
						|
								            'view_mode': 'tree,form',
							 | 
						|
								            'res_model': 'jira.sprint',
							 | 
						|
								            'context': {'default_project_id': self.id},
							 | 
						|
								            'domain': [('project_id', '=', self.id)],
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    @api.model_create_multi
							 | 
						|
								    def create(self, vals_list):
							 | 
						|
								        """ Overrides create method of project to export project to Jira """
							 | 
						|
								        self = self.with_context(mail_create_nosubscribe=True)
							 | 
						|
								        projects = super().create(vals_list)
							 | 
						|
								        jira_connection = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								            'odoo_jira_connector.connection')
							 | 
						|
								        if jira_connection:
							 | 
						|
								            jira_url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.url', False)
							 | 
						|
								            user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.user_id_jira', False)
							 | 
						|
								            password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.api_token', False)
							 | 
						|
								            auth = HTTPBasicAuth(user, password)
							 | 
						|
								            project_headers = {'Accept': 'application/json'}
							 | 
						|
								            response = requests.request(
							 | 
						|
								                'GET', jira_url + '/rest/api/3/project/',
							 | 
						|
								                headers=project_headers, auth=auth)
							 | 
						|
								            projects_json = json.dumps(
							 | 
						|
								                json.loads(response.text), sort_keys=True, indent=4,
							 | 
						|
								                separators=(',', ': '))
							 | 
						|
								            project_json = json.loads(projects_json)
							 | 
						|
								            name_list = [project['name'] for project in project_json]
							 | 
						|
								            key = projects.name.upper()
							 | 
						|
								            project_key = key[:3] + '1' + key[-3:]
							 | 
						|
								            project_keys = project_key.replace(' ', '')
							 | 
						|
								            auth = HTTPBasicAuth(user, password)
							 | 
						|
								            project_payload = {
							 | 
						|
								                'name': projects.name, 'key': project_keys,
							 | 
						|
								                'templateKey': 'com.pyxis.greenhopper.jira:gh-simplified'
							 | 
						|
								                               '-kanban-classic'
							 | 
						|
								            }
							 | 
						|
								            if projects.name not in name_list:
							 | 
						|
								                response = requests.request(
							 | 
						|
								                    'POST', jira_url + 'rest/simplified/latest/project',
							 | 
						|
								                    data=json.dumps(project_payload),
							 | 
						|
								                    headers=HEADERS, auth=auth)
							 | 
						|
								                data = response.json()
							 | 
						|
								                if 'projectId' in data:
							 | 
						|
								                    projects.write({'project_id_jira': data['projectId'],
							 | 
						|
								                                    'jira_project_key': data['projectKey']})
							 | 
						|
								                    self.env['ir.config_parameter'].sudo().set_param(
							 | 
						|
								                        'import_project_count', int(
							 | 
						|
								                            self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                                'import_project_count')) + 1)
							 | 
						|
								
							 | 
						|
								                elif 'errors' in data and 'projectName' in data['errors']:
							 | 
						|
								                    raise ValidationError(
							 | 
						|
								                        "A project with this name already exists. Please "
							 | 
						|
								                        "rename the project.")
							 | 
						|
								                elif 'errors' in data and 'projectKey' in data['errors']:
							 | 
						|
								                    raise ValidationError(data['errors']['projectKey'])
							 | 
						|
								        return projects
							 | 
						|
								
							 | 
						|
								    def write(self, vals):
							 | 
						|
								        """ Overrides the write method of project.project to update project
							 | 
						|
								        name in Jira when we update the project in Odoo"""
							 | 
						|
								        jira_connection = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								            'odoo_jira_connector.connection')
							 | 
						|
								        if jira_connection:
							 | 
						|
								            for project in self:
							 | 
						|
								                jira_url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.url')
							 | 
						|
								                user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.user_id_jira')
							 | 
						|
								                password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.api_token')
							 | 
						|
								                auth = (user, password)
							 | 
						|
								                headers = {
							 | 
						|
								                    "Accept": "application/json",
							 | 
						|
								                    "Content-Type": "application/json"
							 | 
						|
								                }
							 | 
						|
								                url = (f"{jira_url}/rest/api/3/project/"
							 | 
						|
								                       f"{project.jira_project_key}")
							 | 
						|
								                payload = json.dumps({
							 | 
						|
								                    "name": vals.get('name'),
							 | 
						|
								                })
							 | 
						|
								                payload_json = json.loads(payload)
							 | 
						|
								                response = requests.get(
							 | 
						|
								                    url,
							 | 
						|
								                    headers=headers,
							 | 
						|
								                    auth=auth)
							 | 
						|
								                data = response.json()
							 | 
						|
								                if 'name' in data:
							 | 
						|
								                    if data['name'] != payload_json['name']:
							 | 
						|
								                        requests.request(
							 | 
						|
								                            "PUT",
							 | 
						|
								                            url, data=payload, headers=headers, auth=auth)
							 | 
						|
								                else:
							 | 
						|
								                    requests.request(
							 | 
						|
								                        "PUT",
							 | 
						|
								                        url, data=payload, headers=headers, auth=auth)
							 | 
						|
								            return super(ProjectProject, self).write(vals)
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class ProjectTask(models.Model):
							 | 
						|
								    """
							 | 
						|
								    This class is inherited for adding some extra field and override the
							 | 
						|
								        create function
							 | 
						|
								        Methods:
							 | 
						|
								            create(vals_list):
							 | 
						|
								                extends create() to export tasks to Jira
							 | 
						|
								            unlink():
							 | 
						|
								                extends unlink() to delete a task in Jira when we delete the
							 | 
						|
								                task in Odoo
							 | 
						|
								            write(vals):
							 | 
						|
								                extends write() to update a task in Jira when we update the
							 | 
						|
								                task in Odoo
							 | 
						|
								    """
							 | 
						|
								    _inherit = 'project.task'
							 | 
						|
								
							 | 
						|
								    task_id_jira = fields.Char(string='Jira Task ID', help='Task id of Jira.',
							 | 
						|
								                               readonly=True)
							 | 
						|
								    sprint_id = fields.Many2one('jira.sprint',
							 | 
						|
								                                help="Sprint of this task.", readonly=True)
							 | 
						|
								    task_sprint_active = fields.Boolean(string="Active Sprint",
							 | 
						|
								                                        compute="_compute_task_sprint_active",
							 | 
						|
								                                        store=True,
							 | 
						|
								                                        help="Boolean field to check whether "
							 | 
						|
								                                             "the sprint is active or not.")
							 | 
						|
								
							 | 
						|
								    @api.depends('project_id.sprint_active')
							 | 
						|
								    def _compute_task_sprint_active(self):
							 | 
						|
								        """compute function to make sprint_id invisible by changing
							 | 
						|
								        'task_sprint_active' field to true"""
							 | 
						|
								        for rec in self:
							 | 
						|
								            if rec.project_id.sprint_active:
							 | 
						|
								                rec.task_sprint_active = True
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def create(self, vals_list):
							 | 
						|
								        """ Override the create method of tasks to export tasks to Jira """
							 | 
						|
								        res = super(ProjectTask, self).create(vals_list)
							 | 
						|
								        jira_connection = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								            'odoo_jira_connector.connection')
							 | 
						|
								        if jira_connection:
							 | 
						|
								            jira_url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.url')
							 | 
						|
								            user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.user_id_jira')
							 | 
						|
								            password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.api_token')
							 | 
						|
								            query = {'jql': 'project = %s' % res.project_id.jira_project_key}
							 | 
						|
								            requests.get(jira_url + 'rest/api/3/search', headers=HEADERS,
							 | 
						|
								                         params=query, auth=(user, password))
							 | 
						|
								            if not res.task_id_jira:
							 | 
						|
								                payload = json.dumps({
							 | 
						|
								                    'fields': {
							 | 
						|
								                        'project': {'key': res.project_id.jira_project_key},
							 | 
						|
								                        'summary': res.name,
							 | 
						|
								                        'description': res.description,
							 | 
						|
								                        'issuetype': {'name': 'Task'}
							 | 
						|
								                    }
							 | 
						|
								                })
							 | 
						|
								                response = requests.post(
							 | 
						|
								                    jira_url + '/rest/api/2/issue', headers=HEADERS,
							 | 
						|
								                    data=payload, auth=(user, password))
							 | 
						|
								                data = response.json()
							 | 
						|
								                res.task_id_jira = str(data.get('key'))
							 | 
						|
								                self.env['ir.config_parameter'].sudo().set_param(
							 | 
						|
								                    'export_task_count', int(
							 | 
						|
								                        self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                            'export_task_count')) + 1)
							 | 
						|
								        return res
							 | 
						|
								
							 | 
						|
								    def unlink(self):
							 | 
						|
								        """ Overrides the unlink method of task to delete a task in Jira when
							 | 
						|
								        we delete the task in Odoo """
							 | 
						|
								        for task in self:
							 | 
						|
								            if task.stage_id and task.stage_id.fold:
							 | 
						|
								                raise Warning(_('You cannot delete a task in a folded stage.'))
							 | 
						|
								            jira_connection = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.connection')
							 | 
						|
								            if jira_connection:
							 | 
						|
								                jira_url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.url', '')
							 | 
						|
								                user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.user_id_jira')
							 | 
						|
								                password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.api_token')
							 | 
						|
								                if task.task_id_jira:
							 | 
						|
								                    requests.delete(
							 | 
						|
								                        jira_url + '/rest/api/3/issue/' + task.task_id_jira,
							 | 
						|
								                        headers=HEADERS, auth=(user, password))
							 | 
						|
								        return super(ProjectTask, self).unlink()
							 | 
						|
								
							 | 
						|
								    def write(self, vals):
							 | 
						|
								        """ Overrides the write method of task to update a task's name in
							 | 
						|
								        Jira when we update the task in Odoo"""
							 | 
						|
								        jira_connection = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								            'odoo_jira_connector.connection')
							 | 
						|
								
							 | 
						|
								        if jira_connection:
							 | 
						|
								            jira_url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.url', '')
							 | 
						|
								            user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.user_id_jira')
							 | 
						|
								            password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.api_token')
							 | 
						|
								
							 | 
						|
								            for task in self:
							 | 
						|
								                if task.task_id_jira and 'name' in vals:
							 | 
						|
								                    new_task_name = vals['name']
							 | 
						|
								                    payload = {
							 | 
						|
								                        "fields": {
							 | 
						|
								                            "summary": new_task_name
							 | 
						|
								                        }
							 | 
						|
								                    }
							 | 
						|
								                    requests.put(
							 | 
						|
								                        jira_url + '/rest/api/3/issue/' + task.task_id_jira,
							 | 
						|
								                        json=payload, headers=HEADERS, auth=(user, password))
							 | 
						|
								        return super(ProjectTask, self).write(vals)
							 | 
						|
								
							 | 
						|
								    def webhook_data_handle(self, jira_data, webhook_event):
							 | 
						|
								        """Function to Handle Jira Data Received from Webhook"""
							 | 
						|
								        if webhook_event == 'project_created':
							 | 
						|
								            self.create_project(jira_data)
							 | 
						|
								        elif webhook_event == 'project_updated':
							 | 
						|
								            self.update_project(jira_data)
							 | 
						|
								        elif webhook_event == 'project_soft_deleted':
							 | 
						|
								            self.delete_project(jira_data)
							 | 
						|
								        elif webhook_event == 'jira:issue_created':
							 | 
						|
								            self.create_task(jira_data)
							 | 
						|
								        elif webhook_event == 'jira:issue_deleted':
							 | 
						|
								            self.delete_task(jira_data)
							 | 
						|
								        elif webhook_event == 'comment_created':
							 | 
						|
								            self.create_comment(jira_data)
							 | 
						|
								        elif webhook_event == 'comment_deleted':
							 | 
						|
								            self.delete_comment(jira_data)
							 | 
						|
								        elif webhook_event == 'user_created':
							 | 
						|
								            self.create_user(jira_data)
							 | 
						|
								        elif webhook_event == 'user_deleted':
							 | 
						|
								            self.delete_user(jira_data)
							 | 
						|
								        elif webhook_event == 'board_configuration_changed':
							 | 
						|
								            self.board_configuration_change(jira_data)
							 | 
						|
								        elif webhook_event == 'jira:issue_updated':
							 | 
						|
								            self.update_task(jira_data)
							 | 
						|
								        elif webhook_event == 'attachment_deleted':
							 | 
						|
								            self.delete_attachment(jira_data)
							 | 
						|
								        elif webhook_event == 'sprint_started':
							 | 
						|
								            self.sprint_started(jira_data)
							 | 
						|
								        elif webhook_event == 'sprint_closed':
							 | 
						|
								            self.sprint_closed(jira_data)
							 | 
						|
								
							 | 
						|
								    def create_project(self, jira_data):
							 | 
						|
								        """function to create project based on webhook response"""
							 | 
						|
								        jira_project = jira_data['project']
							 | 
						|
								        existing_project = self.env['project.project'].sudo().search(
							 | 
						|
								            [('project_id_jira', '=', jira_project['id'])])
							 | 
						|
								        values = {
							 | 
						|
								            'name': jira_project['name'],
							 | 
						|
								            'project_id_jira': jira_project['id'],
							 | 
						|
								            'jira_project_key': jira_project['key']
							 | 
						|
								        }
							 | 
						|
								        if not existing_project:
							 | 
						|
								            imported_project = self.env['project.project'].sudo().create(
							 | 
						|
								                values)
							 | 
						|
								            url = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.url')
							 | 
						|
								            user = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.user_id_jira')
							 | 
						|
								            password = self.env['ir.config_parameter'].sudo().get_param(
							 | 
						|
								                'odoo_jira_connector.api_token')
							 | 
						|
								            auth = HTTPBasicAuth(user, password)
							 | 
						|
								            headers = {
							 | 
						|
								                "Accept": "application/json"
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            response = requests.request(
							 | 
						|
								                "GET",
							 | 
						|
								                url + "/rest/api/3/project/" + jira_project['key'],
							 | 
						|
								                headers=headers,
							 | 
						|
								                auth=auth
							 | 
						|
								            )
							 | 
						|
								            data = response.json()
							 | 
						|
								            style_value = data.get('style')
							 | 
						|
								            if style_value == 'classic':
							 | 
						|
								                imported_project.write({'sprint_active': False})
							 | 
						|
								            else:
							 | 
						|
								                imported_project.write({'sprint_active': True})
							 | 
						|
								
							 | 
						|
								    def update_project(self, jira_data):
							 | 
						|
								        """function to update project based on webhook response"""
							 | 
						|
								        project_id = jira_data['project']['id']
							 | 
						|
								        existing_project = self.env['project.project'].sudo().search(
							 | 
						|
								            [('project_id_jira', '=', project_id)])
							 | 
						|
								        if existing_project.name != jira_data['project']['name']:
							 | 
						|
								            existing_project.write({'name': jira_data['project']['name']})
							 | 
						|
								
							 | 
						|
								    def delete_project(self, jira_data):
							 | 
						|
								        """function to delete project based on webhook response"""
							 | 
						|
								        project_id = (jira_data['project']['id'])
							 | 
						|
								        self.env['project.project'].sudo().search(
							 | 
						|
								            [('project_id_jira', '=', project_id)]).unlink()
							 | 
						|
								
							 | 
						|
								    def create_task(self, jira_data):
							 | 
						|
								        """function to create task based on webhook response"""
							 | 
						|
								        task_name = jira_data['issue']['fields']['summary']
							 | 
						|
								        task_key = jira_data['issue']['key']
							 | 
						|
								        jira_project_id = jira_data['issue']['fields']['project']['id']
							 | 
						|
								        project = self.env['project.project'].sudo().search(
							 | 
						|
								            [('project_id_jira', '=', int(jira_project_id))])
							 | 
						|
								        existing_task = self.env['project.task'].sudo().search(
							 | 
						|
								            [('task_id_jira', '=', jira_data['issue']['key'])])
							 | 
						|
								        if not existing_task:
							 | 
						|
								            self.env['project.task'].sudo().create({
							 | 
						|
								                'project_id': project.id,
							 | 
						|
								                'name': task_name,
							 | 
						|
								                'task_id_jira': task_key
							 | 
						|
								            })
							 | 
						|
								
							 | 
						|
								    def delete_task(self, jira_data):
							 | 
						|
								        """function to delete task based on webhook response"""
							 | 
						|
								        task_key = jira_data['issue']['key']
							 | 
						|
								        self.env['project.task'].sudo().search(
							 | 
						|
								            [('task_id_jira', '=', task_key)]).unlink()
							 | 
						|
								
							 | 
						|
								    def create_comment(self, jira_data):
							 | 
						|
								        """function to create comment based on webhook response"""
							 | 
						|
								        text = jira_data['comment']['body']
							 | 
						|
								        task_key = jira_data['issue']['key']
							 | 
						|
								        task = self.env['project.task'].sudo().search(
							 | 
						|
								            [('task_id_jira', '=', task_key)])
							 | 
						|
								        existing_message = self.env['mail.message'].sudo().search(
							 | 
						|
								            ['&', ('res_id', '=', task.id),
							 | 
						|
								             ('model', '=', 'project.task'),
							 | 
						|
								             ('message_id_jira', '=', jira_data['comment']['id'])])
							 | 
						|
								        if not existing_message:
							 | 
						|
								            input_string = str(text)
							 | 
						|
								            parts = input_string.split(".")
							 | 
						|
								            if len(parts) > 1:
							 | 
						|
								                body = parts[1]
							 | 
						|
								            else:
							 | 
						|
								                body = parts[0]
							 | 
						|
								            self.env['mail.message'].sudo().create(
							 | 
						|
								                {"body": html2plaintext(body),
							 | 
						|
								                 'model': 'project.task',
							 | 
						|
								                 'res_id': task.id,
							 | 
						|
								                 'message_id_jira': jira_data['comment']['id']
							 | 
						|
								                 })
							 | 
						|
								
							 | 
						|
								    def delete_comment(self, jira_data):
							 | 
						|
								        """function to delete comment based on webhook response"""
							 | 
						|
								        self.env['mail.message'].sudo().search(
							 | 
						|
								            [('message_id_jira', '=',
							 | 
						|
								              jira_data['comment']['id'])]).unlink()
							 | 
						|
								
							 | 
						|
								    def create_user(self, jira_data):
							 | 
						|
								        """function to create user based on webhook response"""
							 | 
						|
								        existing_user = self.env['res.user']. \
							 | 
						|
								            search([('jira_user_key', '=', jira_data['user']['accountId'])])
							 | 
						|
								        if not existing_user:
							 | 
						|
								            self.env['res.users'].sudo().create({
							 | 
						|
								                'login': jira_data['user']['displayName'],
							 | 
						|
								                'name': jira_data['user']['displayName'],
							 | 
						|
								                'jira_user_key': jira_data['user']['accountId']
							 | 
						|
								            })
							 | 
						|
								
							 | 
						|
								    def delete_user(self, jira_data):
							 | 
						|
								        """function to delete user based on webhook response"""
							 | 
						|
								        self.env['res.users'].sudo().search(
							 | 
						|
								            [('jira_user_key', '=', jira_data['accountId'])]).unlink()
							 | 
						|
								
							 | 
						|
								    def board_configuration_change(self, jira_data):
							 | 
						|
								        """function to create stages or write project into stages based on
							 | 
						|
								        webhook response"""
							 | 
						|
								        columns = jira_data['configuration']['columnConfig']['columns']
							 | 
						|
								        if jira_data['configuration'].get('location'):
							 | 
						|
								            project_key = jira_data['configuration']['location']['key']
							 | 
						|
								            project = self.env['project.project'].sudo().search(
							 | 
						|
								                [('jira_project_key', '=', project_key)])
							 | 
						|
								            sequence_value = 1
							 | 
						|
								            for column in columns:
							 | 
						|
								                if column['name'] != 'Backlog':
							 | 
						|
								                    stages_jira_id = column['statuses'][0]['id']
							 | 
						|
								                    existing_stage = self.env[
							 | 
						|
								                        'project.task.type'].sudo().search(
							 | 
						|
								                        [('stages_jira_id', '=', stages_jira_id)])
							 | 
						|
								                    existing_stage.write({'project_ids': project,
							 | 
						|
								                                          'sequence': sequence_value})
							 | 
						|
								                    if not existing_stage:
							 | 
						|
								                        values = {
							 | 
						|
								                            'name': column['name'],
							 | 
						|
								                            'stages_jira_id': stages_jira_id,
							 | 
						|
								                            'jira_project_key': project_key,
							 | 
						|
								                            'project_ids': project,
							 | 
						|
								                            'sequence': sequence_value,
							 | 
						|
								                        }
							 | 
						|
								                        self.env['project.task.type'].sudo().create(
							 | 
						|
								                            values)
							 | 
						|
								                    sequence_value += 1
							 | 
						|
								            project.write({'board_id_jira': jira_data['configuration']['id']})
							 | 
						|
								        else:
							 | 
						|
								            board_id_jira = jira_data['configuration']['id']
							 | 
						|
								            project = self.env['project.project'].search(
							 | 
						|
								                [('board_id_jira', '=', board_id_jira)])
							 | 
						|
								            existing_stages = self.env[
							 | 
						|
								                'project.task.type'].sudo().search(
							 | 
						|
								                [('project_ids', 'in', project.id),
							 | 
						|
								                 ('stages_jira_id', '!=', '0')])
							 | 
						|
								            jira_status_ids = []
							 | 
						|
								            for column in columns:
							 | 
						|
								                for status in column['statuses']:
							 | 
						|
								                    jira_status_ids.append(status['id'])
							 | 
						|
								            if len(jira_status_ids) < len(existing_stages.ids):
							 | 
						|
								                removed_stage = self.env[
							 | 
						|
								                    'project.task.type'].sudo().search(
							 | 
						|
								                    [('project_ids', 'in', project.id),
							 | 
						|
								                     ('stages_jira_id', 'not in', jira_status_ids)])
							 | 
						|
								                removed_stage.unlink()
							 | 
						|
								            elif len(jira_status_ids) > len(existing_stages.ids):
							 | 
						|
								                columns = jira_data['configuration']['columnConfig'][
							 | 
						|
								                    'columns']
							 | 
						|
								                num_stages = len(columns)
							 | 
						|
								                stage_id = columns[num_stages - 1]['statuses'][0]['id']
							 | 
						|
								                values = {
							 | 
						|
								                    'name': columns[num_stages - 1]['name'],
							 | 
						|
								                    'stages_jira_id': stage_id,
							 | 
						|
								                    'project_ids': project,
							 | 
						|
								                    'sequence': num_stages,
							 | 
						|
								                }
							 | 
						|
								                self.env['project.task.type'].sudo().create(values)
							 | 
						|
								
							 | 
						|
								    def update_task(self, jira_data):
							 | 
						|
								        """function to update a task, which includes changing the task stage,
							 | 
						|
								         adding attachments, adding a description to the task,
							 | 
						|
								         changing the task's name,
							 | 
						|
								         and adding a sprint based on webhook response"""
							 | 
						|
								        task_key = jira_data['issue']['key']
							 | 
						|
								        imported_task = self.env['project.task'].sudo().search(
							 | 
						|
								            [('task_id_jira', '=', task_key)])
							 | 
						|
								        to_value = jira_data['changelog']['items'][0]['to']
							 | 
						|
								        if jira_data['changelog']['items'][0]['field'] == 'resolution':
							 | 
						|
								            second_to_value = jira_data['changelog']['items'][1]['to']
							 | 
						|
								            task_stage = self.env['project.task.type'].sudo().search(
							 | 
						|
								                [('stages_jira_id', '=', second_to_value)])
							 | 
						|
								            imported_task.write({'stage_id': task_stage.id})
							 | 
						|
								        elif jira_data['changelog']['items'][0]['field'] == 'status':
							 | 
						|
								            task_stage = self.env['project.task.type'].sudo().search(
							 | 
						|
								                [('stages_jira_id', '=', to_value)])
							 | 
						|
								            imported_task.write({'stage_id': task_stage.id})
							 | 
						|
								        elif jira_data['changelog']['items'][0]['field'] == 'Attachment':
							 | 
						|
								            if jira_data['changelog']['items'][0]['to'] != 'None':
							 | 
						|
								                attachments = jira_data["issue"]['fields']['attachment']
							 | 
						|
								                jira_attachment_id = [attachment['id'] for attachment in
							 | 
						|
								                                      attachments]
							 | 
						|
								                num_attachments = len(jira_attachment_id)
							 | 
						|
								                user_name = self.env[
							 | 
						|
								                    'ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.user_id_jira')
							 | 
						|
								                api_token = self.env[
							 | 
						|
								                    'ir.config_parameter'].sudo().get_param(
							 | 
						|
								                    'odoo_jira_connector.api_token')
							 | 
						|
								                auth = HTTPBasicAuth(user_name, api_token)
							 | 
						|
								                if num_attachments > 0:
							 | 
						|
								                    name = attachments[num_attachments - 1].get('filename')
							 | 
						|
								                    mime_type = attachments[num_attachments - 1].get(
							 | 
						|
								                        'mimeType')
							 | 
						|
								                    src = attachments[num_attachments - 1].get('content')
							 | 
						|
								                    jira_id = attachments[num_attachments - 1].get('id')
							 | 
						|
								                    image = base64.b64encode(
							 | 
						|
								                        requests.get(src, auth=auth).content)
							 | 
						|
								                    existing_attachments = self.env[
							 | 
						|
								                        'ir.attachment'].sudo().search(
							 | 
						|
								                        [('res_id', '=', imported_task.id),
							 | 
						|
								                         ('res_model', '=', 'project.task'),
							 | 
						|
								                         ('attachment_id_jira', '=', jira_id)]
							 | 
						|
								                    )
							 | 
						|
								                    values = {
							 | 
						|
								                        'name': name,
							 | 
						|
								                        'type': 'binary',
							 | 
						|
								                        'datas': image,
							 | 
						|
								                        'res_model': 'project.task',
							 | 
						|
								                        'res_id': imported_task.id,
							 | 
						|
								                        'mimetype': mime_type,
							 | 
						|
								                        'attachment_id_jira': jira_id
							 | 
						|
								                    }
							 | 
						|
								                    if not existing_attachments:
							 | 
						|
								                        self.env['ir.attachment'].sudo().create(values)
							 | 
						|
								                else:
							 | 
						|
								                    pass
							 | 
						|
								        elif jira_data['changelog']['items'][0]['field'] == 'description':
							 | 
						|
								            imported_task.update({'description': jira_data['changelog']
							 | 
						|
								            ['items'][0]['toString']})
							 | 
						|
								        elif jira_data['changelog']['items'][0]['field'] == 'summary':
							 | 
						|
								            if imported_task.name != jira_data['changelog']['items'][0] \
							 | 
						|
								                    ['toString']:
							 | 
						|
								                imported_task.write(
							 | 
						|
								                    {'name': jira_data['changelog']['items'][0]
							 | 
						|
								                    ['toString']})
							 | 
						|
								        elif jira_data['changelog']['items'][0]['field'] == 'Sprint':
							 | 
						|
								            project_key = jira_data['issue']['fields']['project']['key']
							 | 
						|
								            project = self.env['project.project'].sudo().search(
							 | 
						|
								                [('jira_project_key', '=', project_key)])
							 | 
						|
								            custom_field = jira_data['issue']['fields']['customfield_10020']
							 | 
						|
								            if len(custom_field) > 1:
							 | 
						|
								                jira_sprint = self.env['jira.sprint'].sudo().search(
							 | 
						|
								                    [('sprint_id_jira', '=',
							 | 
						|
								                      custom_field[len(custom_field) - 1]['id'])])
							 | 
						|
								                if not jira_sprint:
							 | 
						|
								                    vals = {
							 | 
						|
								                        'name': custom_field[len(custom_field) - 1]['name'],
							 | 
						|
								                        'sprint_id_jira':
							 | 
						|
								                            custom_field[len(custom_field) - 1]['id'],
							 | 
						|
								                        'project_id': project.id
							 | 
						|
								                    }
							 | 
						|
								                    sprint = self.env['jira.sprint'].sudo().create(vals)
							 | 
						|
								                    if project.task_ids:
							 | 
						|
								                        for rec in project.task_ids:
							 | 
						|
								                            rec.write({'sprint_id': sprint.id})
							 | 
						|
								            else:
							 | 
						|
								                jira_sprint = self.env['jira.sprint'].sudo().search([(
							 | 
						|
								                    'sprint_id_jira', '=', custom_field[0]['id'])])
							 | 
						|
								                if not jira_sprint:
							 | 
						|
								                    vals = {
							 | 
						|
								                        'name': custom_field[0]['name'],
							 | 
						|
								                        'sprint_id_jira': custom_field[0]['id'],
							 | 
						|
								                        'project_id': project.id
							 | 
						|
								                    }
							 | 
						|
								                    sprint = self.env['jira.sprint'].sudo().create(vals)
							 | 
						|
								                    if project.task_ids:
							 | 
						|
								                        for rec in project.task_ids:
							 | 
						|
								                            rec.write({'sprint_id': sprint.id})
							 | 
						|
								                            if rec.task_id_jira != task_key:
							 | 
						|
								                                self.create({
							 | 
						|
								                                    'project_id': project.id,
							 | 
						|
								                                    'name': jira_data['issue']['fields'][
							 | 
						|
								                                        'summary'],
							 | 
						|
								                                    'task_id_jira': task_key,
							 | 
						|
								                                    'sprint_id': jira_sprint.id
							 | 
						|
								                                })
							 | 
						|
								                                break
							 | 
						|
								                    else:
							 | 
						|
								                        task_name = jira_data['issue']['fields']['summary']
							 | 
						|
								                        self.create({
							 | 
						|
								                            'project_id': project.id,
							 | 
						|
								                            'name': task_name,
							 | 
						|
								                            'task_id_jira': task_key,
							 | 
						|
								                            'sprint_id': sprint.id
							 | 
						|
								                        })
							 | 
						|
								                else:
							 | 
						|
								                    if project.task_ids:
							 | 
						|
								                        for rec in project.task_ids:
							 | 
						|
								                            rec.write({'sprint_id': jira_sprint.id})
							 | 
						|
								                            if rec.task_id_jira != task_key:
							 | 
						|
								                                self.create({
							 | 
						|
								                                    'project_id': project.id,
							 | 
						|
								                                    'name': jira_data['issue']['fields'][
							 | 
						|
								                                        'summary'],
							 | 
						|
								                                    'task_id_jira': task_key,
							 | 
						|
								                                    'sprint_id': jira_sprint.id
							 | 
						|
								                                })
							 | 
						|
								                                break
							 | 
						|
								                    else:
							 | 
						|
								                        task_name = jira_data['issue']['fields']['summary']
							 | 
						|
								                        self.create({
							 | 
						|
								                            'project_id': project.id,
							 | 
						|
								                            'name': task_name,
							 | 
						|
								                            'task_id_jira': task_key,
							 | 
						|
								                            'sprint_id': jira_sprint.id
							 | 
						|
								                        })
							 | 
						|
								
							 | 
						|
								    def delete_attachment(self, jira_data):
							 | 
						|
								        """function to delete attachment based on the response received from
							 | 
						|
								         webhook"""
							 | 
						|
								        jira_id = jira_data['attachment']['id']
							 | 
						|
								        self.env['ir.attachment'].sudo().search(
							 | 
						|
								            [('attachment_id_jira', '=', jira_id)]).unlink()
							 | 
						|
								
							 | 
						|
								    def sprint_started(self, jira_data):
							 | 
						|
								        """function to start sprint which is created using webhook response"""
							 | 
						|
								        sprint_in_odoo = self.env['jira.sprint'].sudo().search(
							 | 
						|
								            [('sprint_id_jira', '=', jira_data['sprint']['id'])])
							 | 
						|
								        if sprint_in_odoo:
							 | 
						|
								            start_date = jira_data['sprint']['startDate']
							 | 
						|
								            input_start_date = datetime. \
							 | 
						|
								                strptime(start_date, '%Y-%m-%dT%H:%M:%S.%fZ')
							 | 
						|
								            jira_start_date = input_start_date.strftime(
							 | 
						|
								                '%Y-%m-%d %H:%M:%S')
							 | 
						|
								            end_date = jira_data['sprint']['endDate']
							 | 
						|
								            input_end_date = datetime. \
							 | 
						|
								                strptime(end_date, '%Y-%m-%dT%H:%M:%S.%fZ')
							 | 
						|
								            jira_end_date = input_end_date.strftime(
							 | 
						|
								                '%Y-%m-%d %H:%M:%S')
							 | 
						|
								            sprint_in_odoo.write({
							 | 
						|
								                'start_date': jira_start_date,
							 | 
						|
								                'end_date': jira_end_date,
							 | 
						|
								                'sprint_goal': jira_data['sprint']['goal'],
							 | 
						|
								                'state': 'ongoing'
							 | 
						|
								            })
							 | 
						|
								
							 | 
						|
								    def sprint_closed(self, jira_data):
							 | 
						|
								        """function to close sprint which is created using webhook response"""
							 | 
						|
								        sprint_in_odoo = self.env['jira.sprint'].sudo().search(
							 | 
						|
								            [('sprint_id_jira', '=', jira_data['sprint']['id'])])
							 | 
						|
								        if sprint_in_odoo:
							 | 
						|
								            sprint_in_odoo.write({'state': 'completed'})
							 | 
						|
								            self.env['project.task'].sudo().search(
							 | 
						|
								                [('stage_id.name', '=', 'Done'),
							 | 
						|
								                 ('sprint_id', '=', sprint_in_odoo.id)]).unlink()
							 | 
						|
								
							 |