diff --git a/connector_jira_servicedesk/README.rst b/connector_jira_servicedesk/README.rst new file mode 100644 index 00000000..1148035b --- /dev/null +++ b/connector_jira_servicedesk/README.rst @@ -0,0 +1,125 @@ +======================================= +JIRA Connector - Service Desk Extension +======================================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fconnector--jira-lightgray.png?logo=github + :target: https://github.com/OCA/connector-jira/tree/13.0/connector_jira_servicedesk + :alt: OCA/connector-jira +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/connector-jira-13-0/connector-jira-13-0-connector_jira_servicedesk + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/233/13.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module add support with jira servicedesk + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Setup +~~~~~ + +A new button is added on the JIRA backend, to import the organizations +of JIRA. Before, be sure to use the button "Configure Organization Link" +in the "Advanced Configuration" tab. + + +Features +~~~~~~~~ + +Organizations +~~~~~~~~~~~~~ + +On Service Desk, you can share projects with Organizations. +You may want to use different Odoo projects according to the +organizations. This is what this extension allows. + +Example: + +* You have one Service Desk project named "Earth Project" with key EARTH +* On JIRA SD You share this project with organizations Themis and Rhea +* However on Odoo, you want to track the hours differently for Themis and Rhea + +Steps on Odoo: + +* Create a Themis project, use the "Link with JIRA" action with the key EARTH +* When you hit Next, the organization(s) you want to link must be set +* Repeat with another project for Rhea + +If the project binding for the synchronization already exists, you can still edit it in the settings of the project and change the organizations. + +When a task or worklog is imported, it will search for a project having +exactly the same set of organizations than the one of the task. If no +project with the same set is found and you have a project configured +without organization, the task will be linked to it. + +This means that, on Odoo, you can have shared project altogether with dedicated +ones, while you only have one project on JIRA. + +* Tasks with org "Themis" will be attached to this project +* Tasks with org "Rhea" will be attached to this project +* Tasks with orgs "Themis" and "Rhea" will be attached to another project "Themis and Rhea" +* The rest of the tasks will be attached to a fourth project (configured without organizations) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Patrick Tombez +* Guewen Baconnier +* Jaime Arroyo +* Akim Juillerat +* Denis Leemann + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/connector-jira `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/connector_jira_servicedesk/__init__.py b/connector_jira_servicedesk/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/connector_jira_servicedesk/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/connector_jira_servicedesk/__manifest__.py b/connector_jira_servicedesk/__manifest__.py new file mode 100644 index 00000000..9376ee8d --- /dev/null +++ b/connector_jira_servicedesk/__manifest__.py @@ -0,0 +1,18 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{ + "name": "JIRA Connector - Service Desk Extension", + "version": "13.0.1.0.0", + "author": "Camptocamp,Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Connector", + "depends": ["connector_jira"], + "website": "https://github.com/camptocamp/connector-jira", + "data": [ + "views/jira_backend_views.xml", + "views/project_project_views.xml", + "views/project_link_jira_views.xml", + "security/ir.model.access.csv", + ], + "installable": True, +} diff --git a/connector_jira_servicedesk/i18n/connector_jira_servicedesk.pot b/connector_jira_servicedesk/i18n/connector_jira_servicedesk.pot new file mode 100644 index 00000000..1f84cbf6 --- /dev/null +++ b/connector_jira_servicedesk/i18n/connector_jira_servicedesk.pot @@ -0,0 +1,160 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector_jira_servicedesk +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: connector_jira_servicedesk +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Activate the synchronization of the Organization field.\n" +" Only on JIRA ServiceDesk. The field contains the name of\n" +" the JIRA custom field that contains the Organization." +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Configure Organization" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_create_uid +msgid "Created by" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_create_date +msgid "Created on" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_display_name +msgid "Display Name" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_id +msgid "ID" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,help:connector_jira_servicedesk.field_jira_project_base_mixin_organization_ids +#: model:ir.model.fields,help:connector_jira_servicedesk.field_jira_project_project_organization_ids +#: model:ir.model.fields,help:connector_jira_servicedesk.field_project_link_jira_organization_ids +msgid "If organizations are set, a task will be added to the project only if the project AND the organization match with the selection." +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Import Organizations" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model,name:connector_jira_servicedesk.model_jira_backend +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_backend_id +msgid "Jira Backend" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model,name:connector_jira_servicedesk.model_jira_organization +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Jira Organization" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model,name:connector_jira_servicedesk.model_jira_project_project +msgid "Jira Projects" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model,name:connector_jira_servicedesk.model_project_link_jira +msgid "Link Project with JIRA" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_name +msgid "Name" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_backend_organization_field_name +msgid "Organization Field" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_project_base_mixin_organization_ids +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_project_project_organization_ids +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_project_link_jira_organization_ids +msgid "Organization(s) on Jira" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_backend_organization_ids +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Organizations" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,field_description:connector_jira_servicedesk.field_jira_organization_project_ids +msgid "Project" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.view_jira_backend_form +msgid "Run" +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model.fields,help:connector_jira_servicedesk.field_jira_backend_organization_field_name +msgid "The 'Organization' field on JIRA is a custom field. The name of the field is something like 'customfield_10002'. " +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.ui.view,arch_db:connector_jira_servicedesk.project_link_jira_form +msgid "The organizations you choose will define how the tasks and worklogs are attached to the project.\n" +" If a task is assigned to an organization, it will be assigned\n" +" to an Odoo project linked to the JIRA project only if the\n" +" organization match. If no project with an organization exists,\n" +" the task will be assigned to a linked project without organization.\n" +" If no such project exists in Odoo, the task is ignored." +msgstr "" + +#. module: connector_jira_servicedesk +#: code:addons/connector_jira_servicedesk/models/project_project/common.py:58 +#, python-format +msgid "The project %s is already linked with the same JIRA project without organization." +msgstr "" + +#. module: connector_jira_servicedesk +#: code:addons/connector_jira_servicedesk/models/project_project/common.py:63 +#, python-format +msgid "The project %s is already linked with this JIRA project and similar organizations." +msgstr "" + +#. module: connector_jira_servicedesk +#: model:ir.model,name:connector_jira_servicedesk.model_jira_project_base_mixin +msgid "jira.project.base.mixin" +msgstr "" diff --git a/connector_jira_servicedesk/models/__init__.py b/connector_jira_servicedesk/models/__init__.py new file mode 100644 index 00000000..6b2bb84b --- /dev/null +++ b/connector_jira_servicedesk/models/__init__.py @@ -0,0 +1,5 @@ +from . import account_analytic_line +from . import jira_backend +from . import project_project +from . import jira_organization +from . import project_task diff --git a/connector_jira_servicedesk/models/account_analytic_line/__init__.py b/connector_jira_servicedesk/models/account_analytic_line/__init__.py new file mode 100644 index 00000000..79ab5dc6 --- /dev/null +++ b/connector_jira_servicedesk/models/account_analytic_line/__init__.py @@ -0,0 +1,2 @@ +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 new file mode 100644 index 00000000..86c1cf35 --- /dev/null +++ b/connector_jira_servicedesk/models/account_analytic_line/common.py @@ -0,0 +1,44 @@ +# 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 new file mode 100644 index 00000000..31344172 --- /dev/null +++ b/connector_jira_servicedesk/models/account_analytic_line/importer.py @@ -0,0 +1,16 @@ +# 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_backend/__init__.py b/connector_jira_servicedesk/models/jira_backend/__init__.py new file mode 100644 index 00000000..e4193cf0 --- /dev/null +++ b/connector_jira_servicedesk/models/jira_backend/__init__.py @@ -0,0 +1 @@ +from . import common diff --git a/connector_jira_servicedesk/models/jira_backend/common.py b/connector_jira_servicedesk/models/jira_backend/common.py new file mode 100644 index 00000000..68fb9c06 --- /dev/null +++ b/connector_jira_servicedesk/models/jira_backend/common.py @@ -0,0 +1,48 @@ +# Copyright 2016-2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import api, fields, models + + +class JiraBackend(models.Model): + _inherit = "jira.backend" + + organization_ids = fields.One2many( + comodel_name="jira.organization", + inverse_name="backend_id", + string="Organizations", + readonly=True, + ) + + organization_field_name = fields.Char( + string="Organization Field", + help="The 'Organization' field on JIRA is a custom field. " + "The name of the field is something like 'customfield_10002'. ", + ) + + @api.model + def _selection_project_template(self): + selection = super()._selection_project_template() + selection += [ + ("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"].import_batch(self) + return True + + def activate_organization(self): + """Get organization field name from JIRA web-service""" + self.ensure_one() + org_field = "com.atlassian.servicedesk:sd-customer-organizations" + with self.work_on("jira.backend") as work: + 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 diff --git a/connector_jira_servicedesk/models/jira_organization/__init__.py b/connector_jira_servicedesk/models/jira_organization/__init__.py new file mode 100644 index 00000000..c6fe6b53 --- /dev/null +++ b/connector_jira_servicedesk/models/jira_organization/__init__.py @@ -0,0 +1,3 @@ +from . import common +from . import importer +from . import adapter diff --git a/connector_jira_servicedesk/models/jira_organization/adapter.py b/connector_jira_servicedesk/models/jira_organization/adapter.py new file mode 100644 index 00000000..6d254ef6 --- /dev/null +++ b/connector_jira_servicedesk/models/jira_organization/adapter.py @@ -0,0 +1,77 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import logging + +from odoo.addons.component.core import Component + +_logger = logging.getLogger(__name__) + +try: + from jira.resources import Resource + from jira.utils import CaseInsensitiveDict +except ImportError as err: + _logger.debug(err) + Resource = object + CaseInsensitiveDict = None + + +class Organization(Resource): + """A Service Desk Organization.""" + + def __init__(self, options, session, raw=None): + super().__init__( + "organization/{0}", options, session, "{server}/rest/servicedeskapi/{path}" + ) + if raw: + self._parse_raw(raw) + + +class OrganizationAdapter(Component): + _name = "jira.organization.adapter" + _inherit = ["jira.webservice.adapter"] + _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 + # the client about this. + _desk_headers = ( + CaseInsensitiveDict({"X-ExperimentalApi": "opt-in"}) + if (CaseInsensitiveDict) + else None + ) + + _desk_api_path_base = "{server}/rest/servicedeskapi/{path}" + + def __init__(self, work_context): + super().__init__(work_context) + self.client._session.headers.update(self._desk_headers) + + def read(self, id_): + # pylint: disable=method-required-super + organization = Organization(self.client._options, self.client._session) + with self.handle_404(): + organization.find(id_) + return organization.raw + + 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: + result = self.client._get_json( + "organization", + params={ + "start": start, + # 50 items per page is the maximum allowed by Jira + "limit": start + 50, + }, + base=self._desk_api_path_base, + ) + start += 50 + orgs += result["values"] + if result["isLastPage"]: + break + + return orgs diff --git a/connector_jira_servicedesk/models/jira_organization/common.py b/connector_jira_servicedesk/models/jira_organization/common.py new file mode 100644 index 00000000..d5bd039a --- /dev/null +++ b/connector_jira_servicedesk/models/jira_organization/common.py @@ -0,0 +1,27 @@ +# Copyright 2016-2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +from odoo import fields, models + +from odoo.addons.queue_job.job import job + + +class JiraOrganization(models.Model): + _name = "jira.organization" + _inherit = "jira.binding" + _description = "Jira Organization" + + name = fields.Char("Name", required=True, readonly=True) + backend_id = fields.Many2one(ondelete="cascade") + project_ids = fields.Many2many(comodel_name="jira.project.project") + + @job(default_channel="root.connector_jira.import") + def import_batch(self, backend, from_date=None, to_date=None): + """ Prepare a batch import of organization from Jira + + from_date and to_date are ignored for organization + """ + with backend.work_on(self._name) as work: + importer = work.component(usage="batch.importer") + importer.run() diff --git a/connector_jira_servicedesk/models/jira_organization/importer.py b/connector_jira_servicedesk/models/jira_organization/importer.py new file mode 100644 index 00000000..1ee724f3 --- /dev/null +++ b/connector_jira_servicedesk/models/jira_organization/importer.py @@ -0,0 +1,36 @@ +# 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} + + +class OrganizationBatchImporter(Component): + """ Import the Jira Organizations + + For every id in in the list of organizations, a direct import is done. + """ + + _name = "jira.organization.batch.importer" + _inherit = "jira.direct.batch.importer" + _apply_on = ["jira.organization"] + + def run(self): + """ Run the synchronization """ + records = self.backend_adapter.search() + for record in records: + self._import_record(record["id"], record=record) diff --git a/connector_jira_servicedesk/models/project_project/__init__.py b/connector_jira_servicedesk/models/project_project/__init__.py new file mode 100644 index 00000000..87c19778 --- /dev/null +++ b/connector_jira_servicedesk/models/project_project/__init__.py @@ -0,0 +1,3 @@ +from . import common +from . import binder +from . import project_link_jira diff --git a/connector_jira_servicedesk/models/project_project/binder.py b/connector_jira_servicedesk/models/project_project/binder.py new file mode 100644 index 00000000..6b26c8ee --- /dev/null +++ b/connector_jira_servicedesk/models/project_project/binder.py @@ -0,0 +1,69 @@ +# Copyright 2016-2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import logging + +from odoo import tools + +from odoo.addons.component.core import Component + +_logger = logging.getLogger(__name__) + + +class JiraProjectBinder(Component): + _inherit = "jira.project.binder" + + def to_internal(self, external_id, unwrap=False, organizations=None): + """ Give the Odoo recordset for an external ID + + When organizations are passed (ids are odoo ids), the binder + will return: + + * a project linked with JIRA with the exact set of organizations + * if no project has the exact same set, a project linked without + organization set on the binding + + If no organizations are passed, only project bindings + without organization match. + + :param external_id: external ID for which we want + the Odoo ID + :param unwrap: if True, returns the normal record + else return the binding record + :param organizations: jira.organization recordset + :return: a recordset, depending on the value of unwrap, + or an empty recordset if the external_id is not mapped + :rtype: recordset + """ + domain = [ + (self._external_field, "=", tools.ustr(external_id)), + (self._backend_field, "=", self.backend_record.id), + ] + if not organizations: + 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: + if not candidate.organization_ids: + fallback = candidate + continue + + if organizations in candidate.organization_ids: + binding = candidate + break + if not binding: + binding = fallback + else: + 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 diff --git a/connector_jira_servicedesk/models/project_project/common.py b/connector_jira_servicedesk/models/project_project/common.py new file mode 100644 index 00000000..448b16c7 --- /dev/null +++ b/connector_jira_servicedesk/models/project_project/common.py @@ -0,0 +1,88 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +import urllib.parse + +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" + + servicedesk_customer_portal_number = fields.Integer( + string="Service desk customer portal ID", + help="This number is used to compute servicedesk URL on analytic lines", + ) + + @api.model + def _selection_project_type(self): + selection = super()._selection_project_type() + selection.append(("service_desk", "Service Desk")) + return selection + + @api.constrains("backend_id", "external_id", "organization_ids") + def _constrains_jira_uniq(self): + """Modify the base constraint by adding organizations + + Rather than checking unicity of backend+jira id, we validate + backend+jira id+organizations ids. + + It allows to have different odoo projects depending of the + organization used on Jira. + + """ + for binding in self: + if not binding.external_id: + continue + same_link_bindings = 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." + ) + % (other.display_name) + ) + if set(my_orgs.ids) == set(other_orgs.ids): + raise exceptions.ValidationError( + _( + "The project %s is already linked with this " + "JIRA project and similar organizations." + ) + % (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 + ), + ) diff --git a/connector_jira_servicedesk/models/project_project/project_link_jira.py b/connector_jira_servicedesk/models/project_project/project_link_jira.py new file mode 100644 index 00000000..8a635634 --- /dev/null +++ b/connector_jira_servicedesk/models/project_project/project_link_jira.py @@ -0,0 +1,34 @@ +# Copyright 2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class ProjectLinkJira(models.TransientModel): + _inherit = "project.link.jira" + + @api.model + def _selection_state(self): + states = super()._selection_state() + states.append(("link_organizations", "Link Organizations")) + return states + + def state_exit_start(self): + if self.sync_action == "link": + self.state = "link_organizations" + else: + super().state_exit_start() + + def state_exit_link_organizations(self): + if not self.jira_project_id: + self._link_binding() + self.state = "issue_types" + + def _prepare_link_binding_values(self, jira_project): + values = super()._prepare_link_binding_values(jira_project) + values["organization_ids"] = [(6, 0, self.organization_ids.ids)] + return values diff --git a/connector_jira_servicedesk/models/project_task/__init__.py b/connector_jira_servicedesk/models/project_task/__init__.py new file mode 100644 index 00000000..35099a47 --- /dev/null +++ b/connector_jira_servicedesk/models/project_task/__init__.py @@ -0,0 +1 @@ +from . import importer diff --git a/connector_jira_servicedesk/models/project_task/importer.py b/connector_jira_servicedesk/models/project_task/importer.py new file mode 100644 index 00000000..2a4d693a --- /dev/null +++ b/connector_jira_servicedesk/models/project_task/importer.py @@ -0,0 +1,54 @@ +# 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 + + +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""" + 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") diff --git a/connector_jira_servicedesk/readme/CONTRIBUTORS.rst b/connector_jira_servicedesk/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..d9338385 --- /dev/null +++ b/connector_jira_servicedesk/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* Patrick Tombez +* Guewen Baconnier +* Jaime Arroyo +* Akim Juillerat +* Denis Leemann diff --git a/connector_jira_servicedesk/readme/DESCRIPTION.rst b/connector_jira_servicedesk/readme/DESCRIPTION.rst new file mode 100644 index 00000000..87c066e8 --- /dev/null +++ b/connector_jira_servicedesk/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module add support with jira servicedesk diff --git a/connector_jira_servicedesk/readme/USAGE.rst b/connector_jira_servicedesk/readme/USAGE.rst new file mode 100644 index 00000000..2781c133 --- /dev/null +++ b/connector_jira_servicedesk/readme/USAGE.rst @@ -0,0 +1,44 @@ +Setup +~~~~~ + +A new button is added on the JIRA backend, to import the organizations +of JIRA. Before, be sure to use the button "Configure Organization Link" +in the "Advanced Configuration" tab. + + +Features +~~~~~~~~ + +Organizations +~~~~~~~~~~~~~ + +On Service Desk, you can share projects with Organizations. +You may want to use different Odoo projects according to the +organizations. This is what this extension allows. + +Example: + +* You have one Service Desk project named "Earth Project" with key EARTH +* On JIRA SD You share this project with organizations Themis and Rhea +* However on Odoo, you want to track the hours differently for Themis and Rhea + +Steps on Odoo: + +* Create a Themis project, use the "Link with JIRA" action with the key EARTH +* When you hit Next, the organization(s) you want to link must be set +* Repeat with another project for Rhea + +If the project binding for the synchronization already exists, you can still edit it in the settings of the project and change the organizations. + +When a task or worklog is imported, it will search for a project having +exactly the same set of organizations than the one of the task. If no +project with the same set is found and you have a project configured +without organization, the task will be linked to it. + +This means that, on Odoo, you can have shared project altogether with dedicated +ones, while you only have one project on JIRA. + +* Tasks with org "Themis" will be attached to this project +* Tasks with org "Rhea" will be attached to this project +* Tasks with orgs "Themis" and "Rhea" will be attached to another project "Themis and Rhea" +* The rest of the tasks will be attached to a fourth project (configured without organizations) diff --git a/connector_jira_servicedesk/security/ir.model.access.csv b/connector_jira_servicedesk/security/ir.model.access.csv new file mode 100644 index 00000000..58bb1663 --- /dev/null +++ b/connector_jira_servicedesk/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +access_jira_organization,access_jira_organization,model_jira_organization,base.group_user,1,0,0,0 +access_jira_organization_manager,access_jira_organization connector manager,model_jira_organization,connector.group_connector_manager,1,1,1,1 diff --git a/connector_jira_servicedesk/static/description/icon.png b/connector_jira_servicedesk/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/connector_jira_servicedesk/static/description/icon.png differ diff --git a/connector_jira_servicedesk/static/description/index.html b/connector_jira_servicedesk/static/description/index.html new file mode 100644 index 00000000..34faa4a5 --- /dev/null +++ b/connector_jira_servicedesk/static/description/index.html @@ -0,0 +1,472 @@ + + + + + + +JIRA Connector - Service Desk Extension + + + +
+

JIRA Connector - Service Desk Extension

+ + +

Beta License: AGPL-3 OCA/connector-jira Translate me on Weblate Try me on Runbot

+

This module add support with jira servicedesk

+

Table of contents

+ +
+

Usage

+
+

Setup

+

A new button is added on the JIRA backend, to import the organizations +of JIRA. Before, be sure to use the button “Configure Organization Link” +in the “Advanced Configuration” tab.

+
+ +
+

Organizations

+

On Service Desk, you can share projects with Organizations. +You may want to use different Odoo projects according to the +organizations. This is what this extension allows.

+

Example:

+
    +
  • You have one Service Desk project named “Earth Project” with key EARTH
  • +
  • On JIRA SD You share this project with organizations Themis and Rhea
  • +
  • However on Odoo, you want to track the hours differently for Themis and Rhea
  • +
+

Steps on Odoo:

+
    +
  • Create a Themis project, use the “Link with JIRA” action with the key EARTH
  • +
  • When you hit Next, the organization(s) you want to link must be set
  • +
  • Repeat with another project for Rhea
  • +
+

If the project binding for the synchronization already exists, you can still edit it in the settings of the project and change the organizations.

+

When a task or worklog is imported, it will search for a project having +exactly the same set of organizations than the one of the task. If no +project with the same set is found and you have a project configured +without organization, the task will be linked to it.

+

This means that, on Odoo, you can have shared project altogether with dedicated +ones, while you only have one project on JIRA.

+
    +
  • Tasks with org “Themis” will be attached to this project
  • +
  • Tasks with org “Rhea” will be attached to this project
  • +
  • Tasks with orgs “Themis” and “Rhea” will be attached to another project “Themis and Rhea”
  • +
  • The rest of the tasks will be attached to a fourth project (configured without organizations)
  • +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/connector-jira project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/connector_jira_servicedesk/tests/__init__.py b/connector_jira_servicedesk/tests/__init__.py new file mode 100644 index 00000000..711c3a73 --- /dev/null +++ b/connector_jira_servicedesk/tests/__init__.py @@ -0,0 +1 @@ +from . import test_import_organization diff --git a/connector_jira_servicedesk/tests/common.py b/connector_jira_servicedesk/tests/common.py new file mode 100644 index 00000000..4f96d954 --- /dev/null +++ b/connector_jira_servicedesk/tests/common.py @@ -0,0 +1,8 @@ +# Copyright 2019-2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from os.path import dirname + +from odoo.addons.connector_jira.tests.common import get_recorder + +recorder = get_recorder(base_path=dirname(__file__)) diff --git a/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_batch.yaml b/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_batch.yaml new file mode 100644 index 00000000..1e08be0d --- /dev/null +++ b/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_batch.yaml @@ -0,0 +1,429 @@ +interactions: + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + method: GET + uri: http://jira:8080/rest/api/2/serverInfo + response: + body: + { + string: '{"baseUrl":"http://localhost:8080","version":"7.12.3","versionNumbers":[7,12,3],"deploymentType":"Server","buildNumber":712004,"buildDate":"2018-10-12T00:00:00.000+0000","serverTime":"2019-04-09T07:25:35.143+0000","scmInfo":"5ef91d760d7124da5ebec5c16a948a4a807698df","serverTitle":"Jira"}', + } + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:25:35 GMT"] + Set-Cookie: + [ + JSESSIONID=E70FE92161655AB0AB0CCFA4FFB1A494; Path=/; HttpOnly, + atlassian.xsrf.token=BYG3-6SPF-0UM1-2LBO_d962a47ccf42cb8fae37c2165e943864fdd7a3f4_lin; + Path=/, + ] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [445x2278x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [1xm845a] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["288"] + status: {code: 200, message: ""} + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + Cookie: + - !!binary | + YXRsYXNzaWFuLnhzcmYudG9rZW49QllHMy02U1BGLTBVTTEtMkxCT19kOTYyYTQ3Y2NmNDJjYjhm + YWUzN2MyMTY1ZTk0Mzg2NGZkZDdhM2Y0X2xpbjsgSlNFU1NJT05JRD1FNzBGRTkyMTYxNjU1QUIw + QUIwQ0NGQTRGRkIxQTQ5NA== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + method: GET + uri: http://jira:8080/rest/api/2/field + response: + body: {string: "[{\"id\":\"issuetype\",\"name\":\"Issue + Type\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + issuetype\",\"type\"],\"schema\":{\"type\":\"issuetype\",\"system\":\"issuetype\"\ + }},{\"id\":\"timespent\",\"name\":\"Time + Spent\",\"custom\":false,\"orderable\"\ + :false,\"navigable\":true,\"searchable\":false,\"clauseNames\":[\"timespent\"\ + ],\"schema\":{\"type\":\"number\",\"system\":\"timespent\"}},{\"id\":\"project\"\ + ,\"name\":\"Project\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"project\"],\"schema\":{\"type\":\"project\"\ + ,\"system\":\"project\"}},{\"id\":\"fixVersions\",\"name\":\"Fix + Version/s\"\ + ,\"custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"fixVersion\"],\"schema\":{\"type\":\"array\",\"items\":\"\ + version\",\"system\":\"fixVersions\"}},{\"id\":\"aggregatetimespent\",\"name\"\ + :\"\u03A3 Time Spent\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\":\"number\"\ + ,\"system\":\"aggregatetimespent\"}},{\"id\":\"resolution\",\"name\":\"Resolution\"\ + ,\"custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"resolution\"],\"schema\":{\"type\":\"resolution\",\"system\"\ + :\"resolution\"}},{\"id\":\"customfield_10104\",\"name\":\"Epic Color\",\"\ + custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10104]\",\"Epic + Color\"],\"schema\":{\"type\":\"string\"\ + ,\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-color\",\"customId\":10104}},{\"\ + id\":\"customfield_10105\",\"name\":\"Rank\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10105]\"\ + ,\"Rank\"],\"schema\":{\"type\":\"any\",\"custom\":\"com.pyxis.greenhopper.jira:gh-lexo-rank\"\ + ,\"customId\":10105}},{\"id\":\"customfield_10106\",\"name\":\"Story + Points\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10106]\",\"Story + Points\"],\"schema\":{\"type\":\"number\"\ + ,\"custom\":\"com.atlassian.jira.plugin.system.customfieldtypes:float\",\"\ + customId\":10106}},{\"id\":\"resolutiondate\",\"name\":\"Resolved\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"resolutiondate\",\"resolved\"],\"schema\":{\"type\":\"datetime\",\"system\"\ + :\"resolutiondate\"}},{\"id\":\"workratio\",\"name\":\"Work + Ratio\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"workratio\"],\"schema\":{\"type\":\"number\",\"system\":\"workratio\"\ + }},{\"id\":\"lastViewed\",\"name\":\"Last + Viewed\",\"custom\":false,\"orderable\"\ + :false,\"navigable\":true,\"searchable\":false,\"clauseNames\":[\"lastViewed\"\ + ],\"schema\":{\"type\":\"datetime\",\"system\":\"lastViewed\"}},{\"id\":\"\ + watches\",\"name\":\"Watchers\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[\"watchers\"],\"schema\":{\"type\"\ + :\"watches\",\"system\":\"watches\"}},{\"id\":\"thumbnail\",\"name\":\"Images\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"\ + clauseNames\":[]},{\"id\":\"created\",\"name\":\"Created\",\"custom\":false,\"\ + orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + created\",\"createdDate\"],\"schema\":{\"type\":\"datetime\",\"system\":\"\ + created\"}},{\"id\":\"priority\",\"name\":\"Priority\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + priority\"],\"schema\":{\"type\":\"priority\",\"system\":\"priority\"}},{\"\ + id\":\"customfield_10100\",\"name\":\"Sprint\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10100]\"\ + ,\"Sprint\"],\"schema\":{\"type\":\"array\",\"items\":\"string\",\"custom\"\ + :\"com.pyxis.greenhopper.jira:gh-sprint\",\"customId\":10100}},{\"id\":\"\ + customfield_10101\",\"name\":\"Epic + Link\",\"custom\":true,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10101]\",\"Epic\ + \ + Link\"],\"schema\":{\"type\":\"any\",\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-link\"\ + ,\"customId\":10101}},{\"id\":\"customfield_10102\",\"name\":\"Epic + Status\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10102]\",\"Epic + Status\"],\"schema\":{\"type\":\"option\"\ + ,\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-status\",\"customId\":10102}},{\"\ + id\":\"labels\",\"name\":\"Labels\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"labels\"],\"schema\"\ + :{\"type\":\"array\",\"items\":\"string\",\"system\":\"labels\"}},{\"id\"\ + :\"customfield_10103\",\"name\":\"Epic Name\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10103]\"\ + ,\"Epic + Name\"],\"schema\":{\"type\":\"string\",\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-label\"\ + ,\"customId\":10103}},{\"id\":\"timeestimate\",\"name\":\"Remaining + Estimate\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"\ + clauseNames\":[\"remainingEstimate\",\"timeestimate\"],\"schema\":{\"type\"\ + :\"number\",\"system\":\"timeestimate\"}},{\"id\":\"aggregatetimeoriginalestimate\"\ + ,\"name\":\"\u03A3 Original + Estimate\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\"\ + :\"number\",\"system\":\"aggregatetimeoriginalestimate\"}},{\"id\":\"versions\"\ + ,\"name\":\"Affects + Version/s\",\"custom\":false,\"orderable\":true,\"navigable\"\ + :true,\"searchable\":true,\"clauseNames\":[\"affectedVersion\"],\"schema\"\ + :{\"type\":\"array\",\"items\":\"version\",\"system\":\"versions\"}},{\"id\"\ + :\"issuelinks\",\"name\":\"Linked Issues\",\"custom\":false,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[],\"schema\"\ + :{\"type\":\"array\",\"items\":\"issuelinks\",\"system\":\"issuelinks\"}},{\"\ + id\":\"assignee\",\"name\":\"Assignee\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"assignee\"],\"schema\"\ + :{\"type\":\"user\",\"system\":\"assignee\"}},{\"id\":\"updated\",\"name\"\ + :\"Updated\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"updated\",\"updatedDate\"],\"schema\":{\"type\":\"\ + datetime\",\"system\":\"updated\"}},{\"id\":\"status\",\"name\":\"Status\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"status\"],\"schema\":{\"type\":\"status\",\"system\":\"status\"\ + }},{\"id\":\"components\",\"name\":\"Component/s\",\"custom\":false,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"component\"\ + ],\"schema\":{\"type\":\"array\",\"items\":\"component\",\"system\":\"components\"\ + }},{\"id\":\"issuekey\",\"name\":\"Key\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[\"id\",\"issue\",\"\ + issuekey\",\"key\"]},{\"id\":\"timeoriginalestimate\",\"name\":\"Original\ + \ + Estimate\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :false,\"clauseNames\":[\"originalEstimate\",\"timeoriginalestimate\"],\"\ + schema\":{\"type\":\"number\",\"system\":\"timeoriginalestimate\"}},{\"id\"\ + :\"description\",\"name\":\"Description\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"description\"],\"\ + schema\":{\"type\":\"string\",\"system\":\"description\"}},{\"id\":\"timetracking\"\ + ,\"name\":\"Time + Tracking\",\"custom\":false,\"orderable\":true,\"navigable\"\ + :false,\"searchable\":true,\"clauseNames\":[],\"schema\":{\"type\":\"timetracking\"\ + ,\"system\":\"timetracking\"}},{\"id\":\"customfield_10203\",\"name\":\"Organizations\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10203]\",\"Organizations\"],\"schema\":{\"type\":\"array\"\ + ,\"items\":\"sd-customerorganization\",\"custom\":\"com.atlassian.servicedesk:sd-customer-organizations\"\ + ,\"customId\":10203}},{\"id\":\"customfield_10204\",\"name\":\"Satisfaction\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10204]\",\"Satisfaction\"],\"schema\":{\"type\":\"any\"\ + ,\"custom\":\"com.atlassian.servicedesk:sd-request-feedback\",\"customId\"\ + :10204}},{\"id\":\"security\",\"name\":\"Security + Level\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + level\"],\"schema\":{\"type\":\"securitylevel\",\"system\":\"security\"}},{\"\ + id\":\"customfield_10205\",\"name\":\"Satisfaction + date\",\"custom\":true,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + cf[10205]\",\"Satisfaction + date\"],\"schema\":{\"type\":\"datetime\",\"custom\"\ + :\"com.atlassian.servicedesk:sd-request-feedback-date\",\"customId\":10205}},{\"\ + id\":\"customfield_10206\",\"name\":\"Approvers\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"Approvers\"\ + ,\"cf[10206]\"],\"schema\":{\"type\":\"array\",\"items\":\"user\",\"custom\"\ + :\"com.atlassian.jira.plugin.system.customfieldtypes:multiuserpicker\",\"\ + customId\":10206}},{\"id\":\"attachment\",\"name\":\"Attachment\",\"custom\"\ + :false,\"orderable\":true,\"navigable\":false,\"searchable\":true,\"clauseNames\"\ + :[\"attachments\"],\"schema\":{\"type\":\"array\",\"items\":\"attachment\"\ + ,\"system\":\"attachment\"}},{\"id\":\"aggregatetimeestimate\",\"name\":\"\ + \u03A3 Remaining + Estimate\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\":\"number\"\ + ,\"system\":\"aggregatetimeestimate\"}},{\"id\":\"customfield_10207\",\"name\"\ + :\"Time to + resolution\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"cf[10207]\",\"Time to resolution\"],\"\ + schema\":{\"type\":\"sd-servicelevelagreement\",\"custom\":\"com.atlassian.servicedesk:sd-sla-field\"\ + ,\"customId\":10207}},{\"id\":\"customfield_10208\",\"name\":\"Time to + first\ + \ + response\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"cf[10208]\",\"Time to first response\"],\"schema\"\ + :{\"type\":\"sd-servicelevelagreement\",\"custom\":\"com.atlassian.servicedesk:sd-sla-field\"\ + ,\"customId\":10208}},{\"id\":\"summary\",\"name\":\"Summary\",\"custom\"\ + :false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"summary\"],\"schema\":{\"type\":\"string\",\"system\":\"summary\"}},{\"\ + id\":\"creator\",\"name\":\"Creator\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"creator\"],\"schema\"\ + :{\"type\":\"user\",\"system\":\"creator\"}},{\"id\":\"subtasks\",\"name\"\ + :\"Sub-Tasks\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"\ + searchable\":false,\"clauseNames\":[\"subtasks\"],\"schema\":{\"type\":\"\ + array\",\"items\":\"issuelinks\",\"system\":\"subtasks\"}},{\"id\":\"reporter\"\ + ,\"name\":\"Reporter\",\"custom\":false,\"orderable\":true,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"reporter\"],\"schema\":{\"type\":\"user\"\ + ,\"system\":\"reporter\"}},{\"id\":\"aggregateprogress\",\"name\":\"\u03A3\ + \ + Progress\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :false,\"clauseNames\":[],\"schema\":{\"type\":\"progress\",\"system\":\"\ + aggregateprogress\"}},{\"id\":\"customfield_10000\",\"name\":\"Development\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10000]\",\"Development\"],\"schema\":{\"type\":\"any\"\ + ,\"custom\":\"com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary\"\ + ,\"customId\":10000}},{\"id\":\"customfield_10200\",\"name\":\"Approvals\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"Approvals\",\"cf[10200]\"],\"schema\":{\"type\":\"sd-approvals\"\ + ,\"custom\":\"com.atlassian.servicedesk.approvals-plugin:sd-approvals\",\"\ + customId\":10200}},{\"id\":\"customfield_10201\",\"name\":\"Request + participants\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10201]\",\"Request participants\"],\"schema\":{\"type\"\ + :\"array\",\"items\":\"user\",\"custom\":\"com.atlassian.servicedesk:sd-request-participants\"\ + ,\"customId\":10201}},{\"id\":\"customfield_10202\",\"name\":\"Customer + Request\ + \ + Type\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"cf[10202]\",\"Customer Request Type\"],\"schema\"\ + :{\"type\":\"sd-customerrequesttype\",\"custom\":\"com.atlassian.servicedesk:vp-origin\"\ + ,\"customId\":10202}},{\"id\":\"environment\",\"name\":\"Environment\",\"\ + custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"environment\"],\"schema\":{\"type\":\"string\",\"system\"\ + :\"environment\"}},{\"id\":\"duedate\",\"name\":\"Due + Date\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + due\",\"duedate\"],\"schema\":{\"type\":\"date\",\"system\":\"duedate\"}},{\"\ + id\":\"progress\",\"name\":\"Progress\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[\"progress\"],\"schema\"\ + :{\"type\":\"progress\",\"system\":\"progress\"}},{\"id\":\"comment\",\"name\"\ + :\"Comment\",\"custom\":false,\"orderable\":true,\"navigable\":false,\"searchable\"\ + :true,\"clauseNames\":[\"comment\"],\"schema\":{\"type\":\"comments-page\"\ + ,\"system\":\"comment\"}},{\"id\":\"votes\",\"name\":\"Votes\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"clauseNames\"\ + :[\"votes\"],\"schema\":{\"type\":\"votes\",\"system\":\"votes\"}},{\"id\"\ + :\"worklog\",\"name\":\"Log Work\",\"custom\":false,\"orderable\":true,\"\ + navigable\":false,\"searchable\":true,\"clauseNames\":[],\"schema\":{\"type\"\ + :\"array\",\"items\":\"worklog\",\"system\":\"worklog\"}}]"} + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:25:35 GMT"] + Set-Cookie: [JSESSIONID=695F7FF23DB85CFCEC23F2A0D87D7D6B; Path=/; HttpOnly] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [445x2279x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [1fb1pfe] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["12093"] + status: {code: 200, message: ""} + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + Cookie: + - !!binary | + YXRsYXNzaWFuLnhzcmYudG9rZW49QllHMy02U1BGLTBVTTEtMkxCT19kOTYyYTQ3Y2NmNDJjYjhm + YWUzN2MyMTY1ZTk0Mzg2NGZkZDdhM2Y0X2xpbjsgSlNFU1NJT05JRD02OTVGN0ZGMjNEQjg1Q0ZD + RUMyM0YyQTBEODdEN0Q2Qg== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + x-experimentalapi: + - !!binary | + b3B0LWlu + method: GET + uri: http://jira:8080/rest/servicedeskapi/organization?start=0&limit=50 + response: + body: + { + string: '{"size":50,"start":0,"limit":50,"isLastPage":false,"_links":{"base":"http://jira:8080","context":"","next":"http://jira:8080/rest/servicedeskapi/organization?limit=50&start=50","self":"http://jira:8080/rest/servicedeskapi/organization?start=0&limit=50"},"values":[{"id":"1","name":"org1","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/1"}},{"id":"2","name":"org2","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/2"}},{"id":"3","name":"org3","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/3"}},{"id":"4","name":"org30","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/4"}},{"id":"5","name":"org32","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/5"}},{"id":"6","name":"org31","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/6"}},{"id":"7","name":"org34","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/7"}},{"id":"8","name":"org33","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/8"}},{"id":"9","name":"org36","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/9"}},{"id":"10","name":"org35","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/10"}},{"id":"11","name":"org38","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/11"}},{"id":"12","name":"org37","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/12"}},{"id":"13","name":"org39","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/13"}},{"id":"14","name":"org50","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/14"}},{"id":"15","name":"org41","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/15"}},{"id":"16","name":"org40","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/16"}},{"id":"17","name":"org43","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/17"}},{"id":"18","name":"org42","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/18"}},{"id":"19","name":"org45","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/19"}},{"id":"20","name":"org44","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/20"}},{"id":"21","name":"org47","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/21"}},{"id":"22","name":"org46","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/22"}},{"id":"23","name":"org49","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/23"}},{"id":"24","name":"org48","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/24"}},{"id":"25","name":"org60","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/25"}},{"id":"26","name":"org52","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/26"}},{"id":"27","name":"org51","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/27"}},{"id":"28","name":"org54","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/28"}},{"id":"29","name":"org10","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/29"}},{"id":"30","name":"org53","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/30"}},{"id":"31","name":"org56","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/31"}},{"id":"32","name":"org12","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/32"}},{"id":"33","name":"org55","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/33"}},{"id":"34","name":"org11","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/34"}},{"id":"35","name":"org58","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/35"}},{"id":"36","name":"org14","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/36"}},{"id":"37","name":"org57","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/37"}},{"id":"38","name":"org13","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/38"}},{"id":"39","name":"org16","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/39"}},{"id":"40","name":"org59","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/40"}},{"id":"41","name":"org15","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/41"}},{"id":"42","name":"org18","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/42"}},{"id":"43","name":"org17","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/43"}},{"id":"44","name":"org19","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/44"}},{"id":"45","name":"org8","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/45"}},{"id":"46","name":"org9","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/46"}},{"id":"47","name":"org4","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/47"}},{"id":"48","name":"org5","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/48"}},{"id":"49","name":"org6","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/49"}},{"id":"50","name":"org7","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/50"}}]}', + } + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:25:35 GMT"] + Set-Cookie: [JSESSIONID=05198C071AE09FF29405F7911341C627; Path=/; HttpOnly] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [445x2280x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [1xlna5j] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["5238"] + status: {code: 200, message: ""} + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + Cookie: + - !!binary | + YXRsYXNzaWFuLnhzcmYudG9rZW49QllHMy02U1BGLTBVTTEtMkxCT19kOTYyYTQ3Y2NmNDJjYjhm + YWUzN2MyMTY1ZTk0Mzg2NGZkZDdhM2Y0X2xpbjsgSlNFU1NJT05JRD0wNTE5OEMwNzFBRTA5RkYy + OTQwNUY3OTExMzQxQzYyNw== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + x-experimentalapi: + - !!binary | + b3B0LWlu + method: GET + uri: http://jira:8080/rest/servicedeskapi/organization?start=50&limit=100 + response: + body: + { + string: '{"size":10,"start":50,"limit":50,"isLastPage":true,"_links":{"base":"http://jira:8080","context":"","prev":"http://jira:8080/rest/servicedeskapi/organization?limit=50&start=0","self":"http://jira:8080/rest/servicedeskapi/organization?start=50&limit=100"},"values":[{"id":"51","name":"org21","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/51"}},{"id":"52","name":"org20","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/52"}},{"id":"53","name":"org23","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/53"}},{"id":"54","name":"org22","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/54"}},{"id":"55","name":"org25","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/55"}},{"id":"56","name":"org24","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/56"}},{"id":"57","name":"org27","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/57"}},{"id":"58","name":"org26","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/58"}},{"id":"59","name":"org29","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/59"}},{"id":"60","name":"org28","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/60"}}]}', + } + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:25:35 GMT"] + Set-Cookie: [JSESSIONID=895A29A492A56350C6C51AD7ABEEDE24; Path=/; HttpOnly] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [445x2281x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [1g3mv90] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["1266"] + status: {code: 200, message: ""} +version: 1 diff --git a/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_from_api_call.yaml b/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_from_api_call.yaml new file mode 100644 index 00000000..771381a3 --- /dev/null +++ b/connector_jira_servicedesk/tests/fixtures/cassettes/test_import_organization_from_api_call.yaml @@ -0,0 +1,372 @@ +interactions: + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + method: GET + uri: http://jira:8080/rest/api/2/serverInfo + response: + body: + { + string: '{"baseUrl":"http://localhost:8080","version":"7.12.3","versionNumbers":[7,12,3],"deploymentType":"Server","buildNumber":712004,"buildDate":"2018-10-12T00:00:00.000+0000","serverTime":"2019-04-09T07:34:59.719+0000","scmInfo":"5ef91d760d7124da5ebec5c16a948a4a807698df","serverTitle":"Jira"}', + } + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:34:59 GMT"] + Set-Cookie: + [ + JSESSIONID=F3754ECC01BFDC09E50B050AFCA448AD; Path=/; HttpOnly, + atlassian.xsrf.token=BYG3-6SPF-0UM1-2LBO_080f5b3302aaf03201d504475fbec12569357bac_lin; + Path=/, + ] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [454x2282x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [88wv88] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["288"] + status: {code: 200, message: ""} + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + Cookie: + - !!binary | + YXRsYXNzaWFuLnhzcmYudG9rZW49QllHMy02U1BGLTBVTTEtMkxCT18wODBmNWIzMzAyYWFmMDMy + MDFkNTA0NDc1ZmJlYzEyNTY5MzU3YmFjX2xpbjsgSlNFU1NJT05JRD1GMzc1NEVDQzAxQkZEQzA5 + RTUwQjA1MEFGQ0E0NDhBRA== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + method: GET + uri: http://jira:8080/rest/api/2/field + response: + body: {string: "[{\"id\":\"issuetype\",\"name\":\"Issue + Type\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + issuetype\",\"type\"],\"schema\":{\"type\":\"issuetype\",\"system\":\"issuetype\"\ + }},{\"id\":\"timespent\",\"name\":\"Time + Spent\",\"custom\":false,\"orderable\"\ + :false,\"navigable\":true,\"searchable\":false,\"clauseNames\":[\"timespent\"\ + ],\"schema\":{\"type\":\"number\",\"system\":\"timespent\"}},{\"id\":\"project\"\ + ,\"name\":\"Project\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"project\"],\"schema\":{\"type\":\"project\"\ + ,\"system\":\"project\"}},{\"id\":\"fixVersions\",\"name\":\"Fix + Version/s\"\ + ,\"custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"fixVersion\"],\"schema\":{\"type\":\"array\",\"items\":\"\ + version\",\"system\":\"fixVersions\"}},{\"id\":\"aggregatetimespent\",\"name\"\ + :\"\u03A3 Time Spent\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\":\"number\"\ + ,\"system\":\"aggregatetimespent\"}},{\"id\":\"resolution\",\"name\":\"Resolution\"\ + ,\"custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"resolution\"],\"schema\":{\"type\":\"resolution\",\"system\"\ + :\"resolution\"}},{\"id\":\"customfield_10104\",\"name\":\"Epic Color\",\"\ + custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10104]\",\"Epic + Color\"],\"schema\":{\"type\":\"string\"\ + ,\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-color\",\"customId\":10104}},{\"\ + id\":\"customfield_10105\",\"name\":\"Rank\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10105]\"\ + ,\"Rank\"],\"schema\":{\"type\":\"any\",\"custom\":\"com.pyxis.greenhopper.jira:gh-lexo-rank\"\ + ,\"customId\":10105}},{\"id\":\"customfield_10106\",\"name\":\"Story + Points\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10106]\",\"Story + Points\"],\"schema\":{\"type\":\"number\"\ + ,\"custom\":\"com.atlassian.jira.plugin.system.customfieldtypes:float\",\"\ + customId\":10106}},{\"id\":\"resolutiondate\",\"name\":\"Resolved\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"resolutiondate\",\"resolved\"],\"schema\":{\"type\":\"datetime\",\"system\"\ + :\"resolutiondate\"}},{\"id\":\"workratio\",\"name\":\"Work + Ratio\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"workratio\"],\"schema\":{\"type\":\"number\",\"system\":\"workratio\"\ + }},{\"id\":\"lastViewed\",\"name\":\"Last + Viewed\",\"custom\":false,\"orderable\"\ + :false,\"navigable\":true,\"searchable\":false,\"clauseNames\":[\"lastViewed\"\ + ],\"schema\":{\"type\":\"datetime\",\"system\":\"lastViewed\"}},{\"id\":\"\ + watches\",\"name\":\"Watchers\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[\"watchers\"],\"schema\":{\"type\"\ + :\"watches\",\"system\":\"watches\"}},{\"id\":\"thumbnail\",\"name\":\"Images\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"\ + clauseNames\":[]},{\"id\":\"created\",\"name\":\"Created\",\"custom\":false,\"\ + orderable\":false,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + created\",\"createdDate\"],\"schema\":{\"type\":\"datetime\",\"system\":\"\ + created\"}},{\"id\":\"priority\",\"name\":\"Priority\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + priority\"],\"schema\":{\"type\":\"priority\",\"system\":\"priority\"}},{\"\ + id\":\"customfield_10100\",\"name\":\"Sprint\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10100]\"\ + ,\"Sprint\"],\"schema\":{\"type\":\"array\",\"items\":\"string\",\"custom\"\ + :\"com.pyxis.greenhopper.jira:gh-sprint\",\"customId\":10100}},{\"id\":\"\ + customfield_10101\",\"name\":\"Epic + Link\",\"custom\":true,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10101]\",\"Epic\ + \ + Link\"],\"schema\":{\"type\":\"any\",\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-link\"\ + ,\"customId\":10101}},{\"id\":\"customfield_10102\",\"name\":\"Epic + Status\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10102]\",\"Epic + Status\"],\"schema\":{\"type\":\"option\"\ + ,\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-status\",\"customId\":10102}},{\"\ + id\":\"labels\",\"name\":\"Labels\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"labels\"],\"schema\"\ + :{\"type\":\"array\",\"items\":\"string\",\"system\":\"labels\"}},{\"id\"\ + :\"customfield_10103\",\"name\":\"Epic Name\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"cf[10103]\"\ + ,\"Epic + Name\"],\"schema\":{\"type\":\"string\",\"custom\":\"com.pyxis.greenhopper.jira:gh-epic-label\"\ + ,\"customId\":10103}},{\"id\":\"timeestimate\",\"name\":\"Remaining + Estimate\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"\ + clauseNames\":[\"remainingEstimate\",\"timeestimate\"],\"schema\":{\"type\"\ + :\"number\",\"system\":\"timeestimate\"}},{\"id\":\"aggregatetimeoriginalestimate\"\ + ,\"name\":\"\u03A3 Original + Estimate\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\"\ + :\"number\",\"system\":\"aggregatetimeoriginalestimate\"}},{\"id\":\"versions\"\ + ,\"name\":\"Affects + Version/s\",\"custom\":false,\"orderable\":true,\"navigable\"\ + :true,\"searchable\":true,\"clauseNames\":[\"affectedVersion\"],\"schema\"\ + :{\"type\":\"array\",\"items\":\"version\",\"system\":\"versions\"}},{\"id\"\ + :\"issuelinks\",\"name\":\"Linked Issues\",\"custom\":false,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[],\"schema\"\ + :{\"type\":\"array\",\"items\":\"issuelinks\",\"system\":\"issuelinks\"}},{\"\ + id\":\"assignee\",\"name\":\"Assignee\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"assignee\"],\"schema\"\ + :{\"type\":\"user\",\"system\":\"assignee\"}},{\"id\":\"updated\",\"name\"\ + :\"Updated\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"updated\",\"updatedDate\"],\"schema\":{\"type\":\"\ + datetime\",\"system\":\"updated\"}},{\"id\":\"status\",\"name\":\"Status\"\ + ,\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"status\"],\"schema\":{\"type\":\"status\",\"system\":\"status\"\ + }},{\"id\":\"components\",\"name\":\"Component/s\",\"custom\":false,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"component\"\ + ],\"schema\":{\"type\":\"array\",\"items\":\"component\",\"system\":\"components\"\ + }},{\"id\":\"issuekey\",\"name\":\"Key\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[\"id\",\"issue\",\"\ + issuekey\",\"key\"]},{\"id\":\"timeoriginalestimate\",\"name\":\"Original\ + \ + Estimate\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :false,\"clauseNames\":[\"originalEstimate\",\"timeoriginalestimate\"],\"\ + schema\":{\"type\":\"number\",\"system\":\"timeoriginalestimate\"}},{\"id\"\ + :\"description\",\"name\":\"Description\",\"custom\":false,\"orderable\":true,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"description\"],\"\ + schema\":{\"type\":\"string\",\"system\":\"description\"}},{\"id\":\"timetracking\"\ + ,\"name\":\"Time + Tracking\",\"custom\":false,\"orderable\":true,\"navigable\"\ + :false,\"searchable\":true,\"clauseNames\":[],\"schema\":{\"type\":\"timetracking\"\ + ,\"system\":\"timetracking\"}},{\"id\":\"customfield_10203\",\"name\":\"Organizations\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10203]\",\"Organizations\"],\"schema\":{\"type\":\"array\"\ + ,\"items\":\"sd-customerorganization\",\"custom\":\"com.atlassian.servicedesk:sd-customer-organizations\"\ + ,\"customId\":10203}},{\"id\":\"customfield_10204\",\"name\":\"Satisfaction\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10204]\",\"Satisfaction\"],\"schema\":{\"type\":\"any\"\ + ,\"custom\":\"com.atlassian.servicedesk:sd-request-feedback\",\"customId\"\ + :10204}},{\"id\":\"security\",\"name\":\"Security + Level\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + level\"],\"schema\":{\"type\":\"securitylevel\",\"system\":\"security\"}},{\"\ + id\":\"customfield_10205\",\"name\":\"Satisfaction + date\",\"custom\":true,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + cf[10205]\",\"Satisfaction + date\"],\"schema\":{\"type\":\"datetime\",\"custom\"\ + :\"com.atlassian.servicedesk:sd-request-feedback-date\",\"customId\":10205}},{\"\ + id\":\"customfield_10206\",\"name\":\"Approvers\",\"custom\":true,\"orderable\"\ + :true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"Approvers\"\ + ,\"cf[10206]\"],\"schema\":{\"type\":\"array\",\"items\":\"user\",\"custom\"\ + :\"com.atlassian.jira.plugin.system.customfieldtypes:multiuserpicker\",\"\ + customId\":10206}},{\"id\":\"attachment\",\"name\":\"Attachment\",\"custom\"\ + :false,\"orderable\":true,\"navigable\":false,\"searchable\":true,\"clauseNames\"\ + :[\"attachments\"],\"schema\":{\"type\":\"array\",\"items\":\"attachment\"\ + ,\"system\":\"attachment\"}},{\"id\":\"aggregatetimeestimate\",\"name\":\"\ + \u03A3 Remaining + Estimate\",\"custom\":false,\"orderable\":false,\"navigable\"\ + :true,\"searchable\":false,\"clauseNames\":[],\"schema\":{\"type\":\"number\"\ + ,\"system\":\"aggregatetimeestimate\"}},{\"id\":\"customfield_10207\",\"name\"\ + :\"Time to + resolution\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"cf[10207]\",\"Time to resolution\"],\"\ + schema\":{\"type\":\"sd-servicelevelagreement\",\"custom\":\"com.atlassian.servicedesk:sd-sla-field\"\ + ,\"customId\":10207}},{\"id\":\"customfield_10208\",\"name\":\"Time to + first\ + \ + response\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"cf[10208]\",\"Time to first response\"],\"schema\"\ + :{\"type\":\"sd-servicelevelagreement\",\"custom\":\"com.atlassian.servicedesk:sd-sla-field\"\ + ,\"customId\":10208}},{\"id\":\"summary\",\"name\":\"Summary\",\"custom\"\ + :false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\"\ + :[\"summary\"],\"schema\":{\"type\":\"string\",\"system\":\"summary\"}},{\"\ + id\":\"creator\",\"name\":\"Creator\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":true,\"clauseNames\":[\"creator\"],\"schema\"\ + :{\"type\":\"user\",\"system\":\"creator\"}},{\"id\":\"subtasks\",\"name\"\ + :\"Sub-Tasks\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"\ + searchable\":false,\"clauseNames\":[\"subtasks\"],\"schema\":{\"type\":\"\ + array\",\"items\":\"issuelinks\",\"system\":\"subtasks\"}},{\"id\":\"reporter\"\ + ,\"name\":\"Reporter\",\"custom\":false,\"orderable\":true,\"navigable\":true,\"\ + searchable\":true,\"clauseNames\":[\"reporter\"],\"schema\":{\"type\":\"user\"\ + ,\"system\":\"reporter\"}},{\"id\":\"aggregateprogress\",\"name\":\"\u03A3\ + \ + Progress\",\"custom\":false,\"orderable\":false,\"navigable\":true,\"searchable\"\ + :false,\"clauseNames\":[],\"schema\":{\"type\":\"progress\",\"system\":\"\ + aggregateprogress\"}},{\"id\":\"customfield_10000\",\"name\":\"Development\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10000]\",\"Development\"],\"schema\":{\"type\":\"any\"\ + ,\"custom\":\"com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary\"\ + ,\"customId\":10000}},{\"id\":\"customfield_10200\",\"name\":\"Approvals\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"Approvals\",\"cf[10200]\"],\"schema\":{\"type\":\"sd-approvals\"\ + ,\"custom\":\"com.atlassian.servicedesk.approvals-plugin:sd-approvals\",\"\ + customId\":10200}},{\"id\":\"customfield_10201\",\"name\":\"Request + participants\"\ + ,\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"cf[10201]\",\"Request participants\"],\"schema\":{\"type\"\ + :\"array\",\"items\":\"user\",\"custom\":\"com.atlassian.servicedesk:sd-request-participants\"\ + ,\"customId\":10201}},{\"id\":\"customfield_10202\",\"name\":\"Customer + Request\ + \ + Type\",\"custom\":true,\"orderable\":true,\"navigable\":true,\"searchable\"\ + :true,\"clauseNames\":[\"cf[10202]\",\"Customer Request Type\"],\"schema\"\ + :{\"type\":\"sd-customerrequesttype\",\"custom\":\"com.atlassian.servicedesk:vp-origin\"\ + ,\"customId\":10202}},{\"id\":\"environment\",\"name\":\"Environment\",\"\ + custom\":false,\"orderable\":true,\"navigable\":true,\"searchable\":true,\"\ + clauseNames\":[\"environment\"],\"schema\":{\"type\":\"string\",\"system\"\ + :\"environment\"}},{\"id\":\"duedate\",\"name\":\"Due + Date\",\"custom\":false,\"\ + orderable\":true,\"navigable\":true,\"searchable\":true,\"clauseNames\":[\"\ + due\",\"duedate\"],\"schema\":{\"type\":\"date\",\"system\":\"duedate\"}},{\"\ + id\":\"progress\",\"name\":\"Progress\",\"custom\":false,\"orderable\":false,\"\ + navigable\":true,\"searchable\":false,\"clauseNames\":[\"progress\"],\"schema\"\ + :{\"type\":\"progress\",\"system\":\"progress\"}},{\"id\":\"comment\",\"name\"\ + :\"Comment\",\"custom\":false,\"orderable\":true,\"navigable\":false,\"searchable\"\ + :true,\"clauseNames\":[\"comment\"],\"schema\":{\"type\":\"comments-page\"\ + ,\"system\":\"comment\"}},{\"id\":\"votes\",\"name\":\"Votes\",\"custom\"\ + :false,\"orderable\":false,\"navigable\":true,\"searchable\":false,\"clauseNames\"\ + :[\"votes\"],\"schema\":{\"type\":\"votes\",\"system\":\"votes\"}},{\"id\"\ + :\"worklog\",\"name\":\"Log Work\",\"custom\":false,\"orderable\":true,\"\ + navigable\":false,\"searchable\":true,\"clauseNames\":[],\"schema\":{\"type\"\ + :\"array\",\"items\":\"worklog\",\"system\":\"worklog\"}}]"} + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:34:59 GMT"] + Set-Cookie: [JSESSIONID=02595F6221A3A7FC73A9B1C5FA665EFB; Path=/; HttpOnly] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [454x2283x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [1p1fqss] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["12093"] + status: {code: 200, message: ""} + - request: + body: null + headers: + Accept: + - !!binary | + YXBwbGljYXRpb24vanNvbiwqLio7cT0wLjk= + Accept-Encoding: + - !!binary | + Z3ppcCwgZGVmbGF0ZQ== + Cache-Control: + - !!binary | + bm8tY2FjaGU= + Connection: + - !!binary | + a2VlcC1hbGl2ZQ== + Content-Type: + - !!binary | + YXBwbGljYXRpb24vanNvbg== + Cookie: + - !!binary | + YXRsYXNzaWFuLnhzcmYudG9rZW49QllHMy02U1BGLTBVTTEtMkxCT18wODBmNWIzMzAyYWFmMDMy + MDFkNTA0NDc1ZmJlYzEyNTY5MzU3YmFjX2xpbjsgSlNFU1NJT05JRD0wMjU5NUY2MjIxQTNBN0ZD + NzNBOUIxQzVGQTY2NUVGQg== + User-Agent: + - !!binary | + cHl0aG9uLXJlcXVlc3RzLzIuMjEuMA== + X-Atlassian-Token: + - !!binary | + bm8tY2hlY2s= + x-experimentalapi: + - !!binary | + b3B0LWlu + method: GET + uri: http://jira:8080/rest/servicedeskapi/organization/55 + response: + body: + { + string: '{"id":"55","name":"org25","_links":{"self":"http://jira:8080/rest/servicedeskapi/organization/55"}}', + } + headers: + Cache-Control: ["no-cache, no-store, no-transform"] + Content-Security-Policy: [frame-ancestors 'self'] + Content-Type: [application/json;charset=UTF-8] + Date: ["Tue, 09 Apr 2019 07:34:59 GMT"] + Set-Cookie: [JSESSIONID=D7428E3CFDC83DBBD4214E6A9EECF1F9; Path=/; HttpOnly] + Transfer-Encoding: [chunked] + Vary: [User-Agent] + X-AREQUESTID: [454x2284x1] + X-ASEN: [SEN-L13384799] + X-ASESSIONID: [n37ugs] + X-AUSERNAME: [gbaconnier] + X-Content-Type-Options: [nosniff] + X-Frame-Options: [SAMEORIGIN] + X-Seraph-LoginReason: [OK] + X-XSS-Protection: [1; mode=block] + content-length: ["99"] + status: {code: 200, message: ""} +version: 1 diff --git a/connector_jira_servicedesk/tests/test_import_organization.py b/connector_jira_servicedesk/tests/test_import_organization.py new file mode 100644 index 00000000..a5470fc2 --- /dev/null +++ b/connector_jira_servicedesk/tests/test_import_organization.py @@ -0,0 +1,56 @@ +# Copyright 2019-2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.connector_jira.tests.common import JiraSavepointCase + +from .common import recorder + + +class TestImportOrganization(JiraSavepointCase): + @recorder.use_cassette + def test_import_organization_batch(self): + """Batch import of organizations + + This is a direct import of all organizations, without using + individual jobs. + """ + organizations = self.env["jira.organization"].search([]) + self.assertEqual(len(organizations), 0) + self.env["jira.organization"].import_batch(self.backend_record,) + organizations = self.env["jira.organization"].search([]) + # ensure that we have more than 50 records which + # is the pagination of the REST API + self.assertEqual(len(organizations), 60) + + def test_import_organization_from_record(self): + """Import one organization from a records + + The batch import directly pass the record because it gets + all the data at once from the API. + """ + binding = self.env["jira.organization"].create( + { + "backend_id": self.backend_record.id, + "external_id": "55", + "name": "dummy", + } + ) + binding.import_record( + self.backend_record, "55", record={"id": "55", "name": "new name"}, + ) + self.assertEqual(binding.name, "new name") + + @recorder.use_cassette + def test_import_organization_from_api_call(self): + """Import one organization from a call to the API""" + binding = self.env["jira.organization"].create( + { + "backend_id": self.backend_record.id, + "external_id": "55", + "name": "dummy", + } + ) + binding.import_record( + self.backend_record, "55", + ) + self.assertEqual(binding.name, "org25") diff --git a/connector_jira_servicedesk/views/jira_backend_views.xml b/connector_jira_servicedesk/views/jira_backend_views.xml new file mode 100644 index 00000000..97158224 --- /dev/null +++ b/connector_jira_servicedesk/views/jira_backend_views.xml @@ -0,0 +1,62 @@ + + + + + jira.backend.form + jira.backend + + + + +
+
+