Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions AzureDevopsTracker/Adapters/WorkItemAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class WorkItemAdapter : IWorkItemAdapter
{
public WorkItemDTO ToWorkItemDTO(WorkItem workItem)
{
if (workItem == null) return null;
if (workItem is null) return null;

return new WorkItemDTO()
{
Expand All @@ -31,7 +31,7 @@ public WorkItemDTO ToWorkItemDTO(WorkItem workItem)
OriginalEstimate = workItem.OriginalEstimate,
WorkItemParentId = workItem.WorkItemParentId,
Activity = workItem.Activity,
Tags = workItem.Tags == null ? new List<string>() : workItem.Tags.Split(';').ToList(),
Tags = workItem.Tags is null ? new List<string>() : workItem.Tags.Split(';').ToList(),
WorkItemsChangesDTO = ToWorkItemsChangeDTO(workItem.WorkItemsChanges.OrderBy(x => x.CreatedAt).ToList()),
TimesByStateDTO = ToTimeByStatesDTO(workItem.CalculateTotalTimeByState().ToList()),
};
Expand All @@ -41,7 +41,7 @@ public List<WorkItemDTO> ToWorkItemsDTO(List<WorkItem> workItems)
{
var workItemsDTO = new List<WorkItemDTO>();

if (workItems == null) return workItemsDTO;
if (workItems is null) return workItemsDTO;

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

public WorkItemChangeDTO ToWorkItemChangeDTO(WorkItemChange workIteChange)
{
if (workIteChange == null) return null;
if (workIteChange is null) return null;

return new WorkItemChangeDTO()
{
Expand All @@ -69,20 +69,20 @@ public List<WorkItemChangeDTO> ToWorkItemsChangeDTO(List<WorkItemChange> workIte
{
var workItemsChangeDTO = new List<WorkItemChangeDTO>();

if (workItemsChanges == null) return workItemsChangeDTO;
if (workItemsChanges is null) return workItemsChangeDTO;

workItemsChanges.ForEach(
workItemsChange =>
workItemsChangeDTO.Add(ToWorkItemChangeDTO(workItemsChange)));

return workItemsChangeDTO
.Where(w => w != null)
.Where(w => w is not null)
.ToList();
}

public TimeByStateDTO ToTimeByStateDTO(TimeByState workItemStatusTime)
{
if (workItemStatusTime == null) return null;
if (workItemStatusTime is null) return null;

return new TimeByStateDTO()
{
Expand All @@ -97,14 +97,14 @@ public List<TimeByStateDTO> ToTimeByStatesDTO(List<TimeByState> workItemStatusTi
{
var workItemStatusTimeDTO = new List<TimeByStateDTO>();

if (workItemStatusTimes == null) return workItemStatusTimeDTO;
if (workItemStatusTimes is null) return workItemStatusTimeDTO;

workItemStatusTimes.ForEach(
workItemStatusTime =>
workItemStatusTimeDTO.Add(ToTimeByStateDTO(workItemStatusTime)));

return workItemStatusTimeDTO
.Where(w => w != null)
.Where(w => w is not null)
.ToList();
}
}
Expand Down
7 changes: 4 additions & 3 deletions AzureDevopsTracker/AzureDevopsTracker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
<PackageLicenseFile>LICENSE.md.txt</PackageLicenseFile>
<Description>A NuGet that allows you to use a Azure DevOps Service Hook to track workitems changes in a simply and detailed way.</Description>
<AssemblyVersion>5.0.0.0</AssemblyVersion>
<FileVersion>5.0.3</FileVersion>
<Version>5.0.3</Version>
<FileVersion>5.0.4</FileVersion>
<Version>5.0.4</Version>
<PackageReleaseNotes>Add ChangeLog Feature</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>

Expand Down
5 changes: 4 additions & 1 deletion AzureDevopsTracker/Configurations/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using AzureDevopsTracker.Interfaces.Internals;
using AzureDevopsTracker.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
Expand All @@ -21,6 +22,8 @@ public static IServiceCollection AddAzureDevopsTracker(this IServiceCollection s

services.AddMessageIntegrations();

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddScoped<AzureDevopsTrackerContext>();
services.AddScoped<IWorkItemAdapter, WorkItemAdapter>();
services.AddScoped<IWorkItemRepository, WorkItemRepository>();
Expand All @@ -44,7 +47,7 @@ private static IServiceCollection AddMessageIntegrations(this IServiceCollection
case EMessengers.MICROSOFT_TEAMS:
services.AddScoped<MessageIntegration, MicrosoftTeamsIntegration>();
break;
default:
default:
services.AddScoped<MessageIntegration, FakeIntegration>();
break;
}
Expand Down
3 changes: 0 additions & 3 deletions AzureDevopsTracker/DTOs/Fields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ public class Fields
[JsonProperty("Microsoft.VSTS.Common.Activity")]
public string Activity { get; set; }

[JsonProperty("Custom.01f51eeb-416d-49b1-b7f9-b92f3a675de1")]
public string Lancado { get; set; }

[JsonProperty("Custom.ChangeLogDescription")]
public string ChangeLogDescription { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public AzureDevopsTrackerContext(DbContextOptions options) : base(options)
public DbSet<TimeByState> TimeByStates { get; set; }
public DbSet<ChangeLogItem> ChangeLogItems { get; set; }
public DbSet<ChangeLog> ChangeLogs { get; set; }
public DbSet<WorkItemCustomField> CustomFields { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expand Down
2 changes: 1 addition & 1 deletion AzureDevopsTracker/Data/DataBaseConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public DataBaseConfig(string connectionsString, string schemaName = "dbo", TimeZ
if (connectionsString.IsNullOrEmpty())
throw new ArgumentException("The ConnectionsString is required");

if (timeZoneInfo == null)
if (timeZoneInfo is null)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time");
else
Expand Down
2 changes: 1 addition & 1 deletion AzureDevopsTracker/Data/Mapping/ChangeLogMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ public void Configure(EntityTypeBuilder<ChangeLog> builder)
.HasColumnType("varchar(max)");
}
}
}
}
20 changes: 20 additions & 0 deletions AzureDevopsTracker/Data/Mapping/CustomFieldMapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using AzureDevopsTracker.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace AzureDevopsTracker.Data.Mapping
{
public class CustomFieldMapping : IEntityTypeConfiguration<WorkItemCustomField>
{
public void Configure(EntityTypeBuilder<WorkItemCustomField> builder)
{
builder.HasKey(k => new { k.WorkItemId, k.Key });

builder.Property(p => p.Key)
.HasColumnType("varchar(1000)");

builder.Property(p => p.Value)
.HasColumnType("varchar(max)");
}
}
}
3 changes: 3 additions & 0 deletions AzureDevopsTracker/Data/WorkItemRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public async Task<WorkItem> GetByWorkItemId(string workItemId)
.Include(x => x.WorkItemsChanges)
.Include(x => x.TimeByStates)
.Include(x => x.ChangeLogItem)
.Include(x => x.CustomFields)
.FirstOrDefaultAsync(x => x.Id == workItemId);
}

Expand All @@ -27,6 +28,7 @@ public async Task<IEnumerable<WorkItem>> ListByWorkItemId(IEnumerable<string> wo
.Include(x => x.WorkItemsChanges)
.Include(x => x.TimeByStates)
.Include(x => x.ChangeLogItem)
.Include(x => x.CustomFields)
.Where(x => workItemsId.Contains(x.Id))
.ToListAsync();
}
Expand All @@ -37,6 +39,7 @@ public async Task<IEnumerable<WorkItem>> ListByIterationPath(string iterationPat
.Include(x => x.WorkItemsChanges)
.Include(x => x.TimeByStates)
.Include(x => x.ChangeLogItem)
.Include(x => x.CustomFields)
.Where(x => x.IterationPath == iterationPath)
.ToListAsync();
}
Expand Down
4 changes: 2 additions & 2 deletions AzureDevopsTracker/Entities/ChangeLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void ClearResponse()

public void AddChangeLogItem(ChangeLogItem changeLogItem)
{
if (changeLogItem == null)
if (changeLogItem is null)
throw new Exception("ChangeLogItem is required");

if (CheckChangeLogItem(changeLogItem))
Expand All @@ -49,7 +49,7 @@ public void AddChangeLogItem(ChangeLogItem changeLogItem)

public void AddChangeLogItems(IEnumerable<ChangeLogItem> changeLogItems)
{
if (changeLogItems == null)
if (changeLogItems is null)
throw new Exception("ChangeLogItems is required");

foreach (var changeLogItem in changeLogItems)
Expand Down
2 changes: 1 addition & 1 deletion AzureDevopsTracker/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public abstract class Entity
public DateTime CreatedAt { get; private set; }
public Entity(string id)
{
Id = id;
Id = id ?? Guid.NewGuid().ToString();
CreatedAt = DateTime.UtcNow;
}

Expand Down
64 changes: 42 additions & 22 deletions AzureDevopsTracker/Entities/WorkItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,25 @@ public class WorkItem : Entity
public string StoryPoints { get; private set; }
public string WorkItemParentId { get; private set; }
public string Activity { get; private set; }
public string Lancado { get; private set; }
public bool Deleted { get; private set; }

public ChangeLogItem ChangeLogItem { get; private set; }

private readonly List<WorkItemChange> _workItemsChanges;
private readonly List<WorkItemChange> _workItemsChanges = new();
public IReadOnlyCollection<WorkItemChange> WorkItemsChanges => _workItemsChanges;

private readonly List<TimeByState> _timeByState;
private readonly List<TimeByState> _timeByState = new();
public IReadOnlyCollection<TimeByState> TimeByStates => _timeByState;

private readonly List<WorkItemCustomField> _workItemCustomFields = new();
public IReadOnlyCollection<WorkItemCustomField> CustomFields => _workItemCustomFields;
public string CurrentStatus => _workItemsChanges?.OrderBy(x => x.CreatedAt)?.LastOrDefault()?.NewState;
public string LastStatus => _workItemsChanges?.OrderBy(x => x.CreatedAt)?.ToList()?.Skip(1)?.LastOrDefault()?.OldState;

private WorkItem()
{
_workItemsChanges = new List<WorkItemChange>();
_timeByState = new List<TimeByState>();
}
private WorkItem() { }

public WorkItem(string workItemId) : base(workItemId)
{
_workItemsChanges = new List<WorkItemChange>();
_timeByState = new List<TimeByState>();
Validate();
}

Expand All @@ -55,8 +51,7 @@ public void Update(string title,
string effort,
string storyPoint,
string originalEstimate,
string activity,
string lancado)
string activity)
{
TeamProject = teamProject;
AreaPath = areaPath;
Expand All @@ -71,7 +66,6 @@ public void Update(string title,
StoryPoints = storyPoint;
OriginalEstimate = originalEstimate;
Activity = activity;
Lancado = lancado;
}

public void Restore()
Expand All @@ -87,34 +81,60 @@ public void Delete()
public void Validate()
{
if (Id.IsNullOrEmpty())
throw new Exception("WorkItemId is required");
throw new ArgumentException("WorkItemId is required");
}

public void AddWorkItemChange(WorkItemChange workItemChange)
{
if (workItemChange == null)
throw new Exception("WorkItemChange is null");
if (workItemChange is null)
throw new ArgumentException("WorkItemChange is null");

_workItemsChanges.Add(workItemChange);
}

public void AddTimeByState(TimeByState timeByState)
{
if (timeByState == null)
throw new Exception("TimeByState is null");
if (timeByState is null)
throw new ArgumentException("TimeByState is null");

_timeByState.Add(timeByState);
}

public void AddTimesByState(IEnumerable<TimeByState> timesByState)
{
if (!timesByState.Any())
if (timesByState is not null && !timesByState.Any())
return;

foreach (var timeByState in timesByState)
AddTimeByState(timeByState);
}

public void AddCustomField(WorkItemCustomField customField)
{
if (customField is null)
throw new ArgumentException("CustomField is null");

_workItemCustomFields.Add(customField);
}

public void AddCustomFields(IEnumerable<WorkItemCustomField> customFields)
{
if (customFields is null || !customFields.Any())
return;

foreach (var customField in customFields)
AddCustomField(customField);
}

public void UpdateCustomFields(IEnumerable<WorkItemCustomField> newCustomFields)
{
if (newCustomFields is null || !newCustomFields.Any())
return;

_workItemCustomFields.Clear();
AddCustomFields(newCustomFields);
}

public void ClearTimesByState()
{
_timeByState.Clear();
Expand All @@ -127,8 +147,8 @@ public void RemoveChangeLogItem()

public void VinculateChangeLogItem(ChangeLogItem changeLogItem)
{
if (changeLogItem == null)
throw new Exception("ChangeLogItem is null");
if (changeLogItem is null)
throw new ArgumentException("ChangeLogItem is null");

ChangeLogItem = changeLogItem;
}
Expand All @@ -139,7 +159,7 @@ public IEnumerable<TimeByState> CalculateTotalTimeByState()
if (!_workItemsChanges.Any())
return timesByStateList;

foreach (var workItemChange in _workItemsChanges.OrderBy(x => x.CreatedAt).GroupBy(x => x.OldState).Where(x => x.Key != null))
foreach (var workItemChange in _workItemsChanges.OrderBy(x => x.CreatedAt).GroupBy(x => x.OldState).Where(x => x.Key is not null))
{
var totalTime = TimeSpan.Zero;
var totalWorkedTime = TimeSpan.Zero;
Expand Down
2 changes: 1 addition & 1 deletion AzureDevopsTracker/Entities/WorkItemChange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void Validate()

public TimeSpan CalculateTotalTime()
{
return OldDate == null ? TimeSpan.Zero : NewDate.ToDateTimeFromTimeZoneInfo() - OldDate.Value.ToDateTimeFromTimeZoneInfo();
return OldDate is null ? TimeSpan.Zero : NewDate.ToDateTimeFromTimeZoneInfo() - OldDate.Value.ToDateTimeFromTimeZoneInfo();
}

public double CalculateTotalWorkedTime()
Expand Down
Loading