Skip to content

Commit 6f9b981

Browse files
committed
Adding custom fields from azure's json
1 parent 9e0c9ab commit 6f9b981

File tree

12 files changed

+188
-37
lines changed

12 files changed

+188
-37
lines changed

AzureDevopsTracker/Adapters/WorkItemAdapter.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal class WorkItemAdapter : IWorkItemAdapter
1212
{
1313
public WorkItemDTO ToWorkItemDTO(WorkItem workItem)
1414
{
15-
if (workItem == null) return null;
15+
if (workItem is null) return null;
1616

1717
return new WorkItemDTO()
1818
{
@@ -31,7 +31,7 @@ public WorkItemDTO ToWorkItemDTO(WorkItem workItem)
3131
OriginalEstimate = workItem.OriginalEstimate,
3232
WorkItemParentId = workItem.WorkItemParentId,
3333
Activity = workItem.Activity,
34-
Tags = workItem.Tags == null ? new List<string>() : workItem.Tags.Split(';').ToList(),
34+
Tags = workItem.Tags is null ? new List<string>() : workItem.Tags.Split(';').ToList(),
3535
WorkItemsChangesDTO = ToWorkItemsChangeDTO(workItem.WorkItemsChanges.OrderBy(x => x.CreatedAt).ToList()),
3636
TimesByStateDTO = ToTimeByStatesDTO(workItem.CalculateTotalTimeByState().ToList()),
3737
};
@@ -41,7 +41,7 @@ public List<WorkItemDTO> ToWorkItemsDTO(List<WorkItem> workItems)
4141
{
4242
var workItemsDTO = new List<WorkItemDTO>();
4343

44-
if (workItems == null) return workItemsDTO;
44+
if (workItems is null) return workItemsDTO;
4545

4646
workItems.ForEach(
4747
workItem =>
@@ -53,7 +53,7 @@ public List<WorkItemDTO> ToWorkItemsDTO(List<WorkItem> workItems)
5353

5454
public WorkItemChangeDTO ToWorkItemChangeDTO(WorkItemChange workIteChange)
5555
{
56-
if (workIteChange == null) return null;
56+
if (workIteChange is null) return null;
5757

5858
return new WorkItemChangeDTO()
5959
{
@@ -69,20 +69,20 @@ public List<WorkItemChangeDTO> ToWorkItemsChangeDTO(List<WorkItemChange> workIte
6969
{
7070
var workItemsChangeDTO = new List<WorkItemChangeDTO>();
7171

72-
if (workItemsChanges == null) return workItemsChangeDTO;
72+
if (workItemsChanges is null) return workItemsChangeDTO;
7373

7474
workItemsChanges.ForEach(
7575
workItemsChange =>
7676
workItemsChangeDTO.Add(ToWorkItemChangeDTO(workItemsChange)));
7777

7878
return workItemsChangeDTO
79-
.Where(w => w != null)
79+
.Where(w => w is not null)
8080
.ToList();
8181
}
8282

8383
public TimeByStateDTO ToTimeByStateDTO(TimeByState workItemStatusTime)
8484
{
85-
if (workItemStatusTime == null) return null;
85+
if (workItemStatusTime is null) return null;
8686

8787
return new TimeByStateDTO()
8888
{
@@ -97,14 +97,14 @@ public List<TimeByStateDTO> ToTimeByStatesDTO(List<TimeByState> workItemStatusTi
9797
{
9898
var workItemStatusTimeDTO = new List<TimeByStateDTO>();
9999

100-
if (workItemStatusTimes == null) return workItemStatusTimeDTO;
100+
if (workItemStatusTimes is null) return workItemStatusTimeDTO;
101101

102102
workItemStatusTimes.ForEach(
103103
workItemStatusTime =>
104104
workItemStatusTimeDTO.Add(ToTimeByStateDTO(workItemStatusTime)));
105105

106106
return workItemStatusTimeDTO
107-
.Where(w => w != null)
107+
.Where(w => w is not null)
108108
.ToList();
109109
}
110110
}

AzureDevopsTracker/Data/DataBaseConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public DataBaseConfig(string connectionsString, string schemaName = "dbo", TimeZ
1111
if (connectionsString.IsNullOrEmpty())
1212
throw new ArgumentException("The ConnectionsString is required");
1313

14-
if (timeZoneInfo == null)
14+
if (timeZoneInfo is null)
1515
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
1616
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time");
1717
else

AzureDevopsTracker/Entities/ChangeLog.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void ClearResponse()
3737

3838
public void AddChangeLogItem(ChangeLogItem changeLogItem)
3939
{
40-
if (changeLogItem == null)
40+
if (changeLogItem is null)
4141
throw new Exception("ChangeLogItem is required");
4242

4343
if (CheckChangeLogItem(changeLogItem))
@@ -49,7 +49,7 @@ public void AddChangeLogItem(ChangeLogItem changeLogItem)
4949

5050
public void AddChangeLogItems(IEnumerable<ChangeLogItem> changeLogItems)
5151
{
52-
if (changeLogItems == null)
52+
if (changeLogItems is null)
5353
throw new Exception("ChangeLogItems is required");
5454

5555
foreach (var changeLogItem in changeLogItems)

AzureDevopsTracker/Entities/Entity.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public abstract class Entity
88
public DateTime CreatedAt { get; private set; }
99
public Entity(string id)
1010
{
11-
Id = id;
11+
Id = id ?? Guid.NewGuid().ToString();
1212
CreatedAt = DateTime.UtcNow;
1313
}
1414

AzureDevopsTracker/Entities/WorkItem.cs

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,21 @@ public class WorkItem : Entity
2424

2525
public ChangeLogItem ChangeLogItem { get; private set; }
2626

27-
private readonly List<WorkItemChange> _workItemsChanges;
27+
private readonly List<WorkItemChange> _workItemsChanges = new List<WorkItemChange>();
2828
public IReadOnlyCollection<WorkItemChange> WorkItemsChanges => _workItemsChanges;
2929

30-
private readonly List<TimeByState> _timeByState;
30+
private readonly List<TimeByState> _timeByState = new List<TimeByState>();
3131
public IReadOnlyCollection<TimeByState> TimeByStates => _timeByState;
32+
33+
private readonly List<WorkItemCustomField> _workItemCustomFields = new List<WorkItemCustomField>();
34+
public IReadOnlyCollection<WorkItemCustomField> CustomFields => _workItemCustomFields;
3235
public string CurrentStatus => _workItemsChanges?.OrderBy(x => x.CreatedAt)?.LastOrDefault()?.NewState;
3336
public string LastStatus => _workItemsChanges?.OrderBy(x => x.CreatedAt)?.ToList()?.Skip(1)?.LastOrDefault()?.OldState;
3437

35-
private WorkItem()
36-
{
37-
_workItemsChanges = new List<WorkItemChange>();
38-
_timeByState = new List<TimeByState>();
39-
}
38+
private WorkItem() { }
4039

4140
public WorkItem(string workItemId) : base(workItemId)
4241
{
43-
_workItemsChanges = new List<WorkItemChange>();
44-
_timeByState = new List<TimeByState>();
4542
Validate();
4643
}
4744

@@ -76,34 +73,75 @@ public void Update(string title,
7673
public void Validate()
7774
{
7875
if (Id.IsNullOrEmpty())
79-
throw new Exception("WorkItemId is required");
76+
throw new ArgumentException("WorkItemId is required");
8077
}
8178

8279
public void AddWorkItemChange(WorkItemChange workItemChange)
8380
{
84-
if (workItemChange == null)
85-
throw new Exception("WorkItemChange is null");
81+
if (workItemChange is null)
82+
throw new ArgumentException("WorkItemChange is null");
8683

8784
_workItemsChanges.Add(workItemChange);
8885
}
8986

9087
public void AddTimeByState(TimeByState timeByState)
9188
{
92-
if (timeByState == null)
93-
throw new Exception("TimeByState is null");
89+
if (timeByState is null)
90+
throw new ArgumentException("TimeByState is null");
9491

9592
_timeByState.Add(timeByState);
9693
}
9794

9895
public void AddTimesByState(IEnumerable<TimeByState> timesByState)
9996
{
100-
if (!timesByState.Any())
97+
if (timesByState is not null && !timesByState.Any())
10198
return;
10299

103100
foreach (var timeByState in timesByState)
104101
AddTimeByState(timeByState);
105102
}
106103

104+
public void AddCustomField(WorkItemCustomField customField)
105+
{
106+
if (customField is null)
107+
throw new ArgumentException("CustomField is null");
108+
109+
if (customField.WorkItemId.IsNullOrEmpty())
110+
customField.LinkWorkItem(Id);
111+
112+
_workItemCustomFields.Add(customField);
113+
}
114+
115+
public void AddCustomFields(IEnumerable<WorkItemCustomField> customFields)
116+
{
117+
if (customFields is not null && !customFields.Any())
118+
return;
119+
120+
foreach (var customField in customFields)
121+
AddCustomField(customField);
122+
}
123+
124+
public void UpdateCustomFields(IEnumerable<WorkItemCustomField> newCustomFields)
125+
{
126+
if (newCustomFields is not null && !newCustomFields.Any())
127+
return;
128+
129+
var customFieldsToAdd = newCustomFields.Where(x => !_workItemCustomFields.Select(x => x.Key).Contains(x.Key));
130+
AddCustomFields(customFieldsToAdd);
131+
132+
var customFieldsToUpdate = newCustomFields.Where(x => _workItemCustomFields.Select(x => x.Key).Contains(x.Key));
133+
foreach (var newCustomField in customFieldsToUpdate)
134+
{
135+
var customField = _workItemCustomFields.FirstOrDefault(x => x.Key == newCustomField.Key);
136+
if (customField is null) continue;
137+
138+
if (customField.WorkItemId.IsNullOrEmpty())
139+
customField.LinkWorkItem(Id);
140+
141+
customField.Update(customField.Value);
142+
}
143+
}
144+
107145
public void ClearTimesByState()
108146
{
109147
_timeByState.Clear();
@@ -116,8 +154,8 @@ public void RemoveChangeLogItem()
116154

117155
public void VinculateChangeLogItem(ChangeLogItem changeLogItem)
118156
{
119-
if (changeLogItem == null)
120-
throw new Exception("ChangeLogItem is null");
157+
if (changeLogItem is null)
158+
throw new ArgumentException("ChangeLogItem is null");
121159

122160
ChangeLogItem = changeLogItem;
123161
}
@@ -128,7 +166,7 @@ public IEnumerable<TimeByState> CalculateTotalTimeByState()
128166
if (!_workItemsChanges.Any())
129167
return timesByStateList;
130168

131-
foreach (var workItemChange in _workItemsChanges.OrderBy(x => x.CreatedAt).GroupBy(x => x.OldState).Where(x => x.Key != null))
169+
foreach (var workItemChange in _workItemsChanges.OrderBy(x => x.CreatedAt).GroupBy(x => x.OldState).Where(x => x.Key is not null))
132170
{
133171
var totalTime = TimeSpan.Zero;
134172
var totalWorkedTime = TimeSpan.Zero;

AzureDevopsTracker/Entities/WorkItemChange.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void Validate()
4040

4141
public TimeSpan CalculateTotalTime()
4242
{
43-
return OldDate == null ? TimeSpan.Zero : NewDate.ToDateTimeFromTimeZoneInfo() - OldDate.Value.ToDateTimeFromTimeZoneInfo();
43+
return OldDate is null ? TimeSpan.Zero : NewDate.ToDateTimeFromTimeZoneInfo() - OldDate.Value.ToDateTimeFromTimeZoneInfo();
4444
}
4545

4646
public double CalculateTotalWorkedTime()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using AzureDevopsTracker.Extensions;
2+
using System;
3+
4+
namespace AzureDevopsTracker.Entities
5+
{
6+
public class WorkItemCustomField
7+
{
8+
public string WorkItemId { get; private set; }
9+
public string Key { get; private set; }
10+
public string Value { get; private set; }
11+
12+
public WorkItem WorkItem { get; private set; }
13+
14+
public WorkItemCustomField(string key, string value)
15+
{
16+
Key = key;
17+
Value = value;
18+
}
19+
20+
public void LinkWorkItem(string workItemId)
21+
{
22+
if (workItemId.IsNullOrEmpty())
23+
throw new ArgumentException("WorkItemId is required");
24+
25+
WorkItemId = workItemId;
26+
}
27+
28+
public void Update(string value)
29+
{
30+
Value = value;
31+
}
32+
}
33+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using AzureDevopsTracker.Entities;
2+
using Newtonsoft.Json.Linq;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
namespace AzureDevopsTracker.Helpers
7+
{
8+
public static class ReadJsonHelper
9+
{
10+
public static IEnumerable<WorkItemCustomField> ReadJson(string jsonTexto)
11+
{
12+
try
13+
{
14+
var workItemCustomFields = new List<WorkItemCustomField>();
15+
foreach (KeyValuePair<string, JToken> element in JObject.Parse(jsonTexto))
16+
{
17+
if (element.Value is JObject)
18+
ReadJsonObject(workItemCustomFields, (JObject)element.Value);
19+
else
20+
GetWorkItemCustomField(workItemCustomFields, element.Key, element.Value.ToString());
21+
}
22+
23+
return workItemCustomFields;
24+
}
25+
catch
26+
{
27+
return Enumerable.Empty<WorkItemCustomField>();
28+
}
29+
}
30+
31+
private static void ReadJsonObject(List<WorkItemCustomField> workItemCustomFields, JObject objeto)
32+
{
33+
foreach (KeyValuePair<string, JToken> item in objeto)
34+
if (item.Value is JObject)
35+
ReadJsonObject(workItemCustomFields, (JObject)item.Value);
36+
else
37+
GetWorkItemCustomField(workItemCustomFields, item.Key, item.Value.ToString());
38+
}
39+
40+
private static void GetWorkItemCustomField(List<WorkItemCustomField> workItemCustomFields, string key, string value)
41+
{
42+
if (key is not null && !key.ToLower().Contains("custom")) return;
43+
workItemCustomFields.Add(new WorkItemCustomField(key, value));
44+
}
45+
}
46+
}

AzureDevopsTracker/Integrations/MessageFacade.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void Send(ChangeLog changeLog)
1919
using var scope = _serviceScopeFactory.CreateScope();
2020

2121
var messageIntegration = scope.ServiceProvider.GetService<MessageIntegration>();
22-
if (messageIntegration == null) throw new Exception("Configure the MessageConfig in Startup to send changelog messages");
22+
if (messageIntegration is null) throw new Exception("Configure the MessageConfig in Startup to send changelog messages");
2323

2424
messageIntegration.Send(changeLog);
2525
}

AzureDevopsTracker/Integrations/MicrosoftTeamsIntegration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ internal override void Send(ChangeLog changeLog)
6464

6565
private string GetText(ChangeLog changeLog)
6666
{
67-
if (changeLog == null || !changeLog.ChangeLogItems.Any()) return string.Empty;
67+
if (changeLog is null || !changeLog.ChangeLogItems.Any()) return string.Empty;
6868

6969
StringBuilder text = new();
7070
text.AppendLine(GetWorkItemsDescriptionSection("Features", changeLog.ChangeLogItems.Where(x => x.WorkItemType != WorkItemStatics.WORKITEM_TYPE_BUG)));

0 commit comments

Comments
 (0)