如何按日期通过WIQL tfs获取任务ID,功能ID,完成小时数? [英] how to get Task id,Feature id,Complete hrs by WIQL tfs by date?

查看:27
本文介绍了如何按日期通过WIQL tfs获取任务ID,功能ID,完成小时数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取任务、功能 ID、按日期完成的小时数.
假设有一个任务 123 在 sprint 中创建,开始日期为 7 月 1 日,结束于 7 月 10 日

how to get Task,Feature id,completed hours by date.
lets say there is a task 123 in which was created on a sprint which start date is 1st July and end at 10th July

1-7-2018 的任务 123 工作小时数为 5 小时数为 0
7 月 5 日的努力是 3 小时完成 2 小时
7 月 10 日的努力是 1 小时,完成是 4 小时

task 123 effort hours is 5 completed hrs is 0 from 1-7-2018
and on 5th July effort is 3 hrs completed 2 hrs
and on 10th July effort is 1 hr and completed is 4 hrs

那么我怎样才能找到从 7 月 1 日到 7 月 5 日的任务 ID、功能 ID(通过 Tree WIQL).

so how can i find task id,Feature id (by Tree WIQL) of date from 1st July to 5th July.

推荐答案

我已经创建了测试解决方案.它基于rest api.它需要nugate包:

I have created test solution. It based on rest api. It requires nugate packages:

安装后你必须更新它们,因为我有错误:继承安全规则被违反输入

And you have to update them after install because I had the error: Inheritance security rules violated by type

测试源代码:

using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Services.Client;

namespace GetFTTaskCompleteForDates
{
    class Program
    {
        public class FTTaskComleted
        {
            public int FTID = 0;
            public int TaskID = 0;
            public int CompletedOnDate = 0;
            public int CompletedFieldValue = 0;
            public DateTime ReportDT;
        }

        static public class WIQLS
        {
            static public string ChangedTasksFromDate = "SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '{0}'  AND  [System.WorkItemType] = 'Task'  AND  [System.ChangedDate] >= '{1}-{2}-{3}T00:00:00.0000000' ORDER BY [System.Id]";
            static public string GetTopParentFeature = "SELECT [System.Id] FROM WorkItemLinks WHERE ([Source].[System.TeamProject] = '{0}'  AND  [Source].[System.WorkItemType] = 'Feature') And ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward') And ([Target].[System.Id] = {1}) ORDER BY [System.Id] mode(Recursive,ReturnMatchingChildren)";
        }

        static string ServiceUrl = "http://tfs-srv:8080/tfs/DefaultCollection";
        static string TeamProject = "VSTSAgile";
        static WorkItemTrackingHttpClient WiClient = null; 
        static VssConnection ServiceConnection = null;
        static string CompletedWorkFieldRef = "Microsoft.VSTS.Scheduling.CompletedWork";
        static string ChangedDateFieldRef = "System.ChangedDate";

        static void Main(string[] args)
        {
            DateTime _startDate = new DateTime(2018, 06, 19);
            DateTime _finishDate = DateTime.Today;  // set to DateTime.MinValue if only one date
            //DateTime _finishDate = DateTime.MinValue;

            List<FTTaskComleted> _lstReport = new List<FTTaskComleted>();

            if (!ConnectToService()) return;

            Dictionary<int, int> _dctTasksFeatures = GetTaskAndFeatures(_startDate);

            if (_dctTasksFeatures.Keys.Count > 0) FillReportList(_dctTasksFeatures, _lstReport, _startDate, _finishDate);

            foreach (FTTaskComleted _item in _lstReport)
                Console.WriteLine("DATE:{0} -- FT:{1} -- TSK:{2} -- HRS -- {3}", _item.ReportDT.ToShortDateString(), _item.FTID, _item.TaskID, _item.CompletedOnDate);
        }

        //Fill list with hours for each date and task
        private static void FillReportList(Dictionary<int, int> pDctTasksFT, List<FTTaskComleted> pLstReport, DateTime pStartDate, DateTime pFinishtDate)
        {

            foreach (int _taskId in pDctTasksFT.Keys)
            {
                List<WorkItem> _revs = WiClient.GetRevisionsAsync(_taskId).Result;

                DateTime _lastDate = DateTime.MinValue; //last processed date for revisions of work item
                int _lastHours = int.MinValue; //last processed value of compteted work for revisions of work item

                foreach (WorkItem _rev in _revs)
                {                    
                    if (!_rev.Fields.Keys.Contains(CompletedWorkFieldRef) || !_rev.Fields.Keys.Contains(ChangedDateFieldRef)) continue;
                    DateTime _changedDate;
                    if (!DateTime.TryParse(_rev.Fields[ChangedDateFieldRef].ToString(), out _changedDate)) continue;

                    bool _inscope = false;

                    // calculate hours based on previous revision
                    int _completedValue, _completedDiff;
                    if (!int.TryParse(_rev.Fields[CompletedWorkFieldRef].ToString(), out _completedValue)) continue;

                    if (_lastHours == int.MinValue) _completedDiff = _completedValue;
                    else _completedDiff = _completedValue - _lastHours;

                    _lastHours = _completedValue;

                    // check for date of revision between needed dates
                    if (pFinishtDate == DateTime.MinValue) { if (_changedDate.Date == pStartDate.Date) _inscope = true; }
                    else if (_changedDate.Date >= pStartDate.Date && _changedDate.Date <= pFinishtDate.Date) _inscope = true;

                    if (_inscope && _completedDiff != 0)
                    {
                        if (_lastDate.Date == _changedDate.Date && pLstReport.Count > 0)
                        {
                            //update existing item if several changes in one day
                            pLstReport[pLstReport.Count - 1].CompletedOnDate += _completedDiff;
                            pLstReport[pLstReport.Count - 1].CompletedFieldValue = _completedValue;
                        }
                        else // add new report item
                            pLstReport.Add(
                                new FTTaskComleted
                                {
                                    FTID = pDctTasksFT[_taskId],
                                    TaskID = _taskId, ReportDT = _changedDate,
                                    CompletedOnDate = _completedDiff,
                                    CompletedFieldValue = _completedValue }
                                );

                        _lastDate = _changedDate;
                    }

                }
            }
        }


        static Dictionary<int, int> GetTaskAndFeatures(DateTime pStartDate)
        {
            Dictionary<int, int> _taskft = new Dictionary<int, int>();

            List<int> _ids = GetTasksIdsForPeriod(pStartDate);

            if (_ids.Count > 0)
            {
                foreach(int _wiId in _ids)
                    if (!AddFeaturesToTask(_wiId, _taskft)) break;
            }

            return _taskft;
        }

        //add top level parent to task id and exclude tasks without parent features
        static bool AddFeaturesToTask(int pId, Dictionary<int, int> pWiDict)
        {
            try
            {
                Wiql _wiql = new Wiql();
                _wiql.Query = String.Format(WIQLS.GetTopParentFeature, TeamProject, pId);

                WorkItemQueryResult _res = WiClient.QueryByWiqlAsync(_wiql).Result;

                if (_res.WorkItemRelations.Count() > 1)
                    pWiDict.Add(pId, _res.WorkItemRelations.ElementAt(0).Target.Id); //first is a top parent
            }
            catch (Exception ex)
            {
                Console.WriteLine("Query problem:");
                Console.WriteLine(ex.Message);
                return false;
            }

            return true;
        }

        //Connect to tfs/vsts
        static public bool ConnectToService()
        {
            try
            {
                VssCredentials creds = new VssClientCredentials();
                creds.Storage = new VssClientCredentialStorage();

                ServiceConnection = new VssConnection(new Uri(ServiceUrl), creds);
                ServiceConnection.ConnectAsync().Wait();
                WiClient = ServiceConnection.GetClient<WorkItemTrackingHttpClient>();
            }
            catch(Exception ex)
            {
                Console.WriteLine("Connection problem:");
                Console.WriteLine(ex.Message);
                return false;
            }

            return true;
        }

        //find all tasks changed after start date. beacouse we can not select revisions between dates.
        static public List<int> GetTasksIdsForPeriod(DateTime pStart)
        {
            List<int> _ids = new List<int>();

            try
            {
                Wiql _wiql = new Wiql();
                _wiql.Query = String.Format(WIQLS.ChangedTasksFromDate, TeamProject, pStart.Year, pStart.Month, pStart.Day);

                WorkItemQueryResult _res = WiClient.QueryByWiqlAsync(_wiql).Result;

                if (_res.WorkItems.Count() > 0)
                    foreach (WorkItemReference _wi in _res.WorkItems) _ids.Add(_wi.Id);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Query problem:");
                Console.WriteLine(ex.Message);
            }

            return _ids;
        }
    }
}

这篇关于如何按日期通过WIQL tfs获取任务ID,功能ID,完成小时数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆