From 116149e13e6976d769cac5b37a147a46aeadc18c Mon Sep 17 00:00:00 2001 From: SilvioC2C Date: Tue, 9 Jul 2024 21:17:54 +0200 Subject: [PATCH] [WIP][MIG] connector_jira_servicedesk: Migration to 17.0 --- connector_jira_servicedesk/__init__.py | 2 + connector_jira_servicedesk/__manifest__.py | 8 +-- .../components/__init__.py | 8 +++ .../components/jira_analytic_line_importer.py | 13 ++++ .../jira_organization_adapter.py} | 24 +++---- .../jira_organization_batch_importer.py} | 20 +----- .../components/jira_organization_from_task.py | 17 +++++ .../components/jira_organization_mapper.py | 17 +++++ .../jira_project_binder.py} | 29 ++++----- .../components/jira_project_task_importer.py | 17 +++++ .../components/jira_task_project_matcher.py | 20 ++++++ connector_jira_servicedesk/models/__init__.py | 5 +- .../models/account_analytic_line.py | 22 +++++++ .../models/account_analytic_line/__init__.py | 2 - .../models/account_analytic_line/common.py | 48 -------------- .../models/account_analytic_line/importer.py | 16 ----- .../models/jira_account_analytic_line.py | 22 +++++++ .../common.py => jira_backend.py} | 15 ++--- .../models/jira_backend/__init__.py | 1 - .../common.py => jira_organization.py} | 0 .../models/jira_organization/__init__.py | 3 - .../models/jira_project_base_mixin.py | 17 +++++ .../common.py => jira_project_project.py} | 52 ++++----------- .../models/project_project/__init__.py | 3 - .../models/project_task/__init__.py | 1 - .../models/project_task/importer.py | 57 ----------------- connector_jira_servicedesk/tests/__init__.py | 2 +- .../views/jira_backend.xml | 63 +++++++++++++++++++ .../views/jira_backend_views.xml | 62 ------------------ ...ect_views.xml => jira_project_project.xml} | 6 +- .../wizards/__init__.py | 1 + .../project_link_jira.py | 0 .../project_link_jira.xml} | 2 +- 33 files changed, 271 insertions(+), 304 deletions(-) create mode 100644 connector_jira_servicedesk/components/__init__.py create mode 100644 connector_jira_servicedesk/components/jira_analytic_line_importer.py rename connector_jira_servicedesk/{models/jira_organization/adapter.py => components/jira_organization_adapter.py} (76%) rename connector_jira_servicedesk/{models/jira_organization/importer.py => components/jira_organization_batch_importer.py} (52%) create mode 100644 connector_jira_servicedesk/components/jira_organization_from_task.py create mode 100644 connector_jira_servicedesk/components/jira_organization_mapper.py rename connector_jira_servicedesk/{models/project_project/binder.py => components/jira_project_binder.py} (74%) create mode 100644 connector_jira_servicedesk/components/jira_project_task_importer.py create mode 100644 connector_jira_servicedesk/components/jira_task_project_matcher.py create mode 100644 connector_jira_servicedesk/models/account_analytic_line.py delete mode 100644 connector_jira_servicedesk/models/account_analytic_line/__init__.py delete mode 100644 connector_jira_servicedesk/models/account_analytic_line/common.py delete mode 100644 connector_jira_servicedesk/models/account_analytic_line/importer.py create mode 100644 connector_jira_servicedesk/models/jira_account_analytic_line.py rename connector_jira_servicedesk/models/{jira_backend/common.py => jira_backend.py} (75%) delete mode 100644 connector_jira_servicedesk/models/jira_backend/__init__.py rename connector_jira_servicedesk/models/{jira_organization/common.py => jira_organization.py} (100%) delete mode 100644 connector_jira_servicedesk/models/jira_organization/__init__.py create mode 100644 connector_jira_servicedesk/models/jira_project_base_mixin.py rename connector_jira_servicedesk/models/{project_project/common.py => jira_project_project.py} (58%) delete mode 100644 connector_jira_servicedesk/models/project_project/__init__.py delete mode 100644 connector_jira_servicedesk/models/project_task/__init__.py delete mode 100644 connector_jira_servicedesk/models/project_task/importer.py create mode 100644 connector_jira_servicedesk/views/jira_backend.xml delete mode 100644 connector_jira_servicedesk/views/jira_backend_views.xml rename connector_jira_servicedesk/views/{project_project_views.xml => jira_project_project.xml} (86%) create mode 100644 connector_jira_servicedesk/wizards/__init__.py rename connector_jira_servicedesk/{models/project_project => wizards}/project_link_jira.py (100%) rename connector_jira_servicedesk/{views/project_link_jira_views.xml => wizards/project_link_jira.xml} (94%) diff --git a/connector_jira_servicedesk/__init__.py b/connector_jira_servicedesk/__init__.py index 0650744f6..79dbb9408 100644 --- a/connector_jira_servicedesk/__init__.py +++ b/connector_jira_servicedesk/__init__.py @@ -1 +1,3 @@ +from . import components from . import models +from . import wizards diff --git a/connector_jira_servicedesk/__manifest__.py b/connector_jira_servicedesk/__manifest__.py index 5e0d2def8..3e18c0474 100644 --- a/connector_jira_servicedesk/__manifest__.py +++ b/connector_jira_servicedesk/__manifest__.py @@ -2,17 +2,17 @@ { "name": "JIRA Connector - Service Desk Extension", - "version": "15.0.1.0.0", + "version": "17.0.1.0.0", "author": "Camptocamp,Odoo Community Association (OCA)", "license": "AGPL-3", "category": "Connector", "depends": ["connector_jira"], "website": "https://github.com/OCA/connector-jira", "data": [ - "views/jira_backend_views.xml", - "views/project_project_views.xml", - "views/project_link_jira_views.xml", "security/ir.model.access.csv", + "views/jira_backend.xml", + "views/jira_project_project.xml", + "wizards/project_link_jira.xml", ], "installable": True, } diff --git a/connector_jira_servicedesk/components/__init__.py b/connector_jira_servicedesk/components/__init__.py new file mode 100644 index 000000000..8c6de2def --- /dev/null +++ b/connector_jira_servicedesk/components/__init__.py @@ -0,0 +1,8 @@ +from . import jira_analytic_line_importer +from . import jira_organization_adapter +from . import jira_organization_batch_importer +from . import jira_organization_from_task +from . import jira_organization_mapper +from . import jira_project_binder +from . import jira_project_task_importer +from . import jira_task_project_matcher diff --git a/connector_jira_servicedesk/components/jira_analytic_line_importer.py b/connector_jira_servicedesk/components/jira_analytic_line_importer.py new file mode 100644 index 000000000..9259808cd --- /dev/null +++ b/connector_jira_servicedesk/components/jira_analytic_line_importer.py @@ -0,0 +1,13 @@ +# Copyright 2019-2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import Component + + +class JiraAnalyticLineImporter(Component): + _inherit = "jira.analytic.line.importer" + + @property + def _issue_fields_to_read(self): + org_fname = self.backend_record.organization_field_name + return super()._issue_fields_to_read + ([org_fname] if org_fname else []) diff --git a/connector_jira_servicedesk/models/jira_organization/adapter.py b/connector_jira_servicedesk/components/jira_organization_adapter.py similarity index 76% rename from connector_jira_servicedesk/models/jira_organization/adapter.py rename to connector_jira_servicedesk/components/jira_organization_adapter.py index 56664f86a..d8df87a0b 100644 --- a/connector_jira_servicedesk/models/jira_organization/adapter.py +++ b/connector_jira_servicedesk/components/jira_organization_adapter.py @@ -20,9 +20,8 @@ class Organization(Resource): """A Service Desk Organization.""" def __init__(self, options, session, raw=None): - super().__init__( - "organization/{0}", options, session, "{server}/rest/servicedeskapi/{path}" - ) + base_url = "{server}/rest/servicedeskapi/{path}" + super().__init__("organization/{0}", options, session, base_url) if raw: self._parse_raw(raw) @@ -33,7 +32,7 @@ class OrganizationAdapter(Component): _apply_on = ["jira.organization"] # The Service Desk REST API returns an error if this header - # is not used. The API may change so they want an agreement for + # is not used. The API may change, so they want an agreement for # the client about this. _desk_headers = CaseInsensitiveDict({"X-ExperimentalApi": "opt-in"}) @@ -54,20 +53,15 @@ def search(self): # A GET on the REST API returns only one page with the # first 50 rows. Fetch all pages. orgs = [] - start = 0 - while True: + # 50 items per page is the maximum allowed by Jira + start, end = 0, 50 + result = {"isLastPage": False} + while not result["isLastPage"]: result = self.client._get_json( "organization", - params={ - "start": start, - # 50 items per page is the maximum allowed by Jira - "limit": start + 50, - }, + params={"start": start, "limit": end}, base=self._desk_api_path_base, ) - start += 50 + start, end = end, end + 50 orgs += result["values"] - if result["isLastPage"]: - break - return orgs diff --git a/connector_jira_servicedesk/models/jira_organization/importer.py b/connector_jira_servicedesk/components/jira_organization_batch_importer.py similarity index 52% rename from connector_jira_servicedesk/models/jira_organization/importer.py rename to connector_jira_servicedesk/components/jira_organization_batch_importer.py index ca537c765..ea8bf0e6d 100644 --- a/connector_jira_servicedesk/models/jira_organization/importer.py +++ b/connector_jira_servicedesk/components/jira_organization_batch_importer.py @@ -2,24 +2,9 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from odoo.addons.component.core import Component -from odoo.addons.connector.components.mapper import mapping -class OrganizationMapper(Component): - _name = "jira.organization.mapper" - _inherit = ["jira.import.mapper"] - _apply_on = "jira.organization" - - direct = [ - ("name", "name"), - ] - - @mapping - def backend_id(self, record): - return {"backend_id": self.backend_record.id} - - -class OrganizationBatchImporter(Component): +class JiraOrganizationBatchImporter(Component): """Import the Jira Organizations For every id in in the list of organizations, a direct import is done. @@ -31,6 +16,5 @@ class OrganizationBatchImporter(Component): def run(self): """Run the synchronization""" - records = self.backend_adapter.search() - for record in records: + for record in self.backend_adapter.search(): self._import_record(record["id"], record=record) diff --git a/connector_jira_servicedesk/components/jira_organization_from_task.py b/connector_jira_servicedesk/components/jira_organization_from_task.py new file mode 100644 index 000000000..d92e03e6a --- /dev/null +++ b/connector_jira_servicedesk/components/jira_organization_from_task.py @@ -0,0 +1,17 @@ +# Copyright 2016-Today Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import Component + + +class JiraOrganizationsFromTask(Component): + _name = "jira.organization.from.task" + _inherit = ["jira.base"] + _usage = "organization.from.task" + + def get_jira_org_ids(self, jira_task_data): + if fields := jira_task_data.get("fields", {}): + if org_fname := self.backend_record.organization_field_name: + if recs := fields.get(org_fname): + return [r["id"] for r in recs] + return [] diff --git a/connector_jira_servicedesk/components/jira_organization_mapper.py b/connector_jira_servicedesk/components/jira_organization_mapper.py new file mode 100644 index 000000000..b2046dc4e --- /dev/null +++ b/connector_jira_servicedesk/components/jira_organization_mapper.py @@ -0,0 +1,17 @@ +# Copyright 2016-2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import Component +from odoo.addons.connector.components.mapper import mapping + + +class OrganizationMapper(Component): + _name = "jira.organization.mapper" + _inherit = ["jira.import.mapper"] + _apply_on = "jira.organization" + + direct = [("name", "name")] + + @mapping + def backend_id(self, record): + return {"backend_id": self.backend_record.id} diff --git a/connector_jira_servicedesk/models/project_project/binder.py b/connector_jira_servicedesk/components/jira_project_binder.py similarity index 74% rename from connector_jira_servicedesk/models/project_project/binder.py rename to connector_jira_servicedesk/components/jira_project_binder.py index 354259b80..7474c029b 100644 --- a/connector_jira_servicedesk/models/project_project/binder.py +++ b/connector_jira_servicedesk/components/jira_project_binder.py @@ -40,32 +40,25 @@ def to_internal(self, external_id, unwrap=False, organizations=None): (self._backend_field, "=", self.backend_record.id), ] if not organizations: - domain.append( - ("organization_ids", "=", False), - ) + domain.append(("organization_ids", "=", False)) candidates = self.model.with_context(active_test=False).search(domain) if organizations: fallback = self.model.browse() - binding = self.model.browse() for candidate in candidates: + # No organization set on candidate: use it as fallback if not candidate.organization_ids: fallback = candidate - continue - - if organizations in candidate.organization_ids: + # All organizations are included in the candidate's organizations: it's + # the binding we were looking for + elif organizations <= candidate.organization_ids: binding = candidate break - if not binding: + # No feasible candidate found: use fallback + else: binding = fallback else: + # No organization set: all candidates are feasible binding = candidates - - if not binding: - if unwrap: - return self.model.browse()[self._odoo_field] - return self.model.browse() - - binding.ensure_one() - if unwrap: - binding = binding[self._odoo_field] - return binding + # Binding must be exactly 1 + binding = (binding and binding.ensure_one()) or self.model.browse() + return binding[self._odoo_field] if unwrap else binding diff --git a/connector_jira_servicedesk/components/jira_project_task_importer.py b/connector_jira_servicedesk/components/jira_project_task_importer.py new file mode 100644 index 000000000..ae81e368a --- /dev/null +++ b/connector_jira_servicedesk/components/jira_project_task_importer.py @@ -0,0 +1,17 @@ +# Copyright 2016-Today Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import Component + + +class JiraProjectTaskImporter(Component): + _inherit = "jira.project.task.importer" + + def _import_dependencies(self): + # OVERRIDE: import organizations + res = super()._import_dependencies() + for jorg_id in self.component(usage="organization.from.task").get_jira_org_ids( + self.external_record + ): + self._import_dependency(jorg_id, "jira.organization") + return res diff --git a/connector_jira_servicedesk/components/jira_task_project_matcher.py b/connector_jira_servicedesk/components/jira_task_project_matcher.py new file mode 100644 index 000000000..e3975214e --- /dev/null +++ b/connector_jira_servicedesk/components/jira_task_project_matcher.py @@ -0,0 +1,20 @@ +# Copyright 2016-Today Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.component.core import Component + + +class JiraTaskProjectMatcher(Component): + _inherit = "jira.task.project.matcher" + + def find_project_binding(self, jira_task_data, unwrap=False): + component = self.component(usage="organization.from.task") + binder = self.binder_for("jira.organization") + org_ids = set() + for j_org_id in component.get_jira_org_ids(jira_task_data): + org_ids.update(binder.to_internal(j_org_id).ids) + return self.binder_for("jira.project.project").to_internal( + jira_task_data["fields"]["project"]["id"], + unwrap=unwrap, + organizations=self.env["jira.organization"].browse(org_ids), + ) diff --git a/connector_jira_servicedesk/models/__init__.py b/connector_jira_servicedesk/models/__init__.py index 6b2bb84b8..f56d7ee6e 100644 --- a/connector_jira_servicedesk/models/__init__.py +++ b/connector_jira_servicedesk/models/__init__.py @@ -1,5 +1,6 @@ from . import account_analytic_line +from . import jira_account_analytic_line from . import jira_backend -from . import project_project from . import jira_organization -from . import project_task +from . import jira_project_base_mixin +from . import jira_project_project diff --git a/connector_jira_servicedesk/models/account_analytic_line.py b/connector_jira_servicedesk/models/account_analytic_line.py new file mode 100644 index 000000000..56b8b92d0 --- /dev/null +++ b/connector_jira_servicedesk/models/account_analytic_line.py @@ -0,0 +1,22 @@ +# Copyright 2020-2021 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import api, fields, models + + +class AccountAnalyticLine(models.Model): + _inherit = "account.analytic.line" + + jira_servicedesk_issue_url = fields.Char( + string="Original JIRA service desk issue Link", + compute="_compute_jira_servicedesk_issue_url", + ) + + @api.depends("jira_bind_ids.jira_servicedesk_issue_url") + def _compute_jira_servicedesk_issue_url(self): + """Compute the service desk references to JIRA. + + We assume that we have only one external record for a line + """ + for record in self: + bind = record.jira_bind_ids[:1] + record.jira_servicedesk_issue_url = bind.jira_servicedesk_issue_url or "" diff --git a/connector_jira_servicedesk/models/account_analytic_line/__init__.py b/connector_jira_servicedesk/models/account_analytic_line/__init__.py deleted file mode 100644 index 79ab5dc6b..000000000 --- a/connector_jira_servicedesk/models/account_analytic_line/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import common -from . import importer diff --git a/connector_jira_servicedesk/models/account_analytic_line/common.py b/connector_jira_servicedesk/models/account_analytic_line/common.py deleted file mode 100644 index 62a666050..000000000 --- a/connector_jira_servicedesk/models/account_analytic_line/common.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2020-2021 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -from odoo import api, fields, models - - -class JiraAccountAnalyticLine(models.Model): - _inherit = "jira.account.analytic.line" - - jira_servicedesk_issue_url = fields.Char( - string="Original JIRA service desk issue Link", - compute="_compute_jira_servicedesk_issue_url", - ) - - @api.depends("jira_issue_key") - def _compute_jira_servicedesk_issue_url(self): - """Compute the external URL to JIRA service desk.""" - for record in self: - jira_project = fields.first(self.project_id.jira_bind_ids) - if jira_project and record.jira_issue_key: - record.jira_servicedesk_issue_url = ( - jira_project.make_servicedesk_issue_url( # noqa: - record.jira_issue_key - ) - ) - - -class AccountAnalyticLine(models.Model): - _inherit = "account.analytic.line" - - jira_servicedesk_issue_url = fields.Char( - string="Original JIRA service desk issue Link", - compute="_compute_jira_servicedesk_issue_url", - readonly=True, - ) - - @api.depends( - "jira_bind_ids.jira_servicedesk_issue_url", - ) - def _compute_jira_servicedesk_issue_url(self): - """Compute the service desk references to JIRA. - - We assume that we have only one external record for a line - """ - for record in self: - if not record.jira_bind_ids: - continue - main_binding = record.jira_bind_ids[0] - record.jira_servicedesk_issue_url = main_binding.jira_servicedesk_issue_url diff --git a/connector_jira_servicedesk/models/account_analytic_line/importer.py b/connector_jira_servicedesk/models/account_analytic_line/importer.py deleted file mode 100644 index 313441729..000000000 --- a/connector_jira_servicedesk/models/account_analytic_line/importer.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2019-2021 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) - -from odoo.addons.component.core import Component - - -class AnalyticLineImporter(Component): - _inherit = "jira.analytic.line.importer" - - @property - def _issue_fields_to_read(self): - issue_fields = super()._issue_fields_to_read - organization_field_name = self.backend_record.organization_field_name - if not organization_field_name: - return issue_fields - return issue_fields + [organization_field_name] diff --git a/connector_jira_servicedesk/models/jira_account_analytic_line.py b/connector_jira_servicedesk/models/jira_account_analytic_line.py new file mode 100644 index 000000000..3942fb33e --- /dev/null +++ b/connector_jira_servicedesk/models/jira_account_analytic_line.py @@ -0,0 +1,22 @@ +# Copyright 2020-2021 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import api, fields, models + + +class JiraAccountAnalyticLine(models.Model): + _inherit = "jira.account.analytic.line" + + jira_servicedesk_issue_url = fields.Char( + string="Original JIRA service desk issue Link", + compute="_compute_jira_servicedesk_issue_url", + ) + + @api.depends("jira_issue_key", "project_id.jira_bind_ids") + def _compute_jira_servicedesk_issue_url(self): + """Compute the external URL to JIRA service desk.""" + for record in self: + url = "" + if jira_key := record.jira_issue_key: + if jira_project := record.project_id.jira_bind_ids[:1]: + url = jira_project.make_servicedesk_issue_url(jira_key) + record.jira_servicedesk_issue_url = url diff --git a/connector_jira_servicedesk/models/jira_backend/common.py b/connector_jira_servicedesk/models/jira_backend.py similarity index 75% rename from connector_jira_servicedesk/models/jira_backend/common.py rename to connector_jira_servicedesk/models/jira_backend.py index 740d1f1eb..289614358 100644 --- a/connector_jira_servicedesk/models/jira_backend/common.py +++ b/connector_jira_servicedesk/models/jira_backend.py @@ -22,18 +22,15 @@ class JiraBackend(models.Model): @api.model def _selection_project_template(self): - selection = super()._selection_project_template() - selection += [ + return super()._selection_project_template() + [ ("Basic", "Basic (Service Desk)"), ("IT Service Desk", "IT Service Desk (Service Desk)"), ("Customer service", "Customer Service (Service Desk)"), ] - return selection def import_organization(self): - self.env["jira.organization"].with_delay( - channel="root.connector_jira.import" - ).import_batch(self) + channel = "root.connector_jira.import" + self.env["jira.organization"].with_delay(channel=channel).import_batch(self) return True def activate_organization(self): @@ -44,7 +41,5 @@ def activate_organization(self): adapter = work.component(usage="backend.adapter") jira_fields = adapter.list_fields() for field in jira_fields: - custom_ref = field.get("schema", {}).get("custom") - if custom_ref == org_field: - self.organization_field_name = field["id"] - break + if field.get("schema", {}).get("custom") == org_field: + return self.update({"organization_field_name": field["id"]}) diff --git a/connector_jira_servicedesk/models/jira_backend/__init__.py b/connector_jira_servicedesk/models/jira_backend/__init__.py deleted file mode 100644 index e4193cf05..000000000 --- a/connector_jira_servicedesk/models/jira_backend/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import common diff --git a/connector_jira_servicedesk/models/jira_organization/common.py b/connector_jira_servicedesk/models/jira_organization.py similarity index 100% rename from connector_jira_servicedesk/models/jira_organization/common.py rename to connector_jira_servicedesk/models/jira_organization.py diff --git a/connector_jira_servicedesk/models/jira_organization/__init__.py b/connector_jira_servicedesk/models/jira_organization/__init__.py deleted file mode 100644 index c6fe6b53e..000000000 --- a/connector_jira_servicedesk/models/jira_organization/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from . import common -from . import importer -from . import adapter diff --git a/connector_jira_servicedesk/models/jira_project_base_mixin.py b/connector_jira_servicedesk/models/jira_project_base_mixin.py new file mode 100644 index 000000000..76fe6337e --- /dev/null +++ b/connector_jira_servicedesk/models/jira_project_base_mixin.py @@ -0,0 +1,17 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import fields, models + + +class JiraProjectBaseMixin(models.AbstractModel): + _inherit = "jira.project.base.mixin" + + organization_ids = fields.Many2many( + comodel_name="jira.organization", + string="Organization(s) on Jira", + domain="[('backend_id', '=', backend_id)]", + help="If organizations are set, a task will be " + "added to the project only if the project AND " + "the organization match with the selection.", + ) diff --git a/connector_jira_servicedesk/models/project_project/common.py b/connector_jira_servicedesk/models/jira_project_project.py similarity index 58% rename from connector_jira_servicedesk/models/project_project/common.py rename to connector_jira_servicedesk/models/jira_project_project.py index 448b16c77..fdd0c3dc5 100644 --- a/connector_jira_servicedesk/models/project_project/common.py +++ b/connector_jira_servicedesk/models/jira_project_project.py @@ -5,25 +5,6 @@ from odoo import _, api, exceptions, fields, models -class JiraProjectBaseFields(models.AbstractModel): - """JIRA Project Base fields - - Shared by the binding jira.project.project - and the wizard to link/create a JIRA project - """ - - _inherit = "jira.project.base.mixin" - - organization_ids = fields.Many2many( - comodel_name="jira.organization", - string="Organization(s) on Jira", - domain="[('backend_id', '=', backend_id)]", - help="If organizations are set, a task will be " - "added to the project only if the project AND " - "the organization match with the selection.", - ) - - class JiraProjectProject(models.Model): _inherit = "jira.project.project" @@ -34,9 +15,7 @@ class JiraProjectProject(models.Model): @api.model def _selection_project_type(self): - selection = super()._selection_project_type() - selection.append(("service_desk", "Service Desk")) - return selection + return super()._selection_project_type() + [("service_desk", "Service Desk")] @api.constrains("backend_id", "external_id", "organization_ids") def _constrains_jira_uniq(self): @@ -49,40 +28,35 @@ def _constrains_jira_uniq(self): organization used on Jira. """ - for binding in self: - if not binding.external_id: - continue - same_link_bindings = self.with_context(active_test=False).search( + for binding in self.filtered("external_id"): + for other in self.with_context(active_test=False).search( [ ("id", "!=", binding.id), ("backend_id", "=", binding.backend_id.id), ("external_id", "=", binding.external_id), ] - ) - for other in same_link_bindings: + ): my_orgs = binding.organization_ids other_orgs = other.organization_ids if not my_orgs and not other_orgs: raise exceptions.ValidationError( _( "The project %s is already linked with the same" - " JIRA project without organization." + " JIRA project without organization.", + other.display_name, ) - % (other.display_name) ) - if set(my_orgs.ids) == set(other_orgs.ids): + if my_orgs == other_orgs: raise exceptions.ValidationError( _( "The project %s is already linked with this " - "JIRA project and similar organizations." + "JIRA project and similar organizations.", + other.display_name, ) - % (other.display_name) ) def make_servicedesk_issue_url(self, jira_issue_id): - return urllib.parse.urljoin( - self.backend_id.uri, - "/service_desk/customer/portal/{}/{}".format( - self.servicedesk_customer_portal_number, jira_issue_id - ), - ) + base = self.backend_id.uri + num = self.servicedesk_customer_portal_number + url = f"/service_desk/customer/portal/{num}/{jira_issue_id}" + return urllib.parse.urljoin(base, url) diff --git a/connector_jira_servicedesk/models/project_project/__init__.py b/connector_jira_servicedesk/models/project_project/__init__.py deleted file mode 100644 index 87c19778d..000000000 --- a/connector_jira_servicedesk/models/project_project/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from . import common -from . import binder -from . import project_link_jira diff --git a/connector_jira_servicedesk/models/project_task/__init__.py b/connector_jira_servicedesk/models/project_task/__init__.py deleted file mode 100644 index 35099a471..000000000 --- a/connector_jira_servicedesk/models/project_task/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import importer diff --git a/connector_jira_servicedesk/models/project_task/importer.py b/connector_jira_servicedesk/models/project_task/importer.py deleted file mode 100644 index c83513e25..000000000 --- a/connector_jira_servicedesk/models/project_task/importer.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2016-Today Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) - -from odoo.addons.component.core import Component - - -class ProjectTaskProjectMatcher(Component): - _inherit = "jira.task.project.matcher" - - def find_project_binding(self, jira_task_data, unwrap=False): - organizations = self.env["jira.organization"].browse() - jira_org_ids = self.component(usage="organization.from.task").get_jira_org_ids( - jira_task_data - ) - binder = self.binder_for("jira.organization") - for jira_org_id in jira_org_ids: - organizations |= binder.to_internal(jira_org_id) - jira_project_id = jira_task_data["fields"]["project"]["id"] - binder = self.binder_for("jira.project.project") - return binder.to_internal( - jira_project_id, - unwrap=unwrap, - organizations=organizations, - ) - - -class OrganizationsFromTask(Component): - _name = "jira.organization.from.task" - _inherit = ["jira.base"] - _usage = "organization.from.task" - - def get_jira_org_ids(self, jira_task_data): - organization_field_name = self.backend_record.organization_field_name - if not organization_field_name: - return [] - - task_fields = jira_task_data.get("fields", {}) - return [rec["id"] for rec in task_fields.get(organization_field_name) or []] - - -class ProjectTaskImporter(Component): - _inherit = "jira.project.task.importer" - - def _get_external_data(self): - """Return the raw Jira data for ``self.external_id``""" - result = super()._get_external_data() - return result - - def _import_dependencies(self): - """Import the dependencies for the record""" - res = super()._import_dependencies() - jira_org_ids = self.component(usage="organization.from.task").get_jira_org_ids( - self.external_record - ) - for jira_org_id in jira_org_ids: - self._import_dependency(jira_org_id, "jira.organization") - return res diff --git a/connector_jira_servicedesk/tests/__init__.py b/connector_jira_servicedesk/tests/__init__.py index 711c3a737..4733869ff 100644 --- a/connector_jira_servicedesk/tests/__init__.py +++ b/connector_jira_servicedesk/tests/__init__.py @@ -1 +1 @@ -from . import test_import_organization +# from . import test_import_organization diff --git a/connector_jira_servicedesk/views/jira_backend.xml b/connector_jira_servicedesk/views/jira_backend.xml new file mode 100644 index 000000000..f45677003 --- /dev/null +++ b/connector_jira_servicedesk/views/jira_backend.xml @@ -0,0 +1,63 @@ + + + + jira.backend.form + jira.backend + + + + + +