diff --git a/src/BuildingBlocks/Shared/Common/ApiResponse/Errors.cs b/src/BuildingBlocks/Shared/Common/ApiResponse/Errors.cs index bfc5e29..179d95e 100644 --- a/src/BuildingBlocks/Shared/Common/ApiResponse/Errors.cs +++ b/src/BuildingBlocks/Shared/Common/ApiResponse/Errors.cs @@ -10,21 +10,23 @@ public enum Errors [Description("Interal server error. Please contact the administrator.")] COM_000, - [Description("Not found {CustomMessage}.")] + [Description("Not found {0}.")] COM_001, [Description("User ID is not a valid Guid.")] VAL_000, - [Description("Validation failed. Detail messages: \n{CustomMessage}")] + [Description("Validation failed. Detail messages: \n{0}")] VAL_001 } public static class ErrorExtensions { - public static string GetMessages(this Errors error, params string[] messageParams) + public static string GetMessages(this Errors error, params object?[] messageParams) { - var messageFormat = error.GetDescription(); + var messageFormat = error + .GetDescription() + .Replace("\n", Environment.NewLine); var paramsCount = messageFormat.CountUniqueParams(); if (paramsCount != messageParams.Length) @@ -33,7 +35,9 @@ public static string GetMessages(this Errors error, params string[] messageParam "The number of parameters in the error message does not match the number of parameters passed."); } - return string.Format(messageFormat, messageParams.ToArray()); + messageParams = messageParams.Select(p => p?.ToString()).ToArray(); + + return string.Format(messageFormat, messageParams); } public static string GetCode(this Errors error) diff --git a/src/BuildingBlocks/Shared/Common/Helpers/DateTimeHelper.cs b/src/BuildingBlocks/Shared/Common/Helpers/DateTimeHelper.cs new file mode 100644 index 0000000..809f85c --- /dev/null +++ b/src/BuildingBlocks/Shared/Common/Helpers/DateTimeHelper.cs @@ -0,0 +1,19 @@ +namespace Shared.Common.Helpers; + +public static class DateTimeHelper +{ + public static DateTime ToDateTime(this object obj) + { + if (obj is DateTime dateTime) + { + return dateTime.ToUniversalTime(); + } + + if (obj is string stringValue && DateTime.TryParse(stringValue, out var parsedDateTime)) + { + return parsedDateTime.ToUniversalTime(); + } + + throw new ArgumentException("Invalid DateTime format"); + } +} \ No newline at end of file diff --git a/src/BuildingBlocks/Shared/Common/Helpers/DictionaryHelper.cs b/src/BuildingBlocks/Shared/Common/Helpers/DictionaryHelper.cs new file mode 100644 index 0000000..e916dc7 --- /dev/null +++ b/src/BuildingBlocks/Shared/Common/Helpers/DictionaryHelper.cs @@ -0,0 +1,44 @@ +using System.Reflection; + +namespace Shared.Common.Helpers; + +public static class DictionaryHelper +{ + public static IDictionary AsDictionary(this object obj) + { + return (IDictionary)obj; + } + + public static T GetObject(this IDictionary dictionary) where T : new() + { + var result = new T(); + + foreach (var kvp in dictionary) + { + var property = typeof(T).GetProperty(kvp.Key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); + + if (property == null || !property.CanWrite) + { + continue; + } + + var value = kvp.Value; + + if (value is not null) + { + if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)) + { + value = value.ToDateTime(); + } + else + { + value = Convert.ChangeType(value, property.PropertyType); + } + } + + property.SetValue(result, value, null); + } + + return result; + } +} \ No newline at end of file diff --git a/src/Portal/Portal/UseCases/Mutations/Handlers/UpdateKanbanProjectHandler.cs b/src/Portal/Portal/UseCases/Mutations/Handlers/UpdateKanbanProjectHandler.cs index 2649ae5..905f77d 100644 --- a/src/Portal/Portal/UseCases/Mutations/Handlers/UpdateKanbanProjectHandler.cs +++ b/src/Portal/Portal/UseCases/Mutations/Handlers/UpdateKanbanProjectHandler.cs @@ -7,6 +7,7 @@ using Portal.Data; using Portal.UseCases.Responses; using Shared.Common.ApiResponse; +using Shared.Common.Helpers; namespace Portal.UseCases.Mutations.Handlers; @@ -45,13 +46,18 @@ public async Task Handle(UpdateKanbanProjectCommand return new UpdateKanbanProjectResponse { StatusCode = ResponseStatuses.NotFound.GetCode(), - ErrorCode = Errors.VAL_001.GetCode(), - ErrorMessage = Errors.VAL_001.GetMessages("ProjectId") + ErrorCode = Errors.COM_001.GetCode(), + ErrorMessage = Errors.COM_001.GetMessages("ProjectId") }; } // Update column of tasks - var sectionDict = request.Tasks.ToFrozenDictionary(t => Guid.Parse(t.Key), t => Guid.Parse(((KanbanTaskDto)t.Value).Column)); + var sectionDict = request.Tasks + .Select(t => t.Value + .AsDictionary() + .GetObject()) + .ToFrozenDictionary(t => Guid.Parse(t.Id), t => Guid.Parse(t.Column)); + var tasks = await _portalContext.Tasks .Where(t => t.ProjectId.ToString() == request.ProjectId && t.DeletedOn == null) .ToListAsync(cancellationToken);