From e653bacc342fd5b29a292843a0346edd8265b0d5 Mon Sep 17 00:00:00 2001 From: AjmalCybro Date: Tue, 9 Apr 2024 16:03:57 +0530 Subject: [PATCH] Apr 8 [UPDT] : Updated 'asana_odoo_connector' --- asana_odoo_connector/__manifest__.py | 6 +- ...ns_data.xml => ir_actions_server_data.xml} | 0 asana_odoo_connector/doc/RELEASE_NOTES.md | 6 +- .../models/project_project.py | 96 ++++++++++++------ .../models/res_config_settings.py | 97 ++++++++++++------- 5 files changed, 137 insertions(+), 68 deletions(-) rename asana_odoo_connector/data/{ir_actions_data.xml => ir_actions_server_data.xml} (100%) diff --git a/asana_odoo_connector/__manifest__.py b/asana_odoo_connector/__manifest__.py index af5e3755f..407597187 100644 --- a/asana_odoo_connector/__manifest__.py +++ b/asana_odoo_connector/__manifest__.py @@ -21,7 +21,7 @@ ############################################################################### { 'name': 'Asana Odoo Connector', - 'version': '16.0.1.0.0', + 'version': '16.0.1.0.1', 'category': 'Project', 'summary': "With this module, you can easily connect the projects, tasks " "and partners in the odoo to asana", @@ -32,13 +32,13 @@ 'company': 'Cybrosys Techno Solutions', 'maintainer': 'Cybrosys Techno Solutions', 'website': "https://www.cybrosys.com", - 'depends': ['project'], + 'depends': ['project', 'queue_job_cron_jobrunner'], 'data': [ + 'data/ir_actions_server_data.xml', 'views/project_project_views.xml', 'views/project_task_views.xml', 'views/project_task_type_views.xml', 'views/res_config_settings_views.xml', - 'data/ir_actions_data.xml', ], 'external_dependencies': { 'python': [ diff --git a/asana_odoo_connector/data/ir_actions_data.xml b/asana_odoo_connector/data/ir_actions_server_data.xml similarity index 100% rename from asana_odoo_connector/data/ir_actions_data.xml rename to asana_odoo_connector/data/ir_actions_server_data.xml diff --git a/asana_odoo_connector/doc/RELEASE_NOTES.md b/asana_odoo_connector/doc/RELEASE_NOTES.md index 6ef08f8d5..610cac9ad 100644 --- a/asana_odoo_connector/doc/RELEASE_NOTES.md +++ b/asana_odoo_connector/doc/RELEASE_NOTES.md @@ -3,5 +3,9 @@ #### 05.01.2024 #### Version 16.0.1.0.0 #### ADD - - Initial Commit for Asana Odoo Connector + +#### 09.04.2024 +#### Version 16.0.1.0.1 +#### ADD +- Updated API, also added Queue Job functionality diff --git a/asana_odoo_connector/models/project_project.py b/asana_odoo_connector/models/project_project.py index fde7c26db..eb32e5257 100644 --- a/asana_odoo_connector/models/project_project.py +++ b/asana_odoo_connector/models/project_project.py @@ -26,6 +26,7 @@ from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) try: import asana + from asana.rest import ApiException except ImportError: _logger.debug('Cannot `import asana`.') @@ -46,43 +47,76 @@ class ProjectProject(models.Model): Method action_export_to_asana used to export the data in the odoo to asana """ + workspace_gid = self.env[ + 'ir.config_parameter'].sudo().get_param( + 'asana_odoo_connector.workspace_gid') + if not workspace_gid or not self.env[ + 'ir.config_parameter'].sudo().get_param( + 'asana_odoo_connector.app_token'): + raise ValidationError(_("Add Configurations")) + try: + batch_size = 5 # Specify the batch size + start_index = 0 + while start_index < len(self): + exported_project = self.filtered( + lambda self: not self.asana_gid) + project_batch = exported_project[ + start_index:start_index + batch_size] + delay = self.with_delay(priority=1, eta=5) + delay.export_project(items=project_batch, + workspace_gid=workspace_gid) + start_index += batch_size + except ApiException as exc: + raise ValidationError( + _('Please check the workspace ID or the app token')) from exc + + def export_project(self, items, workspace_gid): + """Method export_project to export the data from Odoo to Asana""" configuration = asana.Configuration() - configuration.access_token = self.env[ + app_token = self.env[ 'ir.config_parameter'].sudo().get_param( 'asana_odoo_connector.app_token') + configuration.access_token = app_token api_client = asana.ApiClient(configuration) project_instance = asana.ProjectsApi(api_client) - workspace_gid = self.env[ - 'ir.config_parameter'].sudo().get_param( - 'asana_odoo_connector.workspace_gid') - try: - for project in self: - if not project.asana_gid: - project_body = asana.WorkspaceGidProjectsBody( - {"name": project.name}) - project_response = project_instance.create_project_for_workspace( - project_body, workspace_gid) - project.asana_gid = project_response.data.gid - project_gid = project_response.data.gid - task_instance = asana.TasksApi(api_client) - section_instance = asana.SectionsApi(api_client) - for section in project.type_ids: - section_body = asana.ProjectGidSectionsBody( - {'name': section.name}) - section_responses = section_instance.create_section_for_project( - project_gid, body=section_body - ) - section.asana_gid = section_responses.data.gid - for task in project.tasks: - task_body = asana.TasksBody( - {'name': task.name, 'workspace': workspace_gid, - "projects": project_gid, "memberships": [ + for project in items: + project_body = { + "data": { + "name": project.name + } + } + opts = {} + project_response = project_instance.create_project_for_workspace( + project_body, workspace_gid, opts) + project.asana_gid = project_response['gid'] + project_gid = project_response['gid'] + task_instance = asana.TasksApi(api_client) + section_instance = asana.SectionsApi(api_client) + for section in project.type_ids: + opts = { + "body": { + "data": { + "name": section.name, + } + } + } + section_responses = section_instance.create_section_for_project( + project_gid, opts + ) + section.asana_gid = section_responses['gid'] + for task in project.tasks: + body = { + "data": + { + 'name': task.name, + 'workspace': workspace_gid, + "projects": project_gid, + "memberships": [ { 'project': project_gid, 'section': task.stage_id.asana_gid } - ]}) - task_instance.create_task(task_body) - except Exception as exc: - raise ValidationError( - _('Please check the workspace ID or the app token')) from exc + ]} + } + opts = {} + task_instance.create_task(body, opts) diff --git a/asana_odoo_connector/models/res_config_settings.py b/asana_odoo_connector/models/res_config_settings.py index 764bac895..d731ff21d 100644 --- a/asana_odoo_connector/models/res_config_settings.py +++ b/asana_odoo_connector/models/res_config_settings.py @@ -20,13 +20,16 @@ # ############################################################################### import logging +from logging import Logger + import requests from odoo import fields, models, _ from odoo.exceptions import ValidationError -_logger = logging.getLogger(__name__) +_logger: Logger = logging.getLogger(__name__) try: import asana + from asana.rest import ApiException except ImportError: _logger.debug('Cannot `import asana`.') @@ -56,9 +59,13 @@ def action_import_project_stages(project_gid, api_client): asana to odoo """ api_instance = asana.SectionsApi(api_client) - section_response = api_instance.get_sections_for_project( - project_gid) - return section_response + opts = {} + try: + section_response = list(api_instance.get_sections_for_project( + project_gid, opts)) + return section_response + except ApiException as exc: + _logger.debug(f"Error while trying to import section {exc}") class ResConfigSettings(models.TransientModel): @@ -101,49 +108,73 @@ class ResConfigSettings(models.TransientModel): """ Method action_import_projects to import the project from asana to odoo """ + if not self.workspace_gid or not self.app_token: + raise ValidationError(_("Please add App Token and Workspace gid")) configuration = asana.Configuration() configuration.access_token = self.app_token api_client = asana.ApiClient(configuration) project_instance = asana.ProjectsApi(api_client) - workspace = self.workspace_gid + opts = {'workspace': self.workspace_gid} try: - project_response = project_instance.get_projects( - workspace=workspace) - for project in project_response.data: - asana_gid = project.gid - existing_project = self.env['project.project'].search( - [('asana_gid', '=', asana_gid)]) - if not existing_project: - section_data = action_import_project_stages( - project_gid=asana_gid, - api_client=api_client) - type_ids = [ - (0, 0, {'name': section.name, 'asana_gid': section.gid}) - for section in section_data.data] - new_project = self.env['project.project'].create({ - 'name': project.name, - 'asana_gid': asana_gid, - 'type_ids': type_ids - }) - self.action_import_tasks( - api_client=api_client, section_data=section_data, - project_id=new_project.id) - except Exception as exc: + project_response = list(project_instance.get_projects(opts)) + split_data = [project_response[project:project + 5] for project in + range(0, len(project_response), 10)] + for project in split_data: + delay = self.with_delay(priority=1, eta=5) + delay.create_project(items=project, app_token=self.app_token) + except ApiException as exc: raise ValidationError( _('Please check the workspace ID or the app token')) from exc + def create_project(self, items, app_token): + """Method create_project to create the project from Asana to Odoo""" + configuration = asana.Configuration() + configuration.access_token = app_token + api_client = asana.ApiClient(configuration) + for project in items: + asana_gid = project['gid'] + existing_project = self.env['project.project'].search( + [('asana_gid', '=', asana_gid)]) + if not existing_project: + section_data = action_import_project_stages( + project_gid=asana_gid, + api_client=api_client) + type_ids = [] + for section in section_data: + existing_stage = self.env['project.task.type'].search( + [('asana_gid', '=', section['gid'])], limit=1) + if existing_stage: + type_ids.append((4, existing_stage.id)) + else: + new_stage = self.env['project.task.type'].create({ + 'name': section['name'], + 'asana_gid': section['gid'], + }) + type_ids.append((0, 0, {'name': new_stage.name, + 'asana_gid': new_stage.asana_gid})) + new_project = self.env['project.project'].create({ + 'name': project['name'], + 'asana_gid': asana_gid, + 'type_ids': type_ids + }) + self.action_import_tasks( + api_client=api_client, section_data=section_data, + project_id=new_project.id) + def action_import_tasks(self, api_client, section_data, project_id): """ Method action_import_tasks to import tasks from the asana to odoo """ api_instance = asana.TasksApi(api_client) - for section in section_data.data: - task_response = api_instance.get_tasks_for_section(section.gid) - for task in task_response.data: + for section in section_data: + opts = {} + task_response = list( + api_instance.get_tasks_for_section(section['gid'], opts)) + for task in task_response: self.env['project.task'].create({ - 'name': task.name, - 'asana_gid': task.gid, + 'name': task['name'], + 'asana_gid': task['gid'], 'stage_id': self.env['project.task.type'].search( - [('asana_gid', '=', section.gid)]).id, + [('asana_gid', '=', section['gid'])], limit=1).id, 'project_id': project_id })