pylero.plan — pylero documentation

# Source code for pylero.plan

    # -*- coding: utf8 -*-
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    from __future__ import unicode_literals

    import suds
    from pylero._compatible import basestring
    from pylero.base_polarion import BasePolarion
    from pylero.custom import ArrayOfCustom
    from pylero.custom import Custom
    from pylero.enum_option_id import ArrayOfEnumOptionId
    from pylero.enum_option_id import EnumOptionId
    from pylero.exceptions import PyleroLibException
    from pylero.plan_record import ArrayOfPlanRecord
    from pylero.plan_record import PlanRecord
    from pylero.plan_statistics import PlanStatistics
    from pylero.project import Project
    from pylero.subterra_uri import SubterraURI
    from pylero.text import Text
    from pylero.user import User
    from pylero.work_item import _WorkItem

    class Plan(BasePolarion):
        """Object to handle the Polarion WSDL tns6:Plan class

        Attributes:
            allowed_types (ArrayOfEnumOptionId)
            author_uri (SubterraURI)
            calculation_type (EnumOptionId)
            capacity (float)
            color (string)
            created (dateTime)
            custom_fields (ArrayOfCustom)
            default_estimate (float)
            description (Text)
            due_date (date)
            estimation_field (string)
            finished_on (dateTime)
            is_template (boolean)
            location (Location)
            name (string)
            parent (Plan)
            plan_id (string)
            previous_time_spent (duration)
            prioritization_field (string)
            project_uri (SubterraURI)
            records (ArrayOfPlanRecord)
            sort_order (int)
            start_date (date)
            started_on (dateTime)
            status (EnumOptionId)
            template_uri (SubterraURI)
            updated (dateTime)"""

        _cls_suds_map = {
            "allowed_types": {
                "field_name": "allowedTypes",
                "is_array": True,
                "cls": EnumOptionId,
                "arr_cls": ArrayOfEnumOptionId,
                "inner_field_name": "EnumOptionId",
                "enum_id": "workitem-type",
            },
            "author": {
                "field_name": "authorURI",
                "cls": User,
                "named_arg": "uri",
                "sync_field": "uri",
            },
            "calculation_type": {"field_name": "calculationType", "cls": EnumOptionId},
            "capacity": "capacity",
            "color": "color",
            "created": "created",
            "custom_fields": {
                "field_name": "customFields",
                "is_array": True,
                "cls": Custom,
                "arr_cls": ArrayOfCustom,
                "inner_field_name": "Custom",
            },
            "default_estimate": "defaultEstimate",
            "description": {"field_name": "description", "cls": Text},
            "due_date": "dueDate",
            "estimation_field": "estimationField",
            "finished_on": "finishedOn",
            "is_template": "isTemplate",
            "location": "location",
            "name": "name",
            # the parent field exists when creating an object Plan(), however the
            # field is not returned in a get or search operation. Because of this,
            # the attribute should not be accessible. the _fix_circular_refs is
            # also commented out for the same reason. If this attribute become
            # relevant in the future, that funciton should be activated.
            # "parent":
            #    {"field_name": "parent"},  # populated in circ refs
            "plan_id": "id",
            "previous_time_spent": "previousTimeSpent",
            "prioritization_field": "prioritizationField",
            "project_id": {
                "field_name": "projectURI",
                "cls": Project,
                "named_arg": "uri",
                "sync_field": "uri",
            },
            "records": {
                "field_name": "records",
                "is_array": True,
                "cls": PlanRecord,
                "arr_cls": ArrayOfPlanRecord,
                "inner_field_name": "PlanRecord",
            },
            "sort_order": "sortOrder",
            "start_date": "startDate",
            "started_on": "startedOn",
            "status": {"field_name": "status", "cls": EnumOptionId},
            "template_uri": {"field_name": "templateURI", "cls": SubterraURI},
            "updated": "updated",
            "uri": "_uri",
            "_unresolved": "_unresolved",
        }
        _obj_client = "planning_client"
        _obj_struct = "tns4:Plan"
        _id_field = "plan_id"

        @classmethod
        def create(cls, plan_id, plan_name, project_id, parent_id, template_id):
            """Creates a new plan

            Args:
                plan_id (str): The id of the new plan
                plan_name: The name of the new plan
                project_id (str): The project the plan will be created in
                parent_id: The id of the parent plan (can be null)
                template_id: The id of the template used for this plan

            Returns:
                Plan Object

            References:
                Planning.createPlan
            """
            uri = cls.session.planning_client.service.createPlan(
                project_id, plan_name, plan_id, parent_id, template_id
            )
            return Plan(uri=uri)

        @classmethod
        def create_plan_template(cls, template_id, template_name, project_id, parent_id):
            """Creates a new plan template

            Args:
                template_id (str): The id of the new template
                template_name: The name of the new template
                project_id (str): The project the plan will be created in
                parent_id: The id of the template the new template is based on
                            (can be null)

            Returns:
                Plan Object

            References:
                Planning.createPlanTemplate
            """
            uri = cls.session.planning_client.service.createPlanTemplate(
                project_id, template_name, template_id, parent_id
            )
            return Plan(uri=uri)

        @classmethod
        def delete_plans(cls, project_id, plan_ids):
            """Delete specified plans

            Args:
                project_id: the project the plans will be deleted in
                plan_ids: list of plan ids to delete.

            Returns:
                None

            References:
                Planning.deletePlans
            """
            cls.session.planning_client.service.deletePlans(project_id, plan_ids)

        @classmethod
        def search(cls, query, sort="plan_id", limit=-1, fields=[], search_templates=False):
            """search plans or plan templates

            Args
                query
                sort
                limit: the maximum number of records to be returned, -1 for no limit.
                fields: list of the fields requested.

            Returns:
                list of Plan objects

            References:
                Planning.searchPlanTemplates
                Planning.searchPlanTemplatesWithFields
                Planning.searchPlans
                Planning.searchPlansWithFields
            """
            # function names and parameter lists generated dynamically based on
            # parameters passed in.
            if search_templates:
                function_name = "searchPlanTemplates"
            else:
                function_name = "searchPlans"
            if fields:
                function_name += "WithFields"
            p_sort = (
                cls._cls_suds_map[sort]
                if not isinstance(cls._cls_suds_map[sort], dict)
                else cls._cls_suds_map[sort]["field_name"]
            )
            parms = [query, p_sort, limit] + (
                [cls._convert_obj_fields_to_polarion(fields)] if fields else []
            )
            plans = []
            for sud_plan in getattr(cls.session.planning_client.service, function_name)(
                *parms
            ):
                plans.append(Plan(suds_object=sud_plan))
            return plans

        def __init__(self, plan_id=None, project_id=None, uri=None, suds_object=None):
            """Plan Constructor

            Args:
                plan_id: ID of the plan
                project_id: ID of the project that contains the specific plan
                            required when plan_id is given
                uri: the SubterraURI of the plan to load
                suds_object: the Polarion Plan object

            Returns:
                None

            References:
                Planning.getPlanById
                Planning.getPlanByUri
            """
            super(self.__class__, self).__init__(obj_id=plan_id, suds_object=suds_object)
            if plan_id:
                if not project_id:
                    raise PyleroLibException(
                        "When plan_id is passed in, " "project_id is required"
                    )
                self._suds_object = self.session.planning_client.service.getPlanById(
                    project_id, plan_id
                )
            elif uri:
                self._suds_object = self.session.planning_client.service.getPlanByUri(uri)
            if plan_id or uri:
                if getattr(self._suds_object, "_unresolvable", True):
                    raise PyleroLibException("The Plan {0} was not found.".format(plan_id))

        # The parent variable is commented out, see above for explanation.
        # in the event that the parent atrtribute becomes relevant, this function will
        # need to be uncommented out as well
        #    def _fix_circular_refs(self):
        #        # The module references itself as a class attribute, which is not
        #        # allowed, so the self reference is defined here.
        #        self._cls_suds_map["parent"]["cls"] = self.__class__

        def add_plan_items(self, work_items):
            """Add plan records to the plan.

            Args:
                items: list of work_item_ids

            Returns:
                None

            References:
                Planning.addPlanItems
            """
            self._verify_obj()
            if work_items:
                if not isinstance(work_items, list):
                    raise PyleroLibException(
                        "work_items must be a list of _WorkItem objects"
                    )
            p_items = []
            for item in work_items:
                wi = _WorkItem(self.project_id, work_item_id=item)
                p_items.append(wi.uri)
            self.session.planning_client.service.addPlanItems(self.uri, p_items)

        def get_statistics(self):
            """get statistics of the plan

            Args:
                None

            Returns:
                PlanStatistics object

            References:
                Planning.getPlanStatistics
            """
            self._verify_obj()
            suds_stat = self.session.planning_client.service.getPlanStatistics(self.uri)
            return PlanStatistics(suds_object=suds_stat)

        def get_wiki_content(self):
            """Returns the wiki content of the plan

            Args:
                None

            Returns:
                Text object

            References:
                Planning.getPlanWikiContent
            """
            self._verify_obj()
            suds_obj = self.session.planning_client.service.getPlanWikiContent(self.uri)
            return Text(suds_object=suds_obj)

        def remove_plan_items(self, work_items):
            """Remove plan records to the plan.

            Args:
                items: list of work_item_ids

            Returns:
                None

            References:
                Planning.removePlanItems
            """
            self._verify_obj()
            if work_items:
                if not isinstance(work_items, list):
                    raise PyleroLibException(
                        "work_items must be a list of _WorkItem objects"
                    )
            p_items = []
            for item in work_items:
                wi = _WorkItem(self.project_id, work_item_id=item)
                p_items.append(wi.uri)
            self.session.planning_client.service.removePlanItems(self.uri, p_items)

        def set_wiki_content(self, content):
            """method set_wiki_content updates the wiki for the current Plan

            Args:
                Content (str or Text object)

            Returns:
                None

            References:
                Planning.setPlanWikiContent
            """
            self._verify_obj()
            if content:
                if isinstance(content, basestring):
                    obj_content = Text(content=content)
                    suds_content = obj_content._suds_object
                elif isinstance(content, Text):
                    suds_content = content._suds_object
                else:  # is a suds object
                    suds_content = content
            else:
                suds_content = suds.null()
            self.session.planning_client.service.setPlanWikiContent(self.uri, suds_content)

        def update(self):
            """updates the server with the current plan content

            Args:
                None

            Returns:
                None

            References:
                Planning.updatePlan
            """
            self._verify_obj()
            self.session.planning_client.service.updatePlan(self._suds_object)

        def was_started(self):
            """checks if the plan was started yet

            Args:
                None

            Returns:
                bool

            References:
                Planning.wasPlanStarted
            """
            self._verify_obj()
            return self.session.planning_client.service.wasPlanStarted(self.uri)

    class ArrayOfPlan(BasePolarion):
        _obj_client = "builder_client"
        _obj_struct = "tns6:ArrayOfPlan"