private IList <WorkItem> ExecuteRule(IRule rule, ITfsApi api) { var result = new List <WorkItem>(); try { var source = api.QueryItems(rule.Source); var conditional = api.QueryItems(rule.Condition); switch (rule.Operation) { // Кол-во должно быть одинаковым case RuleOperation.SameCount: var except = source.Except(conditional, new IdWorkItemComparer()); result.AddRange(except); break; // Кол-во запроса должно быть нулевым case RuleOperation.ZeroCount: // Пока проверяется только первое условие result.AddRange(source); break; } } catch (Exception e) { Trace.WriteLine($"{nameof(RuleBuilder)}.{nameof(ExecuteRule)}: " + e); } return(result); }
/// <summary> /// Синхронизируем дневной плн списания времени. Кол-во списанного времени должно быть равно дневной норме. /// </summary> /// <param name="api"></param> /// <param name="capacity"></param> /// <param name="currentItem"></param> public void SyncDailyPlan(ITfsApi api, int capacity, Func <WorkItem> currentItem) { // Обновили историю чекинов SyncCheckins(api); // Обрезали, если вышли за предел кол-ва часов CutOffByCapacity(capacity); // сколько было списно пользователем var byUser = CheckinedTime(); // сколько было списано var scheduled = ScheduledTime(); var delta = capacity - byUser - scheduled; // Нужно распланировать ещё времени if (delta > 0) { var item = currentItem(); // Если элемент нулёвый, считаем, что списание выключено if (item != null) { ScheduleWork(item.Id, delta); } } CheckinWork(api); }
/// <summary> /// Списываем запланированную работу /// </summary> /// <param name="api">TFS API</param> /// <param name="capacity">Кол-во рабочих часов в этом дне</param> public void CheckinScheduledWork(ITfsApi api, int capacity) { // Обновили историю чекинов SyncCheckins(api); // Обрезали, если вышли за предел кол-ва часов CutOffByCapacity(capacity); CheckinWork(api); }
public ChooseTaskViewModel(ITfsApi tfs) { _tfs = tfs; SpecialCommand = new ObservableCommand(CreateTask); Searcher = new WorkItemSearcher(_tfs, WorkItemTypes.Task) { Help = Resources.AS_ChooseTask }; }
/// <summary> /// Записываем всю работу в TFS. /// В случаем с чекином вчерашней работы, она записывается отдельно и не мешает /// дневному кол-ву работы /// </summary> private void CheckinWork(ITfsApi tfs) { // Получили задачи на списание времени var manual = Merge(GetManual(this)); // Нашли элементы одним запросом var items = tfs.FindById(manual.Select(x => x.Id)); foreach (var toWrite in manual) { // какая-то ошибка, такого номера нет if (!items.ContainsKey(toWrite.Id)) { Trace.WriteLine( $"{nameof(WriteOffCollection)}.{nameof(CheckinWork)}: Cannot find item {toWrite.Id}"); continue; } // Получили рабочий элемента var workItem = items[toWrite.Id]; try { // Записали время var revision = tfs.WriteHours(workItem, (byte)toWrite.Hours, true); // Удалили этот рабочий элемента RemoveAll(x => x.Id == toWrite.Id); // Не получилось запписать, ошибка if (revision == null) { Trace.WriteLine( $"{nameof(WriteOffCollection)}.{nameof(CheckinWork)}: Cannot write off hours of task {workItem.Id}"); continue; } var time = (DateTime)revision.Fields[CoreField.ChangedDate].Value; Add(new WriteOff(revision.WorkItem.Id, toWrite.Hours, time, // Если запись была запланирована сегодня, считаем это обычным // чекином юзера toWrite.Time.IsToday(), true)); } catch (Exception e) { Trace.WriteLine(e); } } ClearPrevRecords(); }
public SettingsViewModel(string currentConnection, ITfsApi api) { _api = api; ConnectCommand = new ObservableCommand(OnConnect); SubmitCommand = new ObservableCommand(OnSave, OnCanSave); ChooseLogFileCommand = new ObservableCommand(OnChooseFile); Init(currentConnection); }
public NewResponsesBaloonViewModel(IEnumerable <WorkItem> responses, IEnumerable <WorkItem> reviews, ITfsApi api, string title = null) : base(responses, title ?? Resources.AS_CodeReviewRequested) { _reviews = reviews.ToList(); _api = api; _time = TimeSpan.FromDays(Settings.Settings.Read().OldReviewDay); CloseReviewes = ObservableCommand.FromAsyncHandler(OnCloseGoodLooking, OnCanCloseGoodLooking).ExecuteOnce(); CloseOldReviewes = ObservableCommand.FromAsyncHandler(OnCloseOld, OnCanCloseOld).ExecuteOnce(); }
public CreateTaskViewModel(ITfsApi tfs) { _tfs = tfs; // Ищем для привязки только указанные типы Searcher = new WorkItemSearcher(tfs, WorkItemTypes.Pbi, WorkItemTypes.Bug, WorkItemTypes.Improvement, WorkItemTypes.Incident) { Help = Resources.AS_ChooseParentItem }; SubmitCommand = new ObservableCommand(CreateTask, OnCanCreateTask); }
/// <summary> /// Проверяем, записали ли чекины от пользователя /// </summary> /// <param name="tfs"></param> public void SyncCheckins(ITfsApi tfs) { var checkins = tfs.GetWriteoffs(DateTime.Today, DateTime.Now); Trace.WriteLine($"{nameof(WriteOffCollection)}.{nameof(SyncCheckins)}: Founded {checkins.Count} changes"); foreach (var checkin in checkins) { var id = checkin.Key.WorkItem.Id; var date = (DateTime)checkin.Key.Fields[CoreField.ChangedDate].Value; if (!this.Any(x => x.Time == date && x.Id == id)) { var userCheckIn = new WriteOff(id, checkin.Value, date); Add(userCheckIn); Trace.WriteLine($"{nameof(WriteOffCollection)}.{nameof(SyncCheckins)}: Detected new check-in, " + $"Id - {checkin.Key.WorkItem.Id}, Time - {date.ToShortTimeString()}"); } } }
/// <summary> /// Заполняем выпадающий список элементами, привязанными на меня /// </summary> /// <param name="api"></param> /// <param name="types">Типы элементов, который хочу вывести. Cм. <see cref="WorkItemTypes" /></param> public WorkItemSearcher(ITfsApi api, params ItemTypeMark[] types) { _api = api; _action = new TimedAction <string, IList <WorkItemVm> >(PerformSearch); _action.Performed += OnResult; _items = new List <WorkItemVm>(); Filter = new FilterViewModel(types?.ToArray()); Filter.FilterChanged += (sender, args) => UpdateByFilter(true); var mine = _api.GetMyWorkItems(); if (!types.IsNullOrEmpty()) { var workTypes = types.Select(x => x.WorkType).ToArray(); mine = mine.Where(x => x.IsTypeOf(workTypes)).ToList(); } _originItems.AddRange(mine.Select(x => new WorkItemVm(x))); UpdateByFilter(); }
public TFSIssueResolver(ITfsApi tfsApi) { _tfsApi = tfsApi; }
public MonthCheckinsViewModel(ITfsApi api) { _api = api; Date = DateTime.Now; }
public TfsApiController(ITfsApi tfsApiService) { this._tfsApiService = tfsApiService; }
/// <summary> /// Проверяет правило и возвращает неподхдодящие рабочие элементы /// </summary> /// <param name="rules"></param> /// <returns></returns> public Dictionary <IRule, IList <WorkItem> > CheckInconsistant(IEnumerable <IRule> rules, ITfsApi api) { var toReturn = new Dictionary <IRule, IList <WorkItem> >(); foreach (var rule in rules) { var result = ExecuteRule(rule, api); if (result.Any()) { toReturn[rule] = result; } } return(toReturn); }