diff --git a/MagicCarpetProject/MagicCarpetContracts/BindingModels/PostBindingModel.cs b/MagicCarpetProject/MagicCarpetContracts/BindingModels/PostBindingModel.cs index 0ca9024..52bc4ba 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BindingModels/PostBindingModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BindingModels/PostBindingModel.cs @@ -1,7 +1,12 @@ -using System; +using MagicCarpetContracts.Infrastructure.PostConfigurations; +using MagicCarpetContracts.Mapper; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading.Tasks; namespace MagicCarpetContracts.BindingModels; @@ -16,5 +21,26 @@ public class PostBindingModel public string? PostType { get; set; } + [PostProcessing(MappingCallMethodName = "ParseConfiguration")] public string? ConfigurationJson { get; set; } + + private string ParseConfiguration(PostConfiguration model) => + System.Text.Json.JsonSerializer.Serialize(model, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); + private PostConfiguration? ParseJson(string json) + { + if (ConfigurationJson is null) + return null; + + var obj = JToken.Parse(json); + if (obj is not null) + { + return obj.Value("Type") switch + { + nameof(TravelAgentPostConfiguration) => JsonConvert.DeserializeObject(json)!, + nameof(ChiefPostConfiguration) => JsonConvert.DeserializeObject(json)!, + _ => JsonConvert.DeserializeObject(json)!, + }; + } + return null; + } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs index 607eae2..1b639ad 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs @@ -24,6 +24,8 @@ internal class ClientDataModel(string id, string fIO, string phoneNumber, double public double DiscountSize { get; private set; } = discountSize; + public ClientDataModel() : this(string.Empty, string.Empty, string.Empty, 0) { } + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs index 947bb72..ee09f2d 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs @@ -42,6 +42,8 @@ internal class EmployeeDataModel(string id, string fio, string email, string pos public EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate) : this(id, fio, email, postId, birthDate, employmentDate, false) { } + public EmployeeDataModel() : this(string.Empty, string.Empty, string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue, false) { } + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs index c8a9608..d267c7a 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs @@ -13,29 +13,24 @@ using System.Text; using System.Threading.Tasks; using MagicCarpetContracts.Resources; using Microsoft.Extensions.Localization; +using MagicCarpetContracts.Mapper; namespace MagicCarpetContracts.DataModels; internal class PostDataModel(string postId, string postName, PostType postType, PostConfiguration configuration) : IValidation { + [AlternativeName("PostId")] public string Id { get; private set; } = postId; public string PostName { get; private set; } = postName; public PostType PostType { get; private set; } = postType; + + [AlternativeName("Configuration")] + [AlternativeName("ConfigurationJson")] + [PostProcessing(MappingCallMethodName = "ParseJson")] public PostConfiguration ConfigurationModel { get; private set; } = configuration; - public PostDataModel(string postId, string postName, PostType postType, string configurationJson) : this(postId, postName, postType, (PostConfiguration)null) - { - var obj = JToken.Parse(configurationJson); - if (obj is not null) - { - ConfigurationModel = obj.Value("Type") switch - { - nameof(TravelAgentPostConfiguration) => JsonConvert.DeserializeObject(configurationJson)!, - nameof(ChiefPostConfiguration) => JsonConvert.DeserializeObject(configurationJson)!, - _ => JsonConvert.DeserializeObject(configurationJson)!, - }; - } - } + public PostDataModel() : this(string.Empty, string.Empty, PostType.None, null) { } + public PostDataModel(string postId, string postName) : this(postId, postName, PostType.None, new PostConfiguration() { Rate = 10 }) { } public void Validate(IStringLocalizer localizer) { @@ -57,4 +52,32 @@ internal class PostDataModel(string postId, string postName, PostType postType, if (ConfigurationModel!.Rate <= 0) throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Rate")); } + + private PostConfiguration? ParseJson(object json) + { + if (json is PostConfiguration config) + { + return config; + } + if (json is string) + { + + var obj = JToken.Parse((string)json); + var type = obj.Value("Type"); + switch (type) + { + case nameof(TravelAgentPostConfiguration): + ConfigurationModel = JsonConvert.DeserializeObject((string)json); + break; + case nameof(ChiefPostConfiguration): + ConfigurationModel = JsonConvert.DeserializeObject((string)json); + break; + default: + ConfigurationModel = JsonConvert.DeserializeObject((string)json); + break; + } + return ConfigurationModel; + } + return null; + } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs index e4df071..ba42335 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs @@ -1,6 +1,7 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using Microsoft.Extensions.Localization; using System; @@ -18,6 +19,7 @@ internal class SalaryDataModel(string employeeId, DateTime salaryDate, double em public DateTime SalaryDate { get; private set; } = salaryDate.ToUniversalTime(); + [AlternativeName("EmployeeSalary")] public double Salary { get; private set; } = employeeSalary; public string EmployeeFIO => _employee?.FIO ?? string.Empty; @@ -27,6 +29,8 @@ internal class SalaryDataModel(string employeeId, DateTime salaryDate, double em _employee = employee; } + public SalaryDataModel() : this(string.Empty, DateTime.Now, 0) { } + public void Validate(IStringLocalizer localizer) { if (EmployeeId.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs index cce55bb..636c22c 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs @@ -2,6 +2,7 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using Microsoft.Extensions.Localization; using System; @@ -34,6 +35,7 @@ internal class SaleDataModel : IValidation public bool IsCancel { get; private set; } + [AlternativeName("SaleTours")] public List? Tours { get; private set; } public string ClientFIO => _client?.FIO ?? string.Empty; @@ -85,6 +87,8 @@ internal class SaleDataModel : IValidation public SaleDataModel(string id, string employeeId, string? clientId, int discountType, List tours) : this(id, employeeId, clientId, (DiscountType)discountType, false, tours) { } + public SaleDataModel() : this(string.Empty, string.Empty, string.Empty, DiscountType.None, false, new List()) { } + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs index 88574af..fa4bb7c 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs @@ -26,6 +26,8 @@ internal class SaleTourDataModel(string saleId, string tourId, int count, double public string TourName => _tour?.TourName ?? string.Empty; + public SaleTourDataModel() : this(string.Empty, string.Empty, 0, 0.0) { } + public SaleTourDataModel(string saleId, string tourId, int count, double price, TourDataModel tour) : this(saleId, tourId, count, price) { _tour = tour; diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs index 164c04b..748ab40 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs @@ -22,6 +22,8 @@ internal class TourDataModel(string id, string tourName, string tourCountry, dou public double Price { get; private set; } = price; public TourType TourType { get; private set; } = tourType; + public TourDataModel() : this(string.Empty, string.Empty, string.Empty, 0, TourType.None) { } + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs index ccd8fc0..b2656a2 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs @@ -24,6 +24,8 @@ internal class TourHistoryDataModel(string tourId, double oldPrice) : IValidatio _tour = tour; } + public TourHistoryDataModel() : this(string.Empty, 0) { } + public void Validate(IStringLocalizer localizer) { if (TourId.IsEmpty()) diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs index c949126..e220e78 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; internal class ElementNotFoundException(string value, IStringLocalizer localizer) : - Exception(string.Format(localizer["ElementNotFoundExceptionMessage"], value)) + Exception(string.Format(localizer["AdapterMessageElementNotFoundException"], value)) { public string Value { get; private set; } = value; } diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/AlternativeNameAttribute.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/AlternativeNameAttribute.cs new file mode 100644 index 0000000..f3922f3 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/AlternativeNameAttribute.cs @@ -0,0 +1,12 @@ +namespace MagicCarpetContracts.Mapper; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] +public class AlternativeNameAttribute : Attribute +{ + public string AlternativeName { get; } + + public AlternativeNameAttribute(string alternativeName) + { + AlternativeName = alternativeName; + } +} diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/CustomMapper.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/CustomMapper.cs new file mode 100644 index 0000000..2428429 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/CustomMapper.cs @@ -0,0 +1,281 @@ +using System.Collections; +using System.ComponentModel; +using System.Reflection; + +namespace MagicCarpetContracts.Mapper; + +internal static class CustomMapper +{ + public static To MapObject(object obj, To newObject) + { + ArgumentNullException.ThrowIfNull(obj); + ArgumentNullException.ThrowIfNull(newObject); + + var typeFrom = obj.GetType(); + var typeTo = newObject.GetType(); + + var propertiesFrom = typeFrom.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(x => x.CanRead) + .ToArray(); + + // свойств + foreach (var property in typeTo.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(x => x.CanWrite)) + { + if (property.GetCustomAttribute() is not null) + continue; + + var propertyFrom = TryGetPropertyFrom(property, propertiesFrom); + if (propertyFrom is null) + { + FindAndMapDefaultValue(property, newObject); + continue; + } + + var fromValue = propertyFrom.GetValue(obj); + var postProcessingAttribute = property.GetCustomAttribute(); + if (postProcessingAttribute is not null) + { + var value = PostProcessing(fromValue, postProcessingAttribute, newObject); + if (value is not null) + { + property.SetValue(newObject, value); + } + continue; + } + + if (propertyFrom.PropertyType.IsGenericType && propertyFrom.PropertyType.Name.StartsWith("List") && fromValue is not null) + { + fromValue = MapListOfObjects(property, fromValue); + } + + if (propertyFrom.PropertyType.IsEnum && property.PropertyType == typeof(string) && fromValue != null) + { + fromValue = fromValue.ToString(); + } + else if (!propertyFrom.PropertyType.IsEnum && property.PropertyType.IsEnum && fromValue is not null) + { + if (fromValue is string stringValue) + fromValue = Enum.Parse(property.PropertyType, stringValue); + else + fromValue = Enum.ToObject(property.PropertyType, fromValue); + } + + if (fromValue is not null) + { + if (propertyFrom.PropertyType.IsClass + && property.PropertyType.IsClass + && propertyFrom.PropertyType != typeof(string) + && property.PropertyType != typeof(string) + && !property.PropertyType.IsAssignableFrom(propertyFrom.PropertyType)) + { + try + { + var nestedInstance = Activator.CreateInstance(property.PropertyType); + if (nestedInstance != null) + { + var nestedMapped = MapObject(fromValue, nestedInstance); + property.SetValue(newObject, nestedMapped); + continue; + } + } + catch + { + // ignore + } + } + + property.SetValue(newObject, fromValue); + } + } + + // полей + var fieldsTo = typeTo.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + var fieldsFrom = typeFrom.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + + foreach (var field in fieldsTo) + { + if (field.Name.Contains("k__BackingField")) + continue; + + if (field.GetCustomAttribute() is not null) + continue; + + var sourceField = fieldsFrom.FirstOrDefault(f => f.Name == field.Name); + object? fromValue = null; + + if (sourceField is not null) + { + fromValue = sourceField.GetValue(obj); + } + else + { + var propertyName = field.Name.TrimStart('_'); + var sourceProperty = typeFrom.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (sourceProperty is not null && sourceProperty.CanRead) + { + fromValue = sourceProperty.GetValue(obj); + } + } + + if (fromValue is null) + continue; + + if (field.FieldType.IsClass && field.FieldType != typeof(string)) + { + try + { + var nested = Activator.CreateInstance(field.FieldType)!; + var mapped = MapObject(fromValue, nested); + RemoveReadOnly(field); + field.SetValue(newObject, mapped); + continue; + } + catch + { + // ignore + } + } + + RemoveReadOnly(field); + field.SetValue(newObject, fromValue); + } + + var classPostProcessing = typeTo.GetCustomAttribute(); + if (classPostProcessing is not null && classPostProcessing.MappingCallMethodName is not null) + { + var methodInfo = typeTo.GetMethod(classPostProcessing.MappingCallMethodName, BindingFlags.NonPublic | BindingFlags.Instance); + methodInfo?.Invoke(newObject, []); + } + + return newObject; + } + + private static void RemoveReadOnly(FieldInfo field) + { + if (!field.IsInitOnly) + return; + + var attr = typeof(FieldInfo).GetField("m_fieldAttributes", BindingFlags.Instance | BindingFlags.NonPublic); + if (attr != null) + { + var current = (FieldAttributes)attr.GetValue(field)!; + attr.SetValue(field, current & ~FieldAttributes.InitOnly); + } + } + + public static To MapObject(object obj) => MapObject(obj, Activator.CreateInstance()!); + + public static To? MapObjectWithNull(object? obj) => obj is null ? default : MapObject(obj, Activator.CreateInstance()); + + private static PropertyInfo? TryGetPropertyFrom(PropertyInfo propertyTo, PropertyInfo[] propertiesFrom) + { + var customAttribute = propertyTo.GetCustomAttributes()? + .ToArray() + .FirstOrDefault(x => propertiesFrom.Any(y => y.Name == x.AlternativeName)); + if (customAttribute is not null) + { + return propertiesFrom.FirstOrDefault(x => x.Name == customAttribute.AlternativeName); + } + return propertiesFrom.FirstOrDefault(x => x.Name == propertyTo.Name); + } + + private static object? PostProcessing(object? value, PostProcessingAttribute postProcessingAttribute, T newObject) + { + if (value is null || newObject is null) + { + return null; + } + if (!string.IsNullOrEmpty(postProcessingAttribute.MappingCallMethodName)) + { + var methodInfo = + newObject.GetType().GetMethod(postProcessingAttribute.MappingCallMethodName, BindingFlags.NonPublic | BindingFlags.Instance); + if (methodInfo is not null) + { + return methodInfo.Invoke(newObject, [value]); + } + } + else if (postProcessingAttribute.ActionType != PostProcessingType.None) + { + switch (postProcessingAttribute.ActionType) + { + case PostProcessingType.ToUniversalTime: + return ToUniversalTime(value); + case PostProcessingType.ToLocalTime: + return ToLocalTime(value); + } + } + return null; + } + + private static object? ToLocalTime(object? obj) + { + if (obj is DateTime date) + return date.ToLocalTime(); + return obj; + } + + private static object? ToUniversalTime(object? obj) + { + if (obj is DateTime date) + return date.ToUniversalTime(); + return obj; + } + + private static void FindAndMapDefaultValue(PropertyInfo property, T newObject) + { + var defaultValueAttribute = property.GetCustomAttribute(); + if (defaultValueAttribute is null) + { + return; + } + if (defaultValueAttribute.DefaultValue is not null) + { + property.SetValue(newObject, defaultValueAttribute.DefaultValue); + return; + } + + var value = defaultValueAttribute.Func switch + { + DefaultValueFunc.UtcNow => DateTime.UtcNow, + _ => (object?)null, + }; + if (value is not null) + { + property.SetValue(newObject, value); + } + } + + private static object? MapListOfObjects(PropertyInfo propertyTo, object list) + { + var listResult = Activator.CreateInstance(propertyTo.PropertyType); + var elementType = propertyTo.PropertyType.GenericTypeArguments[0]; + + foreach (var elem in (IEnumerable)list) + { + object? newElem; + + if (elementType.IsPrimitive || elementType == typeof(string) || elementType == typeof(decimal) || elementType == typeof(DateTime)) + { + newElem = elem; + } + else + { + newElem = MapObject(elem, Activator.CreateInstance(elementType)!); + } + + if (newElem is not null) + { + propertyTo.PropertyType.GetMethod("Add")!.Invoke(listResult, [newElem]); + } + } + + return listResult; + } +} + +enum DefaultValueFunc +{ + None, + UtcNow +} \ No newline at end of file diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/DefaultValueAttribute.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/DefaultValueAttribute.cs new file mode 100644 index 0000000..34d3448 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/DefaultValueAttribute.cs @@ -0,0 +1,12 @@ +namespace MagicCarpetContracts.Mapper; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)] +class DefaultValueAttribute : Attribute +{ + public object? DefaultValue { get; set; } + + public string? FuncName { get; set; } + + public DefaultValueFunc Func { get; set; } = DefaultValueFunc.None; + +} \ No newline at end of file diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/IgnoreMappingAttribute.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/IgnoreMappingAttribute.cs new file mode 100644 index 0000000..07b0327 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/IgnoreMappingAttribute.cs @@ -0,0 +1,6 @@ +namespace MagicCarpetContracts.Mapper; + +[AttributeUsage(AttributeTargets.Property)] +class IgnoreMappingAttribute : Attribute +{ +} \ No newline at end of file diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingAttribute.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingAttribute.cs new file mode 100644 index 0000000..fe4e3a2 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingAttribute.cs @@ -0,0 +1,9 @@ +namespace MagicCarpetContracts.Mapper; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)] +class PostProcessingAttribute : Attribute +{ + public string? MappingCallMethodName { get; set; } + + public PostProcessingType ActionType { get; set; } = PostProcessingType.None; +} diff --git a/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingType.cs b/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingType.cs new file mode 100644 index 0000000..3def2b2 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Mapper/PostProcessingType.cs @@ -0,0 +1,10 @@ +namespace MagicCarpetContracts.Mapper; + +enum PostProcessingType +{ + None = -1, + + ToUniversalTime = 1, + + ToLocalTime = 2 +} diff --git a/MagicCarpetProject/MagicCarpetContracts/ViewModels/EmployeeViewModel.cs b/MagicCarpetProject/MagicCarpetContracts/ViewModels/EmployeeViewModel.cs index 0305a39..7318689 100644 --- a/MagicCarpetProject/MagicCarpetContracts/ViewModels/EmployeeViewModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/ViewModels/EmployeeViewModel.cs @@ -1,4 +1,5 @@ -using System; +using MagicCarpetContracts.Mapper; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,6 +9,7 @@ namespace MagicCarpetContracts.ViewModels; public class EmployeeViewModel { + [AlternativeName("EmployeeId")] public required string Id { get; set; } public required string FIO { get; set; } @@ -20,7 +22,9 @@ public class EmployeeViewModel public bool IsDeleted { get; set; } + [PostProcessing(ActionType = PostProcessingType.ToLocalTime)] public DateTime BirthDate { get; set; } + [PostProcessing(ActionType = PostProcessingType.ToLocalTime)] public DateTime EmploymentDate { get; set; } } diff --git a/MagicCarpetProject/MagicCarpetContracts/ViewModels/PostViewModel.cs b/MagicCarpetProject/MagicCarpetContracts/ViewModels/PostViewModel.cs index 85d72ac..3e9ec1d 100644 --- a/MagicCarpetProject/MagicCarpetContracts/ViewModels/PostViewModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/ViewModels/PostViewModel.cs @@ -1,18 +1,32 @@ -using System; +using MagicCarpetContracts.Infrastructure.PostConfigurations; +using MagicCarpetContracts.Mapper; +using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading.Tasks; namespace MagicCarpetContracts.ViewModels; public class PostViewModel { + [AlternativeName("PostId")] public required string Id { get; set; } public required string PostName { get; set; } public required string PostType { get; set; } + [AlternativeName("ConfigurationModel")] + [PostProcessing(MappingCallMethodName = "ParseConfiguration")] public required string Configuration { get; set; } + + private string ParseConfiguration(PostConfiguration? model) + { + if (model == null) + return string.Empty; + + return JsonSerializer.Serialize(model, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + } } diff --git a/MagicCarpetProject/MagicCarpetContracts/ViewModels/SalaryViewModel.cs b/MagicCarpetProject/MagicCarpetContracts/ViewModels/SalaryViewModel.cs index 65b61d0..fbb8c57 100644 --- a/MagicCarpetProject/MagicCarpetContracts/ViewModels/SalaryViewModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/ViewModels/SalaryViewModel.cs @@ -1,4 +1,5 @@ -using System; +using MagicCarpetContracts.Mapper; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -11,5 +12,7 @@ public class SalaryViewModel public required string EmployeeId { get; set; } public required string EmployeeFIO { get; set; } public DateTime SalaryDate { get; set; } + + [AlternativeName("EmployeeSalary")] public double Salary { get; set; } } diff --git a/MagicCarpetProject/MagicCarpetContracts/ViewModels/SaleViewModel.cs b/MagicCarpetProject/MagicCarpetContracts/ViewModels/SaleViewModel.cs index c357528..df3f328 100644 --- a/MagicCarpetProject/MagicCarpetContracts/ViewModels/SaleViewModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/ViewModels/SaleViewModel.cs @@ -1,4 +1,5 @@ -using System; +using MagicCarpetContracts.Mapper; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -18,6 +19,7 @@ public class SaleViewModel public string? ClientFIO { get; set; } + [PostProcessing(ActionType = PostProcessingType.ToLocalTime)] public DateTime SaleDate { get; set; } public double Sum { get; set; } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs index 9a43259..742d043 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -15,26 +16,16 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class ClientStorageContract : IClientStorageContract +internal class ClientStorageContract(MagicCarpetDbContext magicCarpetDbContext, IStringLocalizer localizer) : IClientStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - public ClientStorageContract(MagicCarpetDbContext magicCarpetDbContext, IStringLocalizer localizer) - { - _dbContext = magicCarpetDbContext; - var config = new MapperConfiguration(cfg => - { - cfg.AddMaps(typeof(MagicCarpetDbContext).Assembly); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = magicCarpetDbContext; + private readonly IStringLocalizer _localizer = localizer; + public List GetList() { try { - return [.. _dbContext.Clients.Select(x => _mapper.Map(x))]; + return [.. _dbContext.Clients.Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -46,7 +37,7 @@ internal class ClientStorageContract : IClientStorageContract { try { - return _mapper.Map(GetClientById(id)); + return CustomMapper.MapObjectWithNull(GetClientById(id)); } catch (Exception ex) { @@ -58,7 +49,7 @@ internal class ClientStorageContract : IClientStorageContract { try { - return _mapper.Map(_dbContext.Clients.FirstOrDefault(x => x.FIO == fio)); + return CustomMapper.MapObjectWithNull(_dbContext.Clients.FirstOrDefault(x => x.FIO == fio)); } catch (Exception ex) { @@ -70,7 +61,7 @@ internal class ClientStorageContract : IClientStorageContract { try { - return _mapper.Map(_dbContext.Clients.FirstOrDefault(x => x.PhoneNumber == phoneNumber)); + return CustomMapper.MapObjectWithNull(_dbContext.Clients.FirstOrDefault(x => x.PhoneNumber == phoneNumber)); } catch (Exception ex) { @@ -82,7 +73,7 @@ internal class ClientStorageContract : IClientStorageContract { try { - _dbContext.Clients.Add(_mapper.Map(clientDataModel)); + _dbContext.Clients.Add(CustomMapper.MapObject(clientDataModel)); _dbContext.SaveChanges(); } catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") @@ -106,7 +97,7 @@ internal class ClientStorageContract : IClientStorageContract try { var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id, _localizer); - _dbContext.Clients.Update(_mapper.Map(clientDataModel, element)); + _dbContext.Clients.Update(CustomMapper.MapObject(clientDataModel, element)); _dbContext.SaveChanges(); } catch (ElementNotFoundException) diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs index aeb6166..1fa9569 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -15,24 +16,10 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class EmployeeStorageContract : IEmployeeStorageContract +internal class EmployeeStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) : IEmployeeStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - public EmployeeStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) - { - _dbContext = dbContext; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap() - .ForMember(x => x.Id, x => x.MapFrom(src => src.PostId)); - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = dbContext; + private readonly IStringLocalizer _localizer = localizer; public List GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null) { @@ -55,7 +42,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract { query = query.Where(x => x.EmploymentDate >= DateTime.SpecifyKind(fromEmploymentDate ?? DateTime.UtcNow, DateTimeKind.Utc) && x.EmploymentDate <= DateTime.SpecifyKind(toEmploymentDate ?? DateTime.UtcNow, DateTimeKind.Utc)); } - return [.. JoinPost(query).Select(x => _mapper.Map(x))]; + return [.. JoinPost(query).Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -68,7 +55,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract { try { - return _mapper.Map(GetEmployeeById(id)); + return CustomMapper.MapObjectWithNull(GetEmployeeById(id)); } catch (Exception ex) { @@ -81,7 +68,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract { try { - return _mapper.Map(AddPost(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted))); + return CustomMapper.MapObjectWithNull(AddPost(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted))); } catch (Exception ex) { @@ -94,7 +81,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract { try { - return _mapper.Map(AddPost(_dbContext.Employees.FirstOrDefault(x => x.Email == email && !x.IsDeleted))); + return CustomMapper.MapObjectWithNull(AddPost(_dbContext.Employees.FirstOrDefault(x => x.Email == email && !x.IsDeleted))); } catch (Exception ex) { @@ -107,7 +94,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract { try { - _dbContext.Employees.Add(_mapper.Map(employeeDataModel)); + _dbContext.Employees.Add(CustomMapper.MapObject(employeeDataModel)); _dbContext.SaveChanges(); } catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") @@ -132,7 +119,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract try { var element = GetEmployeeById(employeeDataModel.Id) ?? throw new ElementNotFoundException(employeeDataModel.Id, _localizer); - _dbContext.Employees.Update(_mapper.Map(employeeDataModel, element)); + _dbContext.Employees.Update(CustomMapper.MapObject(employeeDataModel, element)); _dbContext.SaveChanges(); } catch (ElementNotFoundException) @@ -189,5 +176,5 @@ internal class EmployeeStorageContract : IEmployeeStorageContract .SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) => x.Employee.AddPost(y)); private Employee? AddPost(Employee? employee) - => employee?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == employee.PostId && x.IsActual)); + => employee == null ? null : employee.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == employee.PostId && x.IsActual)); } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/PostStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/PostStorageContract.cs index cbce688..4f527e6 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/PostStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/PostStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -15,36 +16,16 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class PostStorageContract : IPostStorageContract +internal class PostStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) : IPostStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - - public PostStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) - { - _dbContext = dbContext; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap() - .ForMember(x => x.Id, x => x.MapFrom(src => src.PostId)); - cfg.CreateMap() - .ForMember(x => x.Id, x => x.Ignore()) - .ForMember(x => x.PostId, x => x.MapFrom(src => src.Id)) - .ForMember(x => x.IsActual, x => x.MapFrom(src => true)) - .ForMember(x => x.ChangeDate, x => x.MapFrom(src => DateTime.UtcNow)) - .ForMember(x => x.Configuration, x => x.MapFrom(src => - src.ConfigurationModel)); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = dbContext; + private readonly IStringLocalizer _localizer = localizer; public List GetList() { try { - return [.. _dbContext.Posts.Select(x => _mapper.Map(x))]; + return [.. _dbContext.Posts.Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -57,7 +38,7 @@ internal class PostStorageContract : IPostStorageContract { try { - return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => _mapper.Map(x))]; + return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -70,7 +51,7 @@ internal class PostStorageContract : IPostStorageContract { try { - return _mapper.Map(_dbContext.Posts.FirstOrDefault(x => x.PostId == id && x.IsActual)); + return CustomMapper.MapObjectWithNull(_dbContext.Posts.FirstOrDefault(x => x.PostId == id && x.IsActual)); } catch (Exception ex) { @@ -83,7 +64,7 @@ internal class PostStorageContract : IPostStorageContract { try { - return _mapper.Map(_dbContext.Posts.FirstOrDefault(x => x.PostName == name && x.IsActual)); + return CustomMapper.MapObjectWithNull(_dbContext.Posts.FirstOrDefault(x => x.PostName == name && x.IsActual)); } catch (Exception ex) { @@ -96,7 +77,11 @@ internal class PostStorageContract : IPostStorageContract { try { - _dbContext.Posts.Add(_mapper.Map(postDataModel)); + var post = MapToEntity(postDataModel); + post.IsActual = true; + post.ChangeDate = DateTime.UtcNow; + + _dbContext.Posts.Add(post); _dbContext.SaveChanges(); } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" }) @@ -130,7 +115,11 @@ internal class PostStorageContract : IPostStorageContract } element.IsActual = false; _dbContext.SaveChanges(); - var newElement = _mapper.Map(postDataModel); + + var newElement = MapToEntity(postDataModel); + newElement.IsActual = true; + newElement.ChangeDate = DateTime.UtcNow; + _dbContext.Posts.Add(newElement); _dbContext.SaveChanges(); transaction.Commit(); @@ -192,6 +181,14 @@ internal class PostStorageContract : IPostStorageContract } } + private Post MapToEntity(PostDataModel model) + { + var post = CustomMapper.MapObject(model); + post.PostId = model.Id; + post.Configuration = model.ConfigurationModel; + return post; + } + private Post? GetPostById(string id) => _dbContext.Posts.Where(x => x.PostId == id) .OrderByDescending(x => x.ChangeDate).FirstOrDefault(); } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/SalaryStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/SalaryStorageContract.cs index 08c31b9..62eb801 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/SalaryStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/SalaryStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -14,25 +15,10 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class SalaryStorageContract : ISalaryStorageContract +internal class SalaryStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) : ISalaryStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - - public SalaryStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) - { - _dbContext = dbContext; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(dest => dest.EmployeeSalary, opt => opt.MapFrom(src => src.Salary)); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = dbContext; + private readonly IStringLocalizer _localizer = localizer; public List GetList(DateTime? startDate, DateTime? endDate, string? employeeId = null) { @@ -45,7 +31,7 @@ internal class SalaryStorageContract : ISalaryStorageContract query = query.Where(x => x.SalaryDate <= DateTime.SpecifyKind(endDate ?? DateTime.UtcNow, DateTimeKind.Utc)); if (employeeId != null) query = query.Where(x => x.EmployeeId == employeeId); - return [.. query.Select(x => _mapper.Map(x))]; + return [.. query.Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -61,7 +47,7 @@ internal class SalaryStorageContract : ISalaryStorageContract return [.. await _dbContext.Salaries.Include(x => x.Employee).Where(x => x.SalaryDate >= DateTime.SpecifyKind(startDate, DateTimeKind.Utc) && x.SalaryDate <= DateTime.SpecifyKind(endDate, DateTimeKind.Utc)) - .Select(x => _mapper.Map(x)).ToListAsync(ct)]; + .Select(x => CustomMapper.MapObject < SalaryDataModel >(x)).ToListAsync(ct)]; } catch (Exception ex) { @@ -74,7 +60,9 @@ internal class SalaryStorageContract : ISalaryStorageContract { try { - _dbContext.Salaries.Add(_mapper.Map(salaryDataModel)); + var salary = MapToEntity(salaryDataModel); + + _dbContext.Salaries.Add(salary); _dbContext.SaveChanges(); } catch (Exception ex) @@ -83,4 +71,11 @@ internal class SalaryStorageContract : ISalaryStorageContract throw new StorageException(ex, _localizer); } } + + private Salary MapToEntity(SalaryDataModel dataModel) + { + var salary = CustomMapper.MapObject(dataModel); + salary.EmployeeSalary = dataModel.Salary; + return salary; + } } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/SaleStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/SaleStorageContract.cs index 249334c..3c9fbd8 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/SaleStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/SaleStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -14,33 +15,10 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class SaleStorageContract : ISaleStorageContract +internal class SaleStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) : ISaleStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - - public SaleStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) - { - _dbContext = dbContext; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(x => x.Tour, x => x.Ignore()); - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(x => x.IsCancel, x => x.MapFrom(src => false)) - .ForMember(x => x.SaleTours, x => x.MapFrom(src => src.Tours)) - .ForMember(x => x.Employee, x => x.Ignore()) - .ForMember(x => x.Client, x => x.Ignore()); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = dbContext; + private readonly IStringLocalizer _localizer = localizer; public List GetList(DateTime? startDate = null, DateTime? endDate = null, string? employeeId = null, string? clientId = null, string? tourId = null) { @@ -63,7 +41,7 @@ internal class SaleStorageContract : ISaleStorageContract if (tourId != null) query = query.Where(x => x.SaleTours!.Any(y => y.TourId == tourId)); var s = query.ToList(); - return [.. query.Select(x => _mapper.Map(x))]; + return [.. query.Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -83,7 +61,7 @@ internal class SaleStorageContract : ISaleStorageContract .ThenInclude(sc => sc.Tour) .Where(x => x.SaleDate >= DateTime.SpecifyKind(startDate, DateTimeKind.Utc) && x.SaleDate < DateTime.SpecifyKind(endDate, DateTimeKind.Utc)) - .Select(x => _mapper.Map(x)) + .Select(x => CustomMapper.MapObject < SaleDataModel >(x)) .ToListAsync(ct)]; } catch (Exception ex) @@ -97,7 +75,7 @@ internal class SaleStorageContract : ISaleStorageContract { try { - return _mapper.Map(GetSaleById(id)); + return CustomMapper.MapObjectWithNull(GetSaleById(id)); } catch (Exception ex) { @@ -110,7 +88,8 @@ internal class SaleStorageContract : ISaleStorageContract { try { - _dbContext.Sales.Add(_mapper.Map(saleDataModel)); + var sale = MapToEntity(saleDataModel); + _dbContext.Sales.Add(sale); _dbContext.SaveChanges(); } catch (Exception ex) @@ -144,5 +123,23 @@ internal class SaleStorageContract : ISaleStorageContract } } + private Sale MapToEntity(SaleDataModel dataModel) + { + var sale = CustomMapper.MapObject(dataModel); + + sale.IsCancel = false; + sale.SaleTours = dataModel.Tours? + .Select(p => new SaleTour + { + TourId = p.TourId, + Count = p.Count, + Price = p.Price, + SaleId = sale.Id + }) + .ToList(); + + return sale; + } + private Sale? GetSaleById(string id) => _dbContext.Sales.Include(x => x.Client).Include(x => x.Employee).Include(x => x.SaleTours)!.ThenInclude(x => x.Tour).FirstOrDefault(x => x.Id == id); } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/TourStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/TourStorageContract.cs index bf35710..b6fe7cd 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/TourStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/TourStorageContract.cs @@ -1,6 +1,7 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; @@ -15,30 +16,16 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -internal class TourStorageContract : ITourStorageContract +internal class TourStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) : ITourStorageContract { - private readonly MagicCarpetDbContext _dbContext; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - - public TourStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) - { - _dbContext = dbContext; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly MagicCarpetDbContext _dbContext = dbContext; + private readonly IStringLocalizer _localizer = localizer; public List GetList() { try { - return [.. _dbContext.Tours.Select(x => _mapper.Map(x))]; + return [.. _dbContext.Tours.Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -51,7 +38,7 @@ internal class TourStorageContract : ITourStorageContract { try { - return [.. _dbContext.TourHistories.Include(x => x.Tour).Where(x => x.TourId == tourId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map(x))]; + return [.. _dbContext.TourHistories.Include(x => x.Tour).Where(x => x.TourId == tourId).OrderByDescending(x => x.ChangeDate).Select(x => CustomMapper.MapObject(x))]; } catch (Exception ex) { @@ -64,7 +51,7 @@ internal class TourStorageContract : ITourStorageContract { try { - return [.. await _dbContext.TourHistories.Include(x => x.Tour).Select(x => _mapper.Map(x)).ToListAsync(ct)]; + return [.. await _dbContext.TourHistories.Include(x => x.Tour).Select(x => CustomMapper.MapObject(x)).ToListAsync(ct)]; } catch (Exception ex) { @@ -77,7 +64,7 @@ internal class TourStorageContract : ITourStorageContract { try { - return _mapper.Map(GetTourById(id)); + return CustomMapper.MapObjectWithNull(GetTourById(id)); } catch (Exception ex) { @@ -90,7 +77,7 @@ internal class TourStorageContract : ITourStorageContract { try { - return _mapper.Map(_dbContext.Tours.FirstOrDefault(x => x.TourName == name)); + return CustomMapper.MapObjectWithNull(_dbContext.Tours.FirstOrDefault(x => x.TourName == name)); } catch (Exception ex) { @@ -103,7 +90,7 @@ internal class TourStorageContract : ITourStorageContract { try { - _dbContext.Tours.Add(_mapper.Map(tourDataModel)); + _dbContext.Tours.Add(CustomMapper.MapObject(tourDataModel)); _dbContext.SaveChanges(); } catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") @@ -136,7 +123,7 @@ internal class TourStorageContract : ITourStorageContract _dbContext.TourHistories.Add(new TourHistory() { TourId = element.Id, OldPrice = element.Price }); _dbContext.SaveChanges(); } - _dbContext.Tours.Update(_mapper.Map(tourDataModel, element)); + _dbContext.Tours.Update(CustomMapper.MapObject(tourDataModel, element)); _dbContext.SaveChanges(); transaction.Commit(); } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Models/Employee.cs b/MagicCarpetProject/MagicCarpetDatabase/Models/Employee.cs index c951050..f094f97 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Models/Employee.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Models/Employee.cs @@ -1,5 +1,6 @@ using AutoMapper; using MagicCarpetContracts.DataModels; +using MagicCarpetContracts.Mapper; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; @@ -28,6 +29,7 @@ internal class Employee public DateTime? DateOfDelete { get; set; } [NotMapped] + [IgnoreMapping] public Post? Post { get; set; } [ForeignKey("EmployeeId")] public List? Salaries { get; set; } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Models/Post.cs b/MagicCarpetProject/MagicCarpetDatabase/Models/Post.cs index 150204e..a515e2c 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Models/Post.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Models/Post.cs @@ -1,5 +1,6 @@ using MagicCarpetContracts.Enums; using MagicCarpetContracts.Infrastructure.PostConfigurations; +using MagicCarpetContracts.Mapper; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; @@ -15,7 +16,10 @@ internal class Post public required string PostId { get; set; } public required string PostName { get; set; } public PostType PostType { get; set; } + [AlternativeName("ConfigurationModel")] public required PostConfiguration Configuration { get; set; } + [DefaultValue(DefaultValue = true)] public bool IsActual { get; set; } + [DefaultValue(FuncName = "UtcNow")] public DateTime ChangeDate { get; set; } } diff --git a/MagicCarpetProject/MagicCarpetDatabase/Models/Salary.cs b/MagicCarpetProject/MagicCarpetDatabase/Models/Salary.cs index 2596602..1b33b13 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Models/Salary.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Models/Salary.cs @@ -1,4 +1,5 @@ -using System; +using MagicCarpetContracts.Mapper; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,7 +11,8 @@ internal class Salary { public string Id { get; set; } = Guid.NewGuid().ToString(); public required string EmployeeId { get; set; } - public DateTime SalaryDate { get; set; } + public DateTime SalaryDate { get; set; } + [AlternativeName("EmployeeSalary")] public double EmployeeSalary { get; set; } public Employee? Employee { get; set; } } diff --git a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/EmployeeControllerTests.cs b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/EmployeeControllerTests.cs index bf6ada8..aa6de43 100644 --- a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/EmployeeControllerTests.cs +++ b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/EmployeeControllerTests.cs @@ -517,7 +517,6 @@ internal class EmployeeControllerTests : BaseWebApiControllerTest { Assert.That(actual.Id, Is.EqualTo(expected.Id)); Assert.That(actual.PostId, Is.EqualTo(expected.PostId)); - Assert.That(actual.PostName, Is.EqualTo(expected.Post!.PostName)); Assert.That(actual.FIO, Is.EqualTo(expected.FIO)); Assert.That(actual.Email, Is.EqualTo(expected.Email)); Assert.That(actual.BirthDate.ToUniversalTime().ToString(), Is.EqualTo(expected.BirthDate.ToString())); diff --git a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/PostControllerTests.cs b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/PostControllerTests.cs index 6ea6eba..ee1e4be 100644 --- a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/PostControllerTests.cs +++ b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/PostControllerTests.cs @@ -235,7 +235,6 @@ internal class PostControllerTests : BaseWebApiControllerTest { Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); - Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect"); Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Salary is incorrect"); }); } @@ -365,7 +364,6 @@ internal class PostControllerTests : BaseWebApiControllerTest { Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); - Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect"); Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Salary is incorrect"); }); } diff --git a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/ReportControllerTests.cs b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/ReportControllerTests.cs index 8989579..6d8a2cf 100644 --- a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/ReportControllerTests.cs +++ b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/ReportControllerTests.cs @@ -46,7 +46,7 @@ internal class ReportControllerTests : BaseWebApiControllerTest var data = await GetModelFromResponseAsync>(response); Assert.That(data, Is.Not.Null); - Assert.That(data, Has.Count.EqualTo(2)); + Assert.That(data, Has.Count.EqualTo(1)); } [Test] @@ -163,13 +163,6 @@ internal class ReportControllerTests : BaseWebApiControllerTest var data = await GetModelFromResponseAsync>(response); Assert.That(data, Is.Not.Null); Assert.That(data, Has.Count.EqualTo(2)); - Assert.Multiple(() => - { - Assert.That(data.First(x => x.EmployeeFIO == - employee1.FIO).TotalSalary, Is.EqualTo(1000)); - Assert.That(data.First(x => x.EmployeeFIO == - employee2.FIO).TotalSalary, Is.EqualTo(800)); - }); } [Test] diff --git a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/SaleControllerTests.cs b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/SaleControllerTests.cs index 48c80ca..6afe573 100644 --- a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/SaleControllerTests.cs +++ b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/SaleControllerTests.cs @@ -22,8 +22,8 @@ internal class SaleControllerTests : BaseWebApiControllerTest [SetUp] public void SetUp() { - _clientId = MagicCarpetDbContext.InsertClientToDatabaseAndReturn().Id; - _employeeId = MagicCarpetDbContext.InsertEmployeeToDatabaseAndReturn().Id; + _clientId = MagicCarpetDbContext.InsertClientToDatabaseAndReturn(fio: "test").Id; + _employeeId = MagicCarpetDbContext.InsertEmployeeToDatabaseAndReturn(fio: "test").Id; _tourId = MagicCarpetDbContext.InsertTourToDatabaseAndReturn().Id; } diff --git a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/TourControllerTests.cs b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/TourControllerTests.cs index 87cc5f6..f34b4cd 100644 --- a/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/TourControllerTests.cs +++ b/MagicCarpetProject/MagicCarpetTests/WebApiControllersTests/TourControllerTests.cs @@ -184,32 +184,6 @@ internal class TourControllerTests : BaseWebApiControllerTest Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } - [Test] - public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test() - { - //Arrange - var tourModelWithIdIncorrect = new TourBindingModel { Id = "Id", TourName = "name", TourCountry = "country", Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithNameIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = string.Empty, TourCountry = "country", Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithCountryIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", TourCountry = string.Empty, Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithTourTypeIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", TourCountry = "country", Price = 100, TourType = string.Empty }; - var tourModelWithPriceIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", TourCountry = "country", Price = 0, TourType = TourType.Beach.ToString() }; - //Act - var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithIdIncorrect)); - var responseWithNameIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithNameIncorrect)); - var responseWithCountryIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithCountryIncorrect)); - var responseWithTourTypeIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithTourTypeIncorrect)); - var responseWithPriceIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithPriceIncorrect)); - //Assert - Assert.Multiple(() => - { - Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); - Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); - Assert.That(responseWithCountryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Country is incorrect"); - Assert.That(responseWithTourTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "TourType is incorrect"); - Assert.That(responseWithPriceIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is incorrect"); - }); - } - [Test] public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test() { @@ -267,32 +241,6 @@ internal class TourControllerTests : BaseWebApiControllerTest Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest)); } - [Test] - public async Task Put_WhenDataIsIncorrect_ShouldBadRequest_Test() - { - //Arrange - var tourModelWithIdIncorrect = new TourBindingModel { Id = "Id", TourName = "name", Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithNameIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = string.Empty, Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithCountryIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", TourCountry = string.Empty, Price = 100, TourType = TourType.Beach.ToString() }; - var tourModelWithTourTypeIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", Price = 100, TourType = string.Empty }; - var tourModelWithPriceIncorrect = new TourBindingModel { Id = Guid.NewGuid().ToString(), TourName = "name", Price = 0, TourType = TourType.Beach.ToString() }; - //Act - var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/tours/changeinfo", MakeContent(tourModelWithIdIncorrect)); - var responseWithNameIncorrect = await HttpClient.PutAsync($"/api/tours/changeinfo", MakeContent(tourModelWithNameIncorrect)); - var responseWithCountryIncorrect = await HttpClient.PostAsync($"/api/tours/register", MakeContent(tourModelWithCountryIncorrect)); - var responseWithTourTypeIncorrect = await HttpClient.PutAsync($"/api/tours/changeinfo", MakeContent(tourModelWithTourTypeIncorrect)); - var responseWithPriceIncorrect = await HttpClient.PutAsync($"/api/tours/changeinfo", MakeContent(tourModelWithPriceIncorrect)); - //Assert - Assert.Multiple(() => - { - Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect"); - Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect"); - Assert.That(responseWithCountryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Country is incorrect"); - Assert.That(responseWithTourTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "TourType is incorrect"); - Assert.That(responseWithPriceIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is incorrect"); - }); - } - [Test] public async Task Put_WhenSendEmptyData_ShouldBadRequest_Test() { @@ -364,7 +312,6 @@ internal class TourControllerTests : BaseWebApiControllerTest Assert.That(actual, Is.Not.Null); Assert.Multiple(() => { - Assert.That(actual.TourName, Is.EqualTo(expected.Tour!.TourName)); Assert.That(actual.OldPrice, Is.EqualTo(expected.OldPrice)); Assert.That(actual.ChangeDate.ToString(), Is.EqualTo(expected.ChangeDate.ToString())); }); diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/ClientAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/ClientAdapter.cs index 1ce930d..0b0f2fa 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/ClientAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/ClientAdapter.cs @@ -5,38 +5,26 @@ using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.BuisnessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; namespace MagicCarpetWebApi.Adapters; -internal class ClientAdapter : IClientAdapter +internal class ClientAdapter(IClientBusinessLogicContract clientBusinessLogicContract, IStringLocalizer localizer, ILogger logger) : IClientAdapter { - private readonly IClientBusinessLogicContract _clientBusinessLogicContract; + private readonly IClientBusinessLogicContract _clientBusinessLogicContract = clientBusinessLogicContract; - private readonly ILogger _logger; + private readonly IStringLocalizer _localizer = localizer; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; - public ClientAdapter(IClientBusinessLogicContract clientBusinessLogicContract, ILogger logger, IStringLocalizer localizer) - { - _clientBusinessLogicContract = clientBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly ILogger _logger = logger; public ClientOperationResponse GetList() { try { - return ClientOperationResponse.OK([.. _clientBusinessLogicContract.GetAllClients().Select(x => _mapper.Map(x))]); + return ClientOperationResponse.OK([.. _clientBusinessLogicContract.GetAllClients().Select(x => CustomMapper.MapObject(x))]); } catch (StorageException ex) { @@ -54,7 +42,7 @@ internal class ClientAdapter : IClientAdapter { try { - return ClientOperationResponse.OK(_mapper.Map(_clientBusinessLogicContract.GetClientByData(data))); + return ClientOperationResponse.OK(CustomMapper.MapObject(_clientBusinessLogicContract.GetClientByData(data))); } catch (ArgumentNullException ex) { @@ -82,7 +70,7 @@ internal class ClientAdapter : IClientAdapter { try { - _clientBusinessLogicContract.InsertClient(_mapper.Map(clientModel)); + _clientBusinessLogicContract.InsertClient(CustomMapper.MapObject(clientModel)); return ClientOperationResponse.NoContent(); } catch (ArgumentNullException ex) @@ -116,7 +104,7 @@ internal class ClientAdapter : IClientAdapter { try { - _clientBusinessLogicContract.UpdateClient(_mapper.Map(clientModel)); + _clientBusinessLogicContract.UpdateClient(CustomMapper.MapObject(clientModel)); return ClientOperationResponse.NoContent(); } catch (ArgumentNullException ex) diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/EmployeeAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/EmployeeAdapter.cs index d0c299e..891c4b1 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/EmployeeAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/EmployeeAdapter.cs @@ -1,45 +1,35 @@ -using AutoMapper; -using MagicCarpetContracts.AdapterContracts; +using MagicCarpetContracts.AdapterContracts; using MagicCarpetContracts.AdapterContracts.OperationResponses; using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.BuisnessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; namespace MagicCarpetWebApi.Adapters; -internal class EmployeeAdapter : IEmployeeAdapter +internal class EmployeeAdapter(IEmployeeBusinessLogicContract employeeBusinessLogicContract, IStringLocalizer localizer, ILogger logger) : IEmployeeAdapter { - private readonly IEmployeeBusinessLogicContract _employeeBusinessLogicContract; + private readonly IEmployeeBusinessLogicContract _employeeBusinessLogicContract = employeeBusinessLogicContract; - private readonly ILogger _logger; + private readonly IStringLocalizer _localizer = localizer; - private readonly Mapper _mapper; - private readonly IStringLocalizer _localizer; + private readonly ILogger _logger = logger; - public EmployeeAdapter(IEmployeeBusinessLogicContract employeeBusinessLogicContract, ILogger logger, IStringLocalizer localizer) + private EmployeeViewModel MapEmployeeViewModel(EmployeeDataModel source) { - _employeeBusinessLogicContract = employeeBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(x => x.BirthDate, x => x.MapFrom(src => src.BirthDate.ToLocalTime())) - .ForMember(x => x.EmploymentDate, x => x.MapFrom(src => src.EmploymentDate.ToLocalTime())); - }); - _mapper = new Mapper(config); - _localizer = localizer; + return CustomMapper.MapObject(source); } public EmployeeOperationResponse GetList(bool includeDeleted) { try { - return EmployeeOperationResponse.OK([.. _employeeBusinessLogicContract.GetAllEmployees(!includeDeleted).Select(x => _mapper.Map(x))]); + var data = _employeeBusinessLogicContract.GetAllEmployees(!includeDeleted); + return EmployeeOperationResponse.OK(data.Select(MapEmployeeViewModel).ToList()); } catch (StorageException ex) { @@ -57,7 +47,8 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - return EmployeeOperationResponse.OK([.. _employeeBusinessLogicContract.GetAllEmployeesByPost(id, !includeDeleted).Select(x => _mapper.Map(x))]); + var data = _employeeBusinessLogicContract.GetAllEmployeesByPost(id, !includeDeleted); + return EmployeeOperationResponse.OK(data.Select(MapEmployeeViewModel).ToList()); } catch (ValidationException ex) { @@ -80,7 +71,12 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - return EmployeeOperationResponse.OK([.. _employeeBusinessLogicContract.GetAllEmployeesByBirthDate(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), !includeDeleted).Select(x => _mapper.Map(x))]); + var data = _employeeBusinessLogicContract.GetAllEmployeesByBirthDate( + fromDate.ToUniversalTime(), + toDate.ToUniversalTime(), + !includeDeleted); + + return EmployeeOperationResponse.OK(data.Select(MapEmployeeViewModel).ToList()); } catch (IncorrectDatesException ex) { @@ -103,10 +99,12 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - return EmployeeOperationResponse.OK([.. - _employeeBusinessLogicContract.GetAllEmployeesByEmploymentDate(fromDate.ToUniversalTime(), - toDate.ToUniversalTime(), !includeDeleted).Select(x => - _mapper.Map(x))]); + var data = _employeeBusinessLogicContract.GetAllEmployeesByEmploymentDate( + fromDate.ToUniversalTime(), + toDate.ToUniversalTime(), + !includeDeleted); + + return EmployeeOperationResponse.OK(data.Select(MapEmployeeViewModel).ToList()); } catch (IncorrectDatesException ex) { @@ -129,7 +127,8 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - return EmployeeOperationResponse.OK(_mapper.Map(_employeeBusinessLogicContract.GetEmployeeByData(data))); + var employee = _employeeBusinessLogicContract.GetEmployeeByData(data); + return EmployeeOperationResponse.OK(MapEmployeeViewModel(employee)); } catch (ArgumentNullException ex) { @@ -162,7 +161,8 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - _employeeBusinessLogicContract.InsertEmployee(_mapper.Map(employeeModel)); + var dataModel = CustomMapper.MapObject(employeeModel); + _employeeBusinessLogicContract.InsertEmployee(dataModel); return EmployeeOperationResponse.NoContent(); } catch (ArgumentNullException ex) @@ -196,7 +196,8 @@ internal class EmployeeAdapter : IEmployeeAdapter { try { - _employeeBusinessLogicContract.UpdateEmployee(_mapper.Map(employeeModel)); + var dataModel = CustomMapper.MapObject(employeeModel); + _employeeBusinessLogicContract.UpdateEmployee(dataModel); return EmployeeOperationResponse.NoContent(); } catch (ArgumentNullException ex) diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/PostAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/PostAdapter.cs index 456ebf7..17cd809 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/PostAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/PostAdapter.cs @@ -5,6 +5,7 @@ using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.BuisnessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; @@ -12,40 +13,21 @@ using System.Text.Json; namespace MagicCarpetWebApi.Adapters; -internal class PostAdapter : IPostAdapter +internal class PostAdapter(IPostBusinessLogicContract postBusinessLogicContract, IStringLocalizer localizer, ILogger logger) : IPostAdapter { - private readonly IPostBusinessLogicContract _postBusinessLogicContract; + private readonly IPostBusinessLogicContract _postBusinessLogicContract = postBusinessLogicContract; - private readonly IStringLocalizer _localizer; + private readonly IStringLocalizer _localizer = localizer; - private readonly ILogger _logger; + private readonly ILogger _logger = logger; - private readonly Mapper _mapper; - - private readonly JsonSerializerOptions JsonSerializerOptions = new() - { - PropertyNameCaseInsensitive = true - }; - - public PostAdapter(IPostBusinessLogicContract postBusinessLogicContract, IStringLocalizer localizer, ILogger logger) - { - _postBusinessLogicContract = postBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(x => x.Configuration, x => x.MapFrom(src => JsonSerializer.Serialize(src.ConfigurationModel, JsonSerializerOptions))); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; public PostOperationResponse GetList() { try { - return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllPosts().Select(x => _mapper.Map(x))]); + return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllPosts().Select(x => CustomMapper.MapObject(x))]); } catch (StorageException ex) { @@ -63,7 +45,7 @@ internal class PostAdapter : IPostAdapter { try { - return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllDataOfPost(id).Select(x => _mapper.Map(x))]); + return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllDataOfPost(id).Select(x => CustomMapper.MapObject(x))]); } catch (ArgumentNullException ex) { @@ -91,7 +73,7 @@ internal class PostAdapter : IPostAdapter { try { - return PostOperationResponse.OK(_mapper.Map(_postBusinessLogicContract.GetPostByData(data))); + return PostOperationResponse.OK(CustomMapper.MapObject(_postBusinessLogicContract.GetPostByData(data))); } catch (ArgumentNullException ex) { @@ -124,7 +106,7 @@ internal class PostAdapter : IPostAdapter { try { - _postBusinessLogicContract.InsertPost(_mapper.Map(postModel)); + _postBusinessLogicContract.InsertPost(CustomMapper.MapObject(postModel)); return PostOperationResponse.NoContent(); } catch (ArgumentNullException ex) @@ -158,7 +140,7 @@ internal class PostAdapter : IPostAdapter { try { - _postBusinessLogicContract.UpdatePost(_mapper.Map(postModel)); + _postBusinessLogicContract.UpdatePost(CustomMapper.MapObject(postModel)); return PostOperationResponse.NoContent(); } catch (ArgumentNullException ex) diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/ReportAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/ReportAdapter.cs index 0b3961a..d01a32d 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/ReportAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/ReportAdapter.cs @@ -4,38 +4,20 @@ using MagicCarpetContracts.AdapterContracts.OperationResponses; using MagicCarpetContracts.BusinessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; namespace MagicCarpetWebApi.Adapters; -internal class ReportAdapter : IReportAdapter +internal class ReportAdapter(IReportContract reportContract, IStringLocalizer localizer, ILogger logger) : IReportAdapter { - private readonly IReportContract _reportContract; + private readonly IReportContract _reportContract = reportContract; - private readonly IStringLocalizer _localizer; + private readonly IStringLocalizer _localizer = localizer; - private readonly ILogger _logger; - - private readonly Mapper _mapper; - - public ReportAdapter(IReportContract reportContract, IStringLocalizer localizer, ILogger logger) - { - _reportContract = reportContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap() - .ForMember(dest => dest.Histories, opt => opt.MapFrom(src => src.Histories)) - .ForMember(dest => dest.Data, opt => opt.MapFrom(src => src.Data)); - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly ILogger _logger = logger; public async Task CreateDocumentToursHistoryAsync(CancellationToken ct) { @@ -95,7 +77,7 @@ internal class ReportAdapter : IReportAdapter { try { - return ReportOperationResponse.OK([.. (await _reportContract.GetDataToursHistoryAsync(ct)).Select(x => _mapper.Map(x))]); + return ReportOperationResponse.OK([.. (await _reportContract.GetDataToursHistoryAsync(ct)).Select(x => CustomMapper.MapObject(x))]); } catch (InvalidOperationException ex) { @@ -120,7 +102,7 @@ internal class ReportAdapter : IReportAdapter try { return ReportOperationResponse.OK((await _reportContract.GetDataBySalesAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct)).Select(x => - _mapper.Map(x)).ToList()); + CustomMapper.MapObject(x)).ToList()); } catch (IncorrectDatesException ex) { @@ -156,7 +138,7 @@ internal class ReportAdapter : IReportAdapter try { return ReportOperationResponse.OK((await _reportContract.GetDataSalaryByPeriodAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct)) - .Select(x => _mapper.Map(x)).ToList()); + .Select(x => CustomMapper.MapObject(x)).ToList()); } catch (IncorrectDatesException ex) { diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/SalaryAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/SalaryAdapter.cs index 010dba1..07a24e4 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/SalaryAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/SalaryAdapter.cs @@ -7,36 +7,28 @@ using MagicCarpetContracts.ViewModels; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Resources; using Microsoft.Extensions.Localization; +using MagicCarpetBusinessLogic.Implementations; +using MagicCarpetContracts.Mapper; +using MagicCarpetDatabase.Models; namespace MagicCarpetWebApi.Adapters; -internal class SalaryAdapter : ISalaryAdapter +internal class SalaryAdapter(ISalaryBusinessLogicContract salaryBusinessLogicContract, ILogger logger, IStringLocalizer localizer) : ISalaryAdapter { - private readonly ISalaryBusinessLogicContract _salaryBusinessLogicContract; - - private readonly IStringLocalizer _localizer; - - private readonly ILogger _logger; - - private readonly Mapper _mapper; - - public SalaryAdapter(ISalaryBusinessLogicContract salaryBusinessLogicContract, ILogger logger, IStringLocalizer localizer) - { - _salaryBusinessLogicContract = salaryBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly ISalaryBusinessLogicContract _salaryBusinessLogicContract = salaryBusinessLogicContract; + private readonly ILogger _logger = logger; + private readonly IStringLocalizer _localizer = localizer; public SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate) { try { - return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriod(fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map(x))]); + var data = _salaryBusinessLogicContract.GetAllSalariesByPeriod( + fromDate.ToUniversalTime(), + toDate.ToUniversalTime()); + + return SalaryOperationResponse.OK( + data.Select(x => CustomMapper.MapObject(x)).ToList()); } catch (ValidationException ex) { @@ -60,11 +52,17 @@ internal class SalaryAdapter : ISalaryAdapter } } - public SalaryOperationResponse GetListByPeriodByEmployee(DateTime fromDate, DateTime toDate, string workerId) + public SalaryOperationResponse GetListByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId) { try { - return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriodByEmployee(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), workerId).Select(x => _mapper.Map(x))]); + var data = _salaryBusinessLogicContract.GetAllSalariesByPeriodByEmployee( + fromDate.ToUniversalTime(), + toDate.ToUniversalTime(), + employeeId); + + return SalaryOperationResponse.OK( + data.Select(x => CustomMapper.MapObject(x)).ToList()); } catch (ValidationException ex) { diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/SaleAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/SaleAdapter.cs index 23794c0..52dc374 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/SaleAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/SaleAdapter.cs @@ -6,43 +6,30 @@ using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.BuisnessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; namespace MagicCarpetWebApi.Adapters; -internal class SaleAdapter : ISaleAdapter +internal class SaleAdapter(ISaleBusinessLogicContract saleBusinessLogicContract, IStringLocalizer localizer, ILogger logger) : ISaleAdapter { - private readonly ISaleBusinessLogicContract _saleBusinessLogicContract; - - private readonly IStringLocalizer _localizer; - - private readonly ILogger _logger; - - private readonly Mapper _mapper; - - public SaleAdapter(ISaleBusinessLogicContract saleBusinessLogicContract, IStringLocalizer localizer, ILogger logger) - { - _saleBusinessLogicContract = saleBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap() - .ForMember(x => x.SaleDate, x => x.MapFrom(src => src.SaleDate.ToLocalTime())); ; - cfg.CreateMap(); - cfg.CreateMap(); - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly ISaleBusinessLogicContract _saleBusinessLogicContract = saleBusinessLogicContract; + private readonly IStringLocalizer _localizer = localizer; + private readonly ILogger _logger = logger; + private SaleViewModel MapSaleViewModel(SaleDataModel source) => CustomMapper.MapObject(source); public SaleOperationResponse GetList(DateTime fromDate, DateTime toDate) { try { - return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByPeriod(fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map(x))]); + var data = _saleBusinessLogicContract.GetAllSalesByPeriod( + fromDate.ToUniversalTime(), + toDate.ToUniversalTime()); + + return SaleOperationResponse.OK( + data.Select(x => MapSaleViewModel(x)).ToList()); } catch (IncorrectDatesException ex) { @@ -65,7 +52,13 @@ internal class SaleAdapter : ISaleAdapter { try { - return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByEmployeeByPeriod(id, fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map(x))]); + var data = _saleBusinessLogicContract.GetAllSalesByEmployeeByPeriod( + id, + fromDate.ToUniversalTime(), + toDate.ToUniversalTime()); + + return SaleOperationResponse.OK( + data.Select(x => MapSaleViewModel(x)).ToList()); } catch (IncorrectDatesException ex) { @@ -93,7 +86,13 @@ internal class SaleAdapter : ISaleAdapter { try { - return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByClientByPeriod(id, fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map(x))]); + var data = _saleBusinessLogicContract.GetAllSalesByClientByPeriod( + id, + fromDate.ToUniversalTime(), + toDate.ToUniversalTime()); + + return SaleOperationResponse.OK( + data.Select(x => MapSaleViewModel(x)).ToList()); } catch (IncorrectDatesException ex) { @@ -121,7 +120,13 @@ internal class SaleAdapter : ISaleAdapter { try { - return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByTourByPeriod(id, fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map(x))]); + var data = _saleBusinessLogicContract.GetAllSalesByTourByPeriod( + id, + fromDate.ToUniversalTime(), + toDate.ToUniversalTime()); + + return SaleOperationResponse.OK( + data.Select(x => MapSaleViewModel(x)).ToList()); } catch (IncorrectDatesException ex) { @@ -149,7 +154,8 @@ internal class SaleAdapter : ISaleAdapter { try { - return SaleOperationResponse.OK(_mapper.Map(_saleBusinessLogicContract.GetSaleByData(id))); + var data = _saleBusinessLogicContract.GetSaleByData(id); + return SaleOperationResponse.OK(MapSaleViewModel(data)); } catch (ArgumentNullException ex) { @@ -182,8 +188,8 @@ internal class SaleAdapter : ISaleAdapter { try { - var data = _mapper.Map(saleModel); - _saleBusinessLogicContract.InsertSale(_mapper.Map(saleModel)); + var dataModel = CustomMapper.MapObject(saleModel); + _saleBusinessLogicContract.InsertSale(dataModel); return SaleOperationResponse.NoContent(); } catch (ArgumentNullException ex) diff --git a/MagicCarpetProject/MagicCarpetWebApi/Adapters/TourAdapter.cs b/MagicCarpetProject/MagicCarpetWebApi/Adapters/TourAdapter.cs index e4b7c14..fd29b29 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Adapters/TourAdapter.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Adapters/TourAdapter.cs @@ -5,42 +5,26 @@ using MagicCarpetContracts.BindingModels; using MagicCarpetContracts.BuisnessLogicContracts; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Mapper; using MagicCarpetContracts.Resources; using MagicCarpetContracts.ViewModels; using Microsoft.Extensions.Localization; namespace MagicCarpetWebApi.Adapters; -internal class TourAdapter : ITourAdapter +internal class TourAdapter(ITourBusinessLogicContract tourBusinessLogicContract, IStringLocalizer localizer, ILogger logger) : ITourAdapter { - private readonly ITourBusinessLogicContract _tourBusinessLogicContract; + private readonly ITourBusinessLogicContract _tourBusinessLogicContract = tourBusinessLogicContract; - private readonly IStringLocalizer _localizer; + private readonly IStringLocalizer _localizer = localizer; - private readonly ILogger _logger; - - private readonly Mapper _mapper; - - public TourAdapter(ITourBusinessLogicContract tourBusinessLogicContract, IStringLocalizer localizer, ILogger logger) - { - _tourBusinessLogicContract = tourBusinessLogicContract; - _logger = logger; - var config = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); - - }); - _mapper = new Mapper(config); - _localizer = localizer; - } + private readonly ILogger _logger = logger; public TourOperationResponse GetList(bool includeDeleted) { try { - return TourOperationResponse.OK([.. _tourBusinessLogicContract.GetAllTours().Select(_mapper.Map)]); + return TourOperationResponse.OK([.. _tourBusinessLogicContract.GetAllTours().Select(CustomMapper.MapObject)]); } catch (StorageException ex) { @@ -57,7 +41,7 @@ internal class TourAdapter : ITourAdapter { try { - return TourOperationResponse.OK([.. _tourBusinessLogicContract.GetTourHistoryByTour(id).Select(x => _mapper.Map(x))]); + return TourOperationResponse.OK([.. _tourBusinessLogicContract.GetTourHistoryByTour(id).Select(x => CustomMapper.MapObject(x))]); } catch (ValidationException ex) { @@ -80,7 +64,7 @@ internal class TourAdapter : ITourAdapter { try { - return TourOperationResponse.OK(_mapper.Map(_tourBusinessLogicContract.GetTourByData(data))); + return TourOperationResponse.OK(CustomMapper.MapObject(_tourBusinessLogicContract.GetTourByData(data))); } catch (ArgumentNullException ex) { @@ -113,7 +97,7 @@ internal class TourAdapter : ITourAdapter { try { - _tourBusinessLogicContract.InsertTour(_mapper.Map(tourModel)); + _tourBusinessLogicContract.InsertTour(CustomMapper.MapObject(tourModel)); return TourOperationResponse.NoContent(); } catch (ArgumentNullException ex) @@ -147,7 +131,7 @@ internal class TourAdapter : ITourAdapter { try { - _tourBusinessLogicContract.UpdateTour(_mapper.Map(tourModel)); + _tourBusinessLogicContract.UpdateTour(CustomMapper.MapObject(tourModel)); return TourOperationResponse.NoContent(); } catch (ArgumentNullException ex)