public async getWorkItemProjectIds()

in src/PortfolioPlanning/Common/Services/PortfolioPlanningDataService.ts [144:245]


    public async getWorkItemProjectIds(
        workItemIds: number[],
        telemetryService?: PortfolioTelemetry
    ): Promise<WorkItemProjectIdsQueryResult> {
        if (!telemetryService) {
            telemetryService = PortfolioTelemetry.getInstance();
        }

        if (!workItemIds || workItemIds.length === 0) {
            return Promise.resolve({
                exceptionMessage: null,
                Results: null,
                QueryInput: workItemIds
            });
        }

        //  Can't use OData service to get work item information just based on Ids.
        //  OData requires a project id or name filter to check security, and we don't have it.
        //  Using WIQL query service to get project name and work item type for each work item id,
        //  then using OData service to get project ids based on project names.
        //  Unfortunately, WIQL doesn't support System.ProjectId :-(.
        const workItemIdsMap: { [workitemId: number]: number } = {};
        workItemIds.forEach(id => {
            workItemIdsMap[id.toString()] = true;
        });
        const workItemIdsSet = Object.keys(workItemIdsMap).map(idStr => Number(idStr));
        const workItemInfo = await PageWorkItemHelper.pageWorkItems(workItemIdsSet, null /** projectName */, [
            "System.Id",
            "System.WorkItemType",
            "System.TeamProject"
        ]);

        const projectIdsByName: { [projectNameKey: string]: string } = {};
        workItemInfo.forEach(wi => {
            const projectNameKey = (wi.fields["System.TeamProject"] as string).toLowerCase();
            //  will add project id later.
            projectIdsByName[projectNameKey] = null;
        });
        const projectNamesSet = Object.keys(projectIdsByName).map(name => name);
        const projectIdQueryResult: ProjectIdsQueryResult = await PortfolioPlanningDataService.getInstance().getProjectIds(
            projectNamesSet
        );

        if (projectIdQueryResult.exceptionMessage && projectIdQueryResult.exceptionMessage.length > 0) {
            throw new Error(
                `runDependencyQuery: Exception running project ids query. Inner exception: ${
                    projectIdQueryResult.exceptionMessage
                }`
            );
        }

        if (!projectIdQueryResult.Results || projectIdQueryResult.Results.length === 0) {
            const exceptionMessage = `Could not retrieve project ids for linked work items: ${workItemIdsSet.join(
                ", "
            )}. Project names found: ${projectNamesSet.join(", ")}`;
            telemetryService.TrackException(new Error(exceptionMessage));

            return {
                exceptionMessage,
                Results: [],
                QueryInput: workItemIdsSet
            };
        }

        projectIdQueryResult.Results.forEach(res => {
            const projectNameKey = res.ProjectName.toLowerCase();

            if (!projectIdsByName[projectNameKey]) {
                projectIdsByName[projectNameKey] = res.ProjectSK;
            }
        });

        const Results: WorkItemProjectId[] = [];

        workItemInfo.forEach(wi => {
            const projectNameKey = (wi.fields["System.TeamProject"] as string).toLowerCase();

            if (!projectIdsByName[projectNameKey]) {
                //  Couldn't find the project id for this linked work item, so ignoring it.
                const telemetryData = {
                    ["ProjectName"]: projectNameKey,
                    ["WorkItemId"]: wi.id
                };
                telemetryService.TrackAction(
                    "PortfolioPlanningDataService/GetWorkItemProjectIds/MissingProjectId",
                    telemetryData
                );
            } else {
                Results.push({
                    WorkItemId: wi.fields["System.Id"],
                    WorkItemType: wi.fields["System.WorkItemType"],
                    ProjectSK: projectIdsByName[projectNameKey]
                });
            }
        });

        return {
            exceptionMessage: null,
            Results,
            QueryInput: workItemIdsSet
        };
    }