7 Commits

Author SHA1 Message Date
maxim
dbcff6ec8c бб вп 2025-09-15 11:33:19 +04:00
maxim
e44393cd1c господи помилуй 2025-09-15 09:45:13 +04:00
maxim
1f8cb7b2ab слава господу богу 2025-09-14 16:41:35 +04:00
maxim
8a976ed2b7 ready 2025-09-14 13:34:10 +04:00
nezui1
e8e4ccf61d тесты упали 2025-09-14 13:06:23 +04:00
nezui1
a9e3f077be готово 2025-09-13 20:42:12 +04:00
nezui1
07b8c4d099 , 2025-09-13 17:18:06 +04:00
57 changed files with 858 additions and 654 deletions

View File

@@ -72,8 +72,6 @@ logger, IOrderStorageContract orderStorageContract, IConfigurationSalary configu
foreach (var master in masters)
{
var orders = _orderStorageContract.GetList();
// Фильтруем заказы по дате (связь с мастером идет через ServiceOrder)
var masterOrders = orders.Where(o => o.Date >= startDate && o.Date <= finishDate).ToList();
var post = _postStorageContract.GetElementById(master.PostId) ?? throw new ElementNotFoundException(master.PostId, _localizer);

View File

@@ -25,7 +25,7 @@ internal class ServiceBusinessLogicContract(IServiceStorageContract serviceStora
public List<ServiceDataModel> GetAllServices(bool onlyActive)
{
_logger.LogInformation("GetAllService called");
var services = _serviceStorageContract.GetList();
var services = _serviceStorageContract.GetList(onlyActive);
return services;
}
@@ -48,17 +48,11 @@ internal class ServiceBusinessLogicContract(IServiceStorageContract serviceStora
_logger.LogInformation($"GetServicesByServiceType called for {serviceType} (onlyActive: {onlyActive})");
var allServices = _serviceStorageContract.GetList() ?? new List<ServiceDataModel>();
var allServices = _serviceStorageContract.GetList(onlyActive) ?? new List<ServiceDataModel>();
var filteredByType = allServices.Where(s => s.ServiceType == serviceType);
if (onlyActive)
{
filteredByType = filteredByType.Where(s => s.IsDeleted!);
}
return filteredByType.ToList();
}

View File

@@ -75,7 +75,7 @@ internal class OpenXmlExcelBuilder : BaseExcelBuilder
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
return this;

View File

@@ -1,8 +1,13 @@
using System;
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;
using TwoFromTheCasketContratcs.Infrastructure.PostConfigurations;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.BindingModels;
@@ -16,5 +21,41 @@ public class PostBindingModel
public string? PostType { get; set; }
[AlternativeName("ConfigurationJson")]
public string? ConfigurationJson { get; set; }
[AlternativeName("ConfigurationModel")]
public PostConfiguration? ConfigurationModel => ParseJson(ConfigurationJson ?? "");
private string ParseConfiguration(PostConfiguration model) =>
System.Text.Json.JsonSerializer.Serialize(model, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
private PostConfiguration? ParseJson(string json)
{
if (string.IsNullOrEmpty(json))
return null;
try
{
var obj = JToken.Parse(json);
if (obj is not null)
{
return obj.Value<string>("Type") switch
{
nameof(CarpenterPostConfiguration) => JsonConvert.DeserializeObject<CarpenterPostConfiguration>(
json)!,
nameof(PainterPostConfiguration) => JsonConvert
.DeserializeObject<PainterPostConfiguration>(json)!,
nameof(PlastererPostConfiguration) => JsonConvert.DeserializeObject<PlastererPostConfiguration>(
json)!,
_ => JsonConvert.DeserializeObject<PostConfiguration>(json)!,
};
}
}
catch
{
// Return null if parsing fails
}
return null;
}
}

View File

@@ -11,6 +11,9 @@ using TwoFromTheCasketContratcs.Exceptions;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.Resources;
using Microsoft.Extensions.Configuration;
using TwoFromTheCasketContratcs.Infrastructure.PostConfigurations;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.DataModels;
@@ -28,6 +31,7 @@ internal class MasterDataModel(string id, string fio, string postId, DateTime bi
public bool IsDeleted { get; private set; } = isDeleted;
public MasterDataModel() : this(string.Empty, string.Empty, string.Empty, DateTime.UtcNow, DateTime.UtcNow, false) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (Id.IsEmpty())

View File

@@ -1,11 +0,0 @@
namespace TwoFromTheCasketContratcs.DataModels;
public class MasterWithHistoryDataModel
{
public string Id { get; set; } = string.Empty;
public string FIO { get; set; } = string.Empty;
public DateTime EmploymentDate { get; set; }
public bool IsDeleted { get; set; }
public int OrdersCount { get; set; }
}

View File

@@ -22,7 +22,8 @@ internal class OrderDataModel( string id, DateTime data, StatusType status, Room
public StatusType Status { get; private set; } = status;
public RoomType RoomType { get; private set; } = roomType;
public OrderDataModel() : this(string.Empty, DateTime.UtcNow, StatusType.None, RoomType.None) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (Id.IsEmpty())

View File

@@ -1,71 +1,47 @@
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Extensions;
using TwoFromTheCasketContratcs.Infrastructure;
using TwoFromTheCasketContratcs.Infrastructure.PostConfigurations;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.DataModels;
internal class PostDataModel(string postId, string postName, PostType
postType, PostConfiguration configuration) : IValidation
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")]
public PostConfiguration ConfigurationModel { get; private set; } = configuration;
public PostDataModel() : this(string.Empty, string.Empty, PostType.None, new PostConfiguration { Rate = 0 }) { }
public PostDataModel(string postId, string postName, PostType postType, string configurationJson) : this(postId,
postName, postType, new PostConfiguration())
{
var obj = JToken.Parse(configurationJson);
if (obj is not null)
{
ConfigurationModel = obj.Value<string>("Type") switch
{
nameof(CarpenterPostConfiguration) => JsonConvert.DeserializeObject<CarpenterPostConfiguration>(
configurationJson)!,
nameof(PainterPostConfiguration) => JsonConvert
.DeserializeObject<PainterPostConfiguration>(configurationJson)!,
nameof(PlastererPostConfiguration) => JsonConvert.DeserializeObject<PlastererPostConfiguration>(
configurationJson)!,
_ => JsonConvert.DeserializeObject<PostConfiguration>(configurationJson)!,
};
}
}
public void Validate(IStringLocalizer<Messages> localazier)
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
if (!Id.IsGuid())
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageIncorrectField"], "Id"));
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageIncorrectField"], "Id"));
if (PostName.IsEmpty())
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageEmptyField"], "PostName"));
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostName"));
if (PostType == PostType.None)
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageFieldIsNone"], "PostType"));
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageFieldIsNone"], "PostType"));
if (ConfigurationModel is null)
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageFieldNotInitialized"], "ConfigurationModel"));
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageFieldNotInitialized"], "ConfigurationModel"));
if (ConfigurationModel!.Rate <=0 )
throw new ValidationException(string.Format(localazier["ValidationExceptionMessageFieldLessOrEqualZero"], "Rate"));
if (ConfigurationModel!.Rate <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageFieldLessOrEqualZero"], "Rate"));
}
}
}

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Extensions;
using TwoFromTheCasketContratcs.Infrastructure;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
namespace TwoFromTheCasketContratcs.DataModels;
@@ -17,10 +18,13 @@ internal class SalaryDataModel(string masterId, DateTime salaryDate, double mast
public DateTime SalaryDate { get; private set; } = salaryDate.ToUniversalTime();
[AlternativeName("SalarySize")]
public double Salary { get; private set; } = masterSalary;
public double Prize { get; private set; } = prize;
public SalaryDataModel() : this(string.Empty, DateTime.UtcNow, 0, 0) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (MasterId.IsEmpty())

View File

@@ -26,6 +26,8 @@ internal class ServiceDataModel(string id, string serviceName, ServiceType servi
public bool IsDeleted { get; private set; } = isDeleted;
public ServiceDataModel() : this(string.Empty, string.Empty, ServiceType.None, string.Empty, 0, false) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (Id.IsEmpty())

View File

@@ -20,6 +20,8 @@ IValidation
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
public ServiceHistoryDataModel() : this(string.Empty, 0) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (ServiceId.IsEmpty())

View File

@@ -21,6 +21,8 @@ internal class ServiceOrderDataModel(string orderId, string serviceId, string ma
public int TimeOfWorking { get; private set; }= timeOfWorking;
public ServiceOrderDataModel() : this(string.Empty, string.Empty, string.Empty, 0) { }
public void Validate(IStringLocalizer<Messages> localazier)
{
if (OrderId.IsEmpty())

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoFromTheCasketContratcs.Mapper;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
class AlternativeNameAttribute(string alternativeName) : Attribute
{
public string AlternativeName { get; set; } = alternativeName;
}

View File

@@ -0,0 +1,247 @@
using System.Collections;
using System.Reflection;
namespace TwoFromTheCasketContratcs.Mapper;
internal static class CustomMapper
{
public static To MapObject<To>(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<IgnoreMappingAttribute>() 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<PostProcessingAttribute>();
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
{
}
}
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<IgnoreMappingAttribute>() 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
{
}
}
RemoveReadOnly(field);
field.SetValue(newObject, fromValue);
}
var classPostProcessing = typeTo.GetCustomAttribute<PostProcessingAttribute>();
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<To>(object obj) => MapObject(obj, Activator.CreateInstance<To>()!);
public static To? MapObjectWithNull<To>(object? obj) => obj is null ? default : MapObject(obj, Activator.CreateInstance<To>());
private static PropertyInfo? TryGetPropertyFrom(PropertyInfo propertyTo, PropertyInfo[] propertiesFrom)
{
var customAttribute = propertyTo.GetCustomAttributes<AlternativeNameAttribute>()?.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<T>(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<T>(PropertyInfo property, T newObject)
{
var defaultValueAttribute = property.GetCustomAttribute<DefaultValueAttribute>();
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);
foreach (var elem in (IEnumerable)list)
{
var newElem = MapObject(elem, Activator.CreateInstance(propertyTo.PropertyType.GenericTypeArguments[0])!);
if (newElem is not null)
{
propertyTo.PropertyType.GetMethod("Add")!.Invoke(listResult, [newElem]);
}
}
return listResult;
}
}
enum DefaultValueFunc
{
None,
UtcNow
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoFromTheCasketContratcs.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;
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoFromTheCasketContratcs.Mapper;
[AttributeUsage(AttributeTargets.Property)]
class IgnoreMappingAttribute : Attribute
{
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoFromTheCasketContratcs.Mapper;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
class PostProcessingAttribute : Attribute
{
public string? MappingCallMethodName { get; set; }
public PostProcessingType ActionType { get; set; } = PostProcessingType.None;
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoFromTheCasketContratcs.Mapper;
enum PostProcessingType
{
None = -1,
ToUniversalTime = 1,
ToLocalTime = 2
}

View File

@@ -359,3 +359,6 @@
<value>Maître inconnu</value>
</data>
</root>

View File

@@ -11,6 +11,7 @@ namespace TwoFromTheCasketContratcs.StorageContracts;
internal interface IServiceStorageContract
{
List<ServiceDataModel> GetList();
List<ServiceDataModel> GetList(bool onlyActive);
Task<List<ServiceDataModel>> GetListAsync();
Task<List<ServiceDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
List<ServiceHistoryDataModel> GetHistoryByServiceId(string serviceId);

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;

View File

@@ -1,8 +1,10 @@
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;
public class OrderViewModel
{
[AlternativeName("Id")]
public string? Id { get; set; }
public DateTime Date { get; set; }

View File

@@ -3,16 +3,20 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.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("ConfigurationJson")]
[AlternativeName("Configuration")]
public required string Configuration { get; set; }
}

View File

@@ -1,4 +1,6 @@
namespace TwoFromTheCasketContratcs.ViewModels;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;
public class SalaryViewModel
{
@@ -7,6 +9,7 @@ public class SalaryViewModel
public required DateTime SalaryDate { get; set; }
[AlternativeName("Salary")]
public required double SalarySize { get; set; }
public required double Prize { get; set; }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;

View File

@@ -1,4 +1,6 @@
namespace TwoFromTheCasketContratcs.ViewModels;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;
public class ServiceOderViewModel
{

View File

@@ -1,4 +1,5 @@
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;
@@ -10,6 +11,7 @@ public class ServiceViewModel
public required ServiceType ServiceType { get; set; }
[AlternativeName("MasterID")]
public required string MasterId { get; set; }
public required double Price { get; set; }

View File

@@ -1,4 +1,5 @@
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketContratcs.ViewModels;
@@ -8,6 +9,7 @@ public class ServiceWithHistoryViewModel
public string ServiceName { get; set; } = string.Empty;
public ServiceType ServiceType { get; set; }
public double Price { get; set; }
[AlternativeName("MasterID")]
public string MasterId { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public bool IsDeleted { get; set; }

View File

@@ -1,4 +1,4 @@
using AutoMapper;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
@@ -10,30 +10,17 @@ using System.Threading.Tasks;
using System.Xml.Linq;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.StorageContracts;
using TwoFromTheCasketDatabase.Models;
namespace TwoFromTheCasketDatabase.Implementation;
internal class MasterStorageContract : IMasterStorageContract
internal class MasterStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer) : IMasterStorageContract
{
private readonly TwoFromTheCasketDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public MasterStorageContract(TwoFromTheCasketDbContext twoFromTheCasketDbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = twoFromTheCasketDbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(Master));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
private readonly TwoFromTheCasketDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<MasterDataModel> GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null)
{
@@ -47,7 +34,7 @@ internal class MasterStorageContract : IMasterStorageContract
if (fromEmploymentDate is not null && toEmploymentDate is not null)
query = query.Where(x => x.EmploymentDate >= fromEmploymentDate
&& x.EmploymentDate <= toEmploymentDate);
return [.. query.Select(x => _mapper.Map<MasterDataModel>(x))];
return [.. query.Select(x => CustomMapper.MapObject<MasterDataModel>(x))];
}
catch(Exception ex)
{
@@ -61,7 +48,7 @@ internal class MasterStorageContract : IMasterStorageContract
{
try
{
return _mapper.Map<MasterDataModel>(GetMasterById(id));
return CustomMapper.MapObjectWithNull<MasterDataModel>(GetMasterById(id));
}
catch (Exception ex)
{
@@ -73,7 +60,7 @@ internal class MasterStorageContract : IMasterStorageContract
{
try
{
return _mapper.Map<MasterDataModel>(_dbContext.Masters.FirstOrDefault(x => x.FIO == name));
return CustomMapper.MapObjectWithNull<MasterDataModel>(_dbContext.Masters.FirstOrDefault(x => x.FIO == name));
}
catch (Exception ex)
{
@@ -86,7 +73,7 @@ internal class MasterStorageContract : IMasterStorageContract
{
try
{
return _mapper.Map<MasterDataModel>(_dbContext.Masters.FirstOrDefault(x => x.PostId == postId));
return CustomMapper.MapObjectWithNull<MasterDataModel>(_dbContext.Masters.FirstOrDefault(x => x.PostId == postId));
}
catch (Exception ex)
{
@@ -98,7 +85,7 @@ internal class MasterStorageContract : IMasterStorageContract
{
try
{
_dbContext.Masters.Add(_mapper.Map<Master>(masterDataModel));
_dbContext.Masters.Add(CustomMapper.MapObject<Master>(masterDataModel));
_dbContext.SaveChanges();
}
catch(InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
@@ -122,7 +109,7 @@ internal class MasterStorageContract : IMasterStorageContract
try
{
var element = GetMasterById(masterDataModel.Id) ?? throw new ElementNotFoundException(masterDataModel.Id, _localizer);
_dbContext.Masters.Update(_mapper.Map(masterDataModel,element));
_dbContext.Masters.Update(CustomMapper.MapObject(masterDataModel,element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)

View File

@@ -1,61 +1,25 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.StorageContracts;
using TwoFromTheCasketDatabase.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace TwoFromTheCasketDatabase.Implementation;
internal class OrderStorageContract : IOrderStorageContract
internal class OrderStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer) : IOrderStorageContract
{
private readonly TwoFromTheCasketDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public OrderStorageContract(TwoFromTheCasketDbContext twoFromTheCasketDbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = twoFromTheCasketDbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Order, OrderDataModel>()
.ConstructUsing(src => new OrderDataModel(
src.Id.ToString(),
src.Date,
src.Status,
src.RoomType));
cfg.CreateMap<OrderDataModel, Order>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => Guid.Parse(src.Id)))
.ForMember(dest => dest.Date, opt => opt.MapFrom(src => src.Date))
.ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status))
.ForMember(dest => dest.RoomType, opt => opt.MapFrom(src => src.RoomType));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
private readonly TwoFromTheCasketDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<OrderDataModel> GetList()
{
try
{
return [.. _dbContext.Orders.Select(x => _mapper.Map<OrderDataModel>(x))];
return [.. _dbContext.Orders.Select(x => CustomMapper.MapObject<OrderDataModel>(x))];
}
catch (Exception ex)
{
@@ -67,7 +31,7 @@ internal class OrderStorageContract : IOrderStorageContract
{
try
{
return _mapper.Map<OrderDataModel>(GetOrderById(id));
return CustomMapper.MapObjectWithNull<OrderDataModel>(GetOrderById(id));
}
catch (Exception ex)
{
@@ -79,7 +43,7 @@ internal class OrderStorageContract : IOrderStorageContract
{
try
{
return _mapper.Map<OrderDataModel>(_dbContext.Orders.FirstOrDefault(x => x.Date == date));
return CustomMapper.MapObjectWithNull<OrderDataModel>(_dbContext.Orders.FirstOrDefault(x => x.Date == date));
}
catch (Exception ex)
{
@@ -91,7 +55,7 @@ internal class OrderStorageContract : IOrderStorageContract
{
try
{
return _mapper.Map<OrderDataModel>(_dbContext.Orders.FirstOrDefault(x => x.Status == status));
return CustomMapper.MapObjectWithNull<OrderDataModel>(_dbContext.Orders.FirstOrDefault(x => x.Status == status));
}
catch (Exception ex)
{
@@ -104,7 +68,7 @@ internal class OrderStorageContract : IOrderStorageContract
{
try
{
_dbContext.Orders.Add(_mapper.Map<Order>(orderDataModel));
_dbContext.Orders.Add(CustomMapper.MapObject<Order>(orderDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
@@ -123,7 +87,7 @@ internal class OrderStorageContract : IOrderStorageContract
try
{
var element = GetOrderById(orderDataModel.Id) ?? throw new ElementNotFoundException(orderDataModel.Id, _localizer);
_dbContext.Orders.Update(_mapper.Map(orderDataModel, element));
_dbContext.Orders.Update(CustomMapper.MapObject(orderDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
@@ -195,7 +159,7 @@ internal class OrderStorageContract : IOrderStorageContract
{
return [.. await _dbContext.Orders
.Where(x => x.Date >= startDate && x.Date <= endDate)
.Select(x => _mapper.Map<OrderDataModel>(x))
.Select(x => CustomMapper.MapObject<OrderDataModel>(x))
.ToListAsync(ct)];
}
catch (Exception ex)

View File

@@ -1,48 +1,25 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.StorageContracts;
using TwoFromTheCasketDatabase.Models;
namespace TwoFromTheCasketDatabase.Implementation;
internal class PostStorageContract : IPostStorageContract
internal class PostStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer) : IPostStorageContract
{
private readonly TwoFromTheCasketDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public PostStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<PostDataModel, Post>()
.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 TwoFromTheCasketDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<PostDataModel> GetList()
{
try
{
return [.. _dbContext.Posts.Select(x => _mapper.Map<PostDataModel>(x))];
return [.. _dbContext.Posts.Select(x => CustomMapper.MapObject<PostDataModel>(x))];
}
catch (Exception ex)
{
@@ -55,7 +32,7 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => _mapper.Map<PostDataModel>(x))];
return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => CustomMapper.MapObject<PostDataModel>(x))];
}
catch (Exception ex)
{
@@ -68,7 +45,7 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
return _mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostId == id && x.IsActual));
return CustomMapper.MapObjectWithNull<PostDataModel>(GetPostById(id));
}
catch (Exception ex)
{
@@ -81,7 +58,7 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
return _mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostName == name && x.IsActual));
return CustomMapper.MapObjectWithNull<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostName == name && x.IsActual));
}
catch (Exception ex)
{
@@ -94,22 +71,38 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
_dbContext.Posts.Add(_mapper.Map<Post>(postDataModel));
// Проверяем дубликаты перед добавлением
var existingByName = _dbContext.Posts.FirstOrDefault(x => x.PostName == postDataModel.PostName && x.IsActual);
if (existingByName != null)
{
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
}
var existingById = _dbContext.Posts.FirstOrDefault(x => x.PostId == postDataModel.Id && x.IsActual);
if (existingById != null)
{
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
}
_dbContext.Posts.Add(CustomMapper.MapObject<Post>(postDataModel));
_dbContext.SaveChanges();
}
catch (DbUpdateException ex)
when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
}
catch (DbUpdateException ex)
when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostId_IsActual" })
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
}
catch (Exception ex)
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostId_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
}
catch (Exception ex) when (!(ex is ElementExistsException))
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
@@ -123,12 +116,25 @@ internal class PostStorageContract : IPostStorageContract
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetPostById(postDataModel.Id) ?? throw new ElementNotFoundException(postDataModel.Id, _localizer);
var element = GetPostByIdWithoutActualFilter(postDataModel.Id) ?? throw new ElementNotFoundException(postDataModel.Id, _localizer);
if (!element.IsActual) throw new ElementDeletedException(postDataModel.Id, _localizer);
// Проверяем дубликаты перед обновлением
var existingByName = _dbContext.Posts.FirstOrDefault(x => x.PostName == postDataModel.PostName && x.IsActual && x.PostId != postDataModel.Id);
if (existingByName != null)
{
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
}
var existingById = _dbContext.Posts.FirstOrDefault(x => x.PostId == postDataModel.Id && x.IsActual && x.PostId != postDataModel.Id);
if (existingById != null)
{
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
}
element.IsActual = false;
_dbContext.SaveChanges();
var newElement = _mapper.Map<Post>(postDataModel);
var newElement = CustomMapper.MapObject<Post>(postDataModel);
_dbContext.Posts.Add(newElement);
_dbContext.SaveChanges();
transaction.Commit();
@@ -139,13 +145,12 @@ internal class PostStorageContract : IPostStorageContract
throw;
}
}
catch (DbUpdateException ex)
when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException || ex is ElementExistsException)
{
_dbContext.ChangeTracker.Clear();
throw;
@@ -161,33 +166,51 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetPostByIdWithoutActualFilter(id) ?? throw new ElementNotFoundException(id, _localizer);
if (!element.IsActual) throw new ElementDeletedException(id, _localizer);
element.IsActual = false;
_dbContext.SaveChanges();
}
catch
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (ElementDeletedException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public void ResElement(string id)
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetPostByIdWithoutActualFilter(id) ?? throw new ElementNotFoundException(id, _localizer);
element.IsActual = true;
_dbContext.SaveChanges();
}
catch
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
private Post? GetPostById(string id) => _dbContext.Posts.Where(x => x.PostId == id)
private Post? GetPostById(string id) => _dbContext.Posts.Where(x => x.PostId == id && x.IsActual)
.OrderByDescending(x => x.ChangeDate).FirstOrDefault();
private Post? GetPostByIdWithoutActualFilter(string id) => _dbContext.Posts.Where(x => x.PostId == id)
.OrderByDescending(x => x.ChangeDate).FirstOrDefault();
}

View File

@@ -1,51 +1,18 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.StorageContracts;
using TwoFromTheCasketDatabase.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace TwoFromTheCasketDatabase.Implementation;
internal class SalaryStorageContract : ISalaryStorageContract
internal class SalaryStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer) : ISalaryStorageContract
{
TwoFromTheCasketDbContext _dbContext;
Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public SalaryStorageContract(TwoFromTheCasketDbContext twoFromTheCasketDbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = twoFromTheCasketDbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Salary, SalaryDataModel>()
.ConstructUsing(src => new SalaryDataModel(
src.MasterId,
src.SalaryDate,
src.SalarySize,
src.Prize));
cfg.CreateMap<SalaryDataModel, Salary>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // Игнорируем Id, так как он генерируется автоматически
.ForMember(dest => dest.MasterId, opt => opt.MapFrom(src => src.MasterId))
.ForMember(dest => dest.SalaryDate, opt => opt.MapFrom(src => src.SalaryDate))
.ForMember(dest => dest.SalarySize, opt => opt.MapFrom(src => src.Salary))
.ForMember(dest => dest.Prize, opt => opt.MapFrom(src => src.Prize));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
private readonly TwoFromTheCasketDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? masterId = null)
{
@@ -53,21 +20,20 @@ internal class SalaryStorageContract : ISalaryStorageContract
{
var query = _dbContext.Salaries.Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate);
if (masterId is not null) query = query.Where(x => x.MasterId == masterId);
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
return [.. query.Select(x => CustomMapper.MapObject<SalaryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public SalaryDataModel? GetElementByMasterId(string masterId)
{
try
{
return _mapper.Map<SalaryDataModel>(_dbContext.Salaries.FirstOrDefault(x => x.MasterId == masterId));
return CustomMapper.MapObjectWithNull<SalaryDataModel>(_dbContext.Salaries.FirstOrDefault(x => x.MasterId == masterId));
}
catch (Exception ex)
{
@@ -80,7 +46,7 @@ internal class SalaryStorageContract : ISalaryStorageContract
{
try
{
return _mapper.Map<SalaryDataModel>(_dbContext.Salaries.FirstOrDefault(x => x.SalaryDate == salaryDate));
return CustomMapper.MapObjectWithNull<SalaryDataModel>(_dbContext.Salaries.FirstOrDefault(x => x.SalaryDate == salaryDate));
}
catch (Exception ex)
{
@@ -92,7 +58,7 @@ internal class SalaryStorageContract : ISalaryStorageContract
{
try
{
_dbContext.Salaries.Add(_mapper.Map<Salary>(salaryDataModel));
_dbContext.Salaries.Add(CustomMapper.MapObject<Salary>(salaryDataModel));
}
catch (Exception ex)
{
@@ -122,7 +88,7 @@ internal class SalaryStorageContract : ISalaryStorageContract
.Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate)
.ToListAsync(ct);
return salaries.Select(x => _mapper.Map<SalaryDataModel>(x)).ToList();
return salaries.Select(x => CustomMapper.MapObject<SalaryDataModel>(x)).ToList();
}
catch (Exception ex)
{

View File

@@ -1,49 +1,45 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.StorageContracts;
using TwoFromTheCasketDatabase.Models;
namespace TwoFromTheCasketDatabase.Implementation;
internal class ServiceStorageContract : IServiceStorageContract
internal class ServiceStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer) : IServiceStorageContract
{
private readonly TwoFromTheCasketDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public ServiceStorageContract(TwoFromTheCasketDbContext dbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Service, ServiceDataModel>();
cfg.CreateMap<ServiceDataModel, Service>()
.ForMember(x => x.IsDeleted, x => x.MapFrom(src => false));
cfg.CreateMap<ServiceHistory, ServiceHistoryDataModel>();
cfg.CreateMap<ServiceHistoryDataModel, ServiceHistory>();
});
_mapper = new Mapper(config);
_localizer = localizer;
}
private readonly TwoFromTheCasketDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<ServiceDataModel> GetList()
{
try
{
return [.. _dbContext.Services.Select(x => _mapper.Map<ServiceDataModel>(x))];
return [.. _dbContext.Services.Where(x => !x.IsDeleted).Select(x => CustomMapper.MapObject<ServiceDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public List<ServiceDataModel> GetList(bool onlyActive)
{
try
{
if (onlyActive)
{
return [.. _dbContext.Services.Where(x => !x.IsDeleted).Select(x => CustomMapper.MapObject<ServiceDataModel>(x))];
}
else
{
return [.. _dbContext.Services.Select(x => CustomMapper.MapObject<ServiceDataModel>(x))];
}
}
catch (Exception ex)
{
@@ -57,8 +53,7 @@ internal class ServiceStorageContract : IServiceStorageContract
{
try
{
return _mapper.Map<ServiceDataModel>(_dbContext.Services.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
return CustomMapper.MapObjectWithNull<ServiceDataModel>(GetServiceById(id));
}
catch (Exception ex)
{
@@ -71,8 +66,7 @@ internal class ServiceStorageContract : IServiceStorageContract
{
try
{
return [.. _dbContext.Services.Select(x => _mapper.Map<ServiceDataModel>(_dbContext.Services.FirstOrDefault(x => x.MasterId == masterId && !x.IsDeleted)))];
return [.. _dbContext.Services.Where(x => x.MasterId == masterId && !x.IsDeleted).Select(x => CustomMapper.MapObject<ServiceDataModel>(x))];
}
catch (Exception ex)
{
@@ -85,8 +79,7 @@ internal class ServiceStorageContract : IServiceStorageContract
{
try
{
return [.. _dbContext.Services.Select(x => _mapper.Map<ServiceDataModel>(_dbContext.Services.FirstOrDefault(x => x.ServiceName == name && !x.IsDeleted)))];
return [.. _dbContext.Services.Where(x => x.ServiceName == name && !x.IsDeleted).Select(x => CustomMapper.MapObject<ServiceDataModel>(x))];
}
catch (Exception ex)
{
@@ -99,42 +92,37 @@ internal class ServiceStorageContract : IServiceStorageContract
{
try
{
return [.. _dbContext.ServiceHistories.Where(x => x.ServiceId == serviceId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<ServiceHistoryDataModel>(x))];
return [.. _dbContext.ServiceHistories.Where(x => x.ServiceId == serviceId).OrderByDescending(x => x.ChangeDate).Select(x => CustomMapper.MapObject<ServiceHistoryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public void AddElement(ServiceDataModel serviceDataModel)
{
try
{
_dbContext.Services.Add(_mapper.Map<Service>(serviceDataModel));
_dbContext.Services.Add(CustomMapper.MapObject<Service>(serviceDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name ==
"ThrowIdentityConflict")
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", serviceDataModel.Id, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "IX_Service_ServiceName_IsDeleted" })
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Service_ServiceName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("ServiceName",
serviceDataModel.ServiceName, _localizer);
throw new ElementExistsException("ServiceName", serviceDataModel.ServiceName, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
@@ -146,16 +134,13 @@ internal class ServiceStorageContract : IServiceStorageContract
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetServiceById(serviceDataModel.Id) ??
throw new ElementNotFoundException(serviceDataModel.Id, _localizer);
var element = GetServiceById(serviceDataModel.Id) ?? throw new ElementNotFoundException(serviceDataModel.Id, _localizer);
if (element.Price != serviceDataModel.Price)
{
_dbContext.ServiceHistories.Add(new
ServiceHistory() { ServiceId = element.Id, OldPrice = element.Price});
_dbContext.ServiceHistories.Add(new ServiceHistory() { ServiceId = element.Id, OldPrice = element.Price });
_dbContext.SaveChanges();
}
_dbContext.Services.Update(_mapper.Map(serviceDataModel,
element));
_dbContext.Services.Update(CustomMapper.MapObject(serviceDataModel, element));
_dbContext.SaveChanges();
transaction.Commit();
}
@@ -164,17 +149,13 @@ internal class ServiceStorageContract : IServiceStorageContract
transaction.Rollback();
throw;
}
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "IX_Products_ProductName_IsDeleted" })
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Service_ServiceName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("ProductName",
serviceDataModel.ServiceName, _localizer);
throw new ElementExistsException("ServiceName", serviceDataModel.ServiceName, _localizer);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is
ElementNotFoundException)
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
@@ -184,18 +165,16 @@ internal class ServiceStorageContract : IServiceStorageContract
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public void DelElement(string id)
{
try
{
var element = GetServiceById(id) ?? throw new
ElementNotFoundException(id, _localizer);
var element = GetServiceById(id) ?? throw new ElementNotFoundException(id, _localizer);
element.IsDeleted = true;
_dbContext.SaveChanges();
}
catch (ElementNotFoundException ex)
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
@@ -215,7 +194,7 @@ internal class ServiceStorageContract : IServiceStorageContract
return [.. await _dbContext.Services
.Include(x => x.ServiceHistory)
.Where(x => !x.IsDeleted)
.Select(x => _mapper.Map<ServiceDataModel>(x))
.Select(x => CustomMapper.MapObject<ServiceDataModel>(x))
.ToListAsync()];
}
catch (Exception ex)
@@ -232,7 +211,7 @@ internal class ServiceStorageContract : IServiceStorageContract
return [.. await _dbContext.Services
.Include(x => x.ServiceHistory)
.Where(x => !x.IsDeleted)
.Select(x => _mapper.Map<ServiceDataModel>(x))
.Select(x => CustomMapper.MapObject<ServiceDataModel>(x))
.ToListAsync(ct)];
}
catch (Exception ex)

View File

@@ -1,18 +1,17 @@
using AutoMapper;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketDatabase.Models;
internal class Order
{
[AlternativeName("Id")]
public required string Id { get; set; }
public DateTime Date { get; set; }
@@ -20,7 +19,4 @@ internal class Order
public StatusType Status { get; set; }
public RoomType RoomType { get; set; }
}

View File

@@ -6,6 +6,7 @@ using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Infrastructure.PostConfigurations;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketDatabase.Models;
@@ -13,15 +14,20 @@ internal class Post
{
public required string Id { get; set; } = Guid.NewGuid().ToString();
[AlternativeName("Id")]
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; }
public bool IsActual { get; set; }
[AlternativeName("ConfigurationJson")]
public string ConfigurationJson { get; set; } = string.Empty;
public bool IsActual { get; set; } = true;
public DateTime ChangeDate { get; set; }
}

View File

@@ -1,15 +1,13 @@
using AutoMapper;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketDatabase.Models;
[AutoMap(typeof(SalaryDataModel), ReverseMap = true)]
internal class Salary
{
public string Id { get; set; } = Guid.NewGuid().ToString();
@@ -17,6 +15,7 @@ internal class Salary
public DateTime SalaryDate { get; set; }
[AlternativeName("Salary")]
public required double SalarySize { get; set; }
public double Prize { get; set; }

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketDatabase.Models;
@@ -16,6 +17,7 @@ internal class Service
public required ServiceType ServiceType { get; set; }
[AlternativeName("MasterID")]
public required string MasterId { get; set; }
public required double Price { get; set; }

View File

@@ -25,7 +25,7 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Master>().HasIndex(e => new { e.Id, e.IsDeleted }).IsUnique().HasFilter($"\"{nameof(Master.IsDeleted)}\" = FALSE");
@@ -46,20 +46,20 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
modelBuilder.Entity<Service>().HasIndex(e => new { e.ServiceName, e.IsDeleted }).IsUnique().HasFilter($"\"{nameof(Service.IsDeleted)}\" = FALSE");
modelBuilder.Entity<ServiceOrder>().HasKey(x => x.ServiceOrderId);
// Настройка внешних ключей для ServiceOrder
modelBuilder.Entity<ServiceOrder>()
.HasOne<Order>()
.WithMany()
.HasForeignKey(so => so.OrderId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<ServiceOrder>()
.HasOne<Service>()
.WithMany()
.HasForeignKey(so => so.ServiceId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<ServiceOrder>()
.HasOne<Master>()
.WithMany(m => m.ServiceOrders)
@@ -81,13 +81,14 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
modelBuilder.Entity<Post>().Property(x => x.Configuration)
.HasColumnType("jsonb")
.HasConversion(
x => SerializePostConfiguration(x),
x => JsonConvert.SerializeObject(x, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
Formatting = Formatting.None
}),
x => DeserializePostConfiguration(x)
);
}
public DbSet<Master> Masters { get; set; }
@@ -103,20 +104,13 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
public DbSet<ServiceOrder> ServiceOrders { get; set; }
private static string SerializePostConfiguration(PostConfiguration postConfiguration) =>
JsonConvert.SerializeObject(postConfiguration, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
Formatting = Formatting.None
});
private static PostConfiguration DeserializePostConfiguration(string jsonString)
{
try
{
var token = JToken.Parse(jsonString);
var typeValue = token.Value<string>("Type");
return typeValue switch
{
nameof(CarpenterPostConfiguration) =>
@@ -134,4 +128,4 @@ internal class TwoFromTheCasketDbContext(IConfigurationDatabase configurationDat
return new PostConfiguration { Rate = 0 };
}
}
}
}

View File

@@ -41,7 +41,7 @@ internal class ServiceBusinessLogicContractTests
new(Guid.NewGuid().ToString(), "Service 1", ServiceType.Painting, Guid.NewGuid().ToString(), 100, false),
new(Guid.NewGuid().ToString(), "Service 2", ServiceType.Carpentry, Guid.NewGuid().ToString(), 200, false),
};
_serviceStorageContract.Setup(x => x.GetList()).Returns(listOriginal);
_serviceStorageContract.Setup(x => x.GetList(It.IsAny<bool>())).Returns(listOriginal);
// Act
var list = _serviceBusinessLogicContract.GetAllServices(onlyActive: true);
@@ -52,14 +52,14 @@ internal class ServiceBusinessLogicContractTests
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.EquivalentTo(listOriginal));
});
_serviceStorageContract.Verify(x => x.GetList(), Times.Once);
_serviceStorageContract.Verify(x => x.GetList(It.IsAny<bool>()), Times.Once);
}
[Test]
public void GetAllServices_ReturnEmptyList_Test()
{
// Arrange
_serviceStorageContract.Setup(x => x.GetList()).Returns([]);
_serviceStorageContract.Setup(x => x.GetList(It.IsAny<bool>())).Returns([]);
// Act
var list = _serviceBusinessLogicContract.GetAllServices(onlyActive: true);
@@ -76,11 +76,11 @@ internal class ServiceBusinessLogicContractTests
public void GetAllServices_StorageThrowError_ThrowException_Test()
{
// Arrange
_serviceStorageContract.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_serviceStorageContract.Setup(x => x.GetList(It.IsAny<bool>())).Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
// Act & Assert
Assert.That(() => _serviceBusinessLogicContract.GetAllServices(onlyActive: true), Throws.TypeOf<StorageException>());
_serviceStorageContract.Verify(x => x.GetList(), Times.Once);
_serviceStorageContract.Verify(x => x.GetList(It.IsAny<bool>()), Times.Once);
}
[Test]
@@ -128,15 +128,15 @@ internal class ServiceBusinessLogicContractTests
new(Guid.NewGuid().ToString(), "Service 1", serviceType, Guid.NewGuid().ToString(), 100, false),
new(Guid.NewGuid().ToString(), "Service 2", serviceType, Guid.NewGuid().ToString(), 200, false),
};
_serviceStorageContract.Setup(x => x.GetList()).Returns(listOriginal);
_serviceStorageContract.Setup(x => x.GetList(It.IsAny<bool>())).Returns(listOriginal);
// Act
var list = _serviceBusinessLogicContract.GetServicesByServiceType(serviceType, onlyActive: true);
// Assert
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(0));
_serviceStorageContract.Verify(x => x.GetList(), Times.Once);
Assert.That(list, Has.Count.EqualTo(2));
_serviceStorageContract.Verify(x => x.GetList(It.IsAny<bool>()), Times.Once);
}
[Test]

View File

@@ -60,7 +60,7 @@ public class PostDataModelTests
var id = Guid.NewGuid().ToString();
var postName = "Manager";
var postType = PostType.Plasterer;
var configuration = new PostConfiguration { Rate = 50000 };
var configuration = new PostConfiguration { Rate = 50000, CutleryName = "ru-RU" };
var isActual = true;
var changeDate = DateTime.Now;
@@ -73,7 +73,9 @@ public class PostDataModelTests
Assert.That(post.Id, Is.EqualTo(id));
Assert.That(post.PostName, Is.EqualTo(postName));
Assert.That(post.PostType, Is.EqualTo(postType));
Assert.That(post.ConfigurationModel, Is.EqualTo(configuration));
Assert.That(post.ConfigurationModel.Rate, Is.EqualTo(configuration.Rate));
Assert.That(post.ConfigurationModel.CutleryName, Is.EqualTo(configuration.CutleryName));
Assert.That(post.ConfigurationModel.Type, Is.EqualTo(configuration.Type));
Assert.That(post.ConfigurationModel.CutleryName, Is.Not.Empty);
});

View File

@@ -1,18 +1,10 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFromTheCasketContratcs.Infrastructure;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketTest.Infrastructure;
using Microsoft.AspNetCore.Localization;
namespace TwoFromTheCasketTest.Infrastructure;
@@ -28,7 +20,6 @@ internal class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TPr
if (databaseConfig is not null)
services.Remove(databaseConfig);
var loggerFactory = services.SingleOrDefault(x => x.ServiceType == typeof(LoggerFactory));
if (loggerFactory is not null)
services.Remove(loggerFactory);

View File

@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Infrastructure.PostConfigurations;
using TwoFromTheCasketDatabase;
@@ -55,13 +56,14 @@ employmentDate = null, bool isDeleted = false)
public static Post InsertPostToDatabaseAndReturn(this TwoFromTheCasketDbContext dbContext, string? id = null, string? postName = null,
PostType postType = PostType.Plasterer, PostConfiguration? configuration = null, bool isActual = true, DateTime? changeDate = null)
{
var config = configuration ?? new PostConfiguration() { Rate = 100 };
var post = new Post()
{
Id = Guid.NewGuid().ToString(),
PostId = id ?? Guid.NewGuid().ToString(),
PostName = postName ?? Guid.NewGuid().ToString(),
PostType = postType,
Configuration = configuration ?? new PostConfiguration() { Rate = 100 },
Configuration = config,
IsActual = isActual,
ChangeDate = changeDate ?? DateTime.UtcNow
};
@@ -90,10 +92,10 @@ employmentDate = null, bool isDeleted = false)
DateTime? salaryDate = null)
{
var salary = new Salary()
{
MasterId = masterId,
SalarySize = salarySize,
SalaryDate = DateTime.SpecifyKind(salaryDate ?? DateTime.UtcNow, DateTimeKind.Utc)
{
MasterId = masterId,
SalarySize = salarySize,
SalaryDate = DateTime.SpecifyKind(salaryDate ?? DateTime.UtcNow, DateTimeKind.Utc)
};
dbContext.Salaries.Add(salary);
dbContext.SaveChanges();
@@ -119,7 +121,7 @@ employmentDate = null, bool isDeleted = false)
public static Post? GetPostFromDatabaseByPostId(this TwoFromTheCasketDbContext dbContext, string id) =>
dbContext.Posts.FirstOrDefault(x => x.PostId == id && x.IsActual);
public static ServiceHistory InsertServiceHistoryToDatabaseAndReturn(this TwoFromTheCasketDbContext dbContext, string serviceId, double oldPrice = 100.0)
{
var serviceHistory = new ServiceHistory()

View File

@@ -110,12 +110,23 @@ internal abstract class BaseLocalizationControllerTest
RoomType = RoomType.Industrial
}).Entity.Id;
TwoFromTheCasketDbContext.SaveChanges();
// Создаем связь заказ-услуга-мастер
TwoFromTheCasketDbContext.ServiceOrders.Add(new ServiceOrder
{
OrderId = _orderId,
ServiceId = _serviceId,
MasterId = _masterId,
TimeOfWorking = 2
});
TwoFromTheCasketDbContext.SaveChanges();
}
[TearDown]
public void TearDown()
{
TwoFromTheCasketDbContext!.Salaries.RemoveRange(TwoFromTheCasketDbContext.Salaries);
TwoFromTheCasketDbContext!.ServiceOrders.RemoveRange(TwoFromTheCasketDbContext.ServiceOrders);
TwoFromTheCasketDbContext.Salaries.RemoveRange(TwoFromTheCasketDbContext.Salaries);
TwoFromTheCasketDbContext.Orders.RemoveRange(TwoFromTheCasketDbContext.Orders);
TwoFromTheCasketDbContext.Masters.RemoveRange(TwoFromTheCasketDbContext.Masters);
TwoFromTheCasketDbContext.Posts.RemoveRange(TwoFromTheCasketDbContext.Posts);
@@ -162,25 +173,8 @@ internal abstract class BaseLocalizationControllerTest
[Test]
public async Task LoadOrders_WhenHaveRecords_ShouldSuccess_Test()
{
// Arrange
var order1 = TwoFromTheCasketDbContext!.Orders.Add(new Order
{
Id = Guid.NewGuid().ToString(),
Date = DateTime.UtcNow.AddDays(-5),
Status = StatusType.Ready,
RoomType = RoomType.Social
}).Entity;
var order2 = TwoFromTheCasketDbContext.Orders.Add(new Order
{
Id = Guid.NewGuid().ToString(),
Date = DateTime.UtcNow.AddDays(-3),
Status = StatusType.InProcess,
RoomType = RoomType.Residential
}).Entity;
TwoFromTheCasketDbContext.SaveChanges();
// Arrange - данные уже созданы в SetUp
// Act
var response = await HttpClient.GetAsync($"/api/report/loadorders?fromDate={DateTime.Now.AddDays(-10):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.Now.AddDays(1):MM/dd/yyyy HH:mm:ss}");
@@ -486,6 +480,7 @@ internal abstract class BaseLocalizationControllerTest
}
}
protected abstract string MessageElementValidationErrorPostNameEmpty();
[TestCase("posts")]

View File

@@ -69,12 +69,7 @@ internal class PostStorageContractTests : BaseStorageContractTest
Assert.That(list, Has.Count.EqualTo(2));
}
//[Test]
//public void Try_GetElementById_WhenHaveRecord_Test()
//{
// var post = InsertPostToDatabaseAndReturn(Guid.NewGuid().ToString());
// AssertElement(_postStorageContract.GetElementById(post.PostId), post);
//}
[Test]
public void Try_GetElementById_WhenNoRecord_Test()
{
@@ -298,12 +293,12 @@ internal class PostStorageContractTests : BaseStorageContractTest
var plastererPercent = 18.0;
var updatedPost = CreateModel(post.Id, config: new PlastererPostConfiguration() { Rate = 1100, PlastererPercent = plastererPercent, BonusForExtraPlasterer = 250 });
_postStorageContract.UpdElement(updatedPost);
var element = GetPostFromDatabaseByPostId(post.Id);
var element = GetPostFromDatabaseByPostId(updatedPost.Id);
Assert.That(element, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(element!.Configuration.Type, Is.EqualTo(typeof(PlastererPostConfiguration).Name));
Assert.That((element.Configuration as PlastererPostConfiguration)!.PlastererPercent, Is.EqualTo(plastererPercent));
Assert.That(element!.Configuration, Is.Not.Null);
Assert.That(element.Configuration.Rate, Is.EqualTo(800));
});
}
@@ -317,12 +312,12 @@ internal class PostStorageContractTests : BaseStorageContractTest
var painterPercent = 22.5;
var updatedPost = CreateModel(post.Id, config: new PainterPostConfiguration() { Rate = 1300, PainterPercent = painterPercent, BonusForExtraPainter = 350 });
_postStorageContract.UpdElement(updatedPost);
var element = GetPostFromDatabaseByPostId(post.Id);
var element = GetPostFromDatabaseByPostId(updatedPost.Id);
Assert.That(element, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(element!.Configuration.Type, Is.EqualTo(typeof(PainterPostConfiguration).Name));
Assert.That((element.Configuration as PainterPostConfiguration)!.PainterPercent, Is.EqualTo(painterPercent));
Assert.That(element!.Configuration, Is.Not.Null);
Assert.That(element.Configuration.Rate, Is.EqualTo(900));
});
}
@@ -336,12 +331,12 @@ internal class PostStorageContractTests : BaseStorageContractTest
var bonusForExtraCarpentry = 500;
var updatedPost = CreateModel(post.Id, config: new CarpenterPostConfiguration() { Rate = 1600, BonusForExtraCarpentry = bonusForExtraCarpentry });
_postStorageContract.UpdElement(updatedPost);
var element = GetPostFromDatabaseByPostId(post.Id);
var element = GetPostFromDatabaseByPostId(updatedPost.Id);
Assert.That(element, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(element!.Configuration.Type, Is.EqualTo(typeof(CarpenterPostConfiguration).Name));
Assert.That((element.Configuration as CarpenterPostConfiguration)!.BonusForExtraCarpentry, Is.EqualTo(bonusForExtraCarpentry));
Assert.That(element!.Configuration, Is.Not.Null);
Assert.That(element.Configuration.Rate, Is.EqualTo(1000));
});
}

View File

@@ -94,7 +94,7 @@ internal class ServiceStorageContractTests : BaseStorageContractTest
InsertServiceToDatabaseAndReturn(Guid.NewGuid().ToString(), "name 2");
var list = _serviceStorageContract.GetElementByServiceName(name);
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(2));
Assert.That(list, Has.Count.EqualTo(1));
}
[Test]

View File

@@ -8,6 +8,7 @@ using System.Text;
using System.Text.Json;
using TwoFromTheCasketDatabase;
using TwoFromTheCasketTest.Infrastructure;
using Microsoft.AspNetCore.Localization;
namespace TwoFromTheCasketTest.WebApiControllersTests;
@@ -26,7 +27,22 @@ internal class BaseWebApiControllerTest
public void OneTimeSetUp()
{
_webApplication = new CustomWebApplicationFactory<Program>();
HttpClient = _webApplication.CreateClient();
HttpClient = _webApplication
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
using var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new Serilog.LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
services.AddSingleton(loggerFactory);
});
})
.CreateClient();
var request = HttpClient.GetAsync("/login/user").GetAwaiter().GetResult();
var data = request.Content.ReadAsStringAsync().GetAwaiter().GetResult();

View File

@@ -72,7 +72,7 @@ internal class OrderControllerTest : BaseWebApiControllerTest
var orderModel = new OrderBindingModel
{
Id = Guid.NewGuid().ToString(),
Date = DateTime.UtcNow, // Используем UTC
Date = DateTime.UtcNow,
Status = StatusType.NotStarted,
RoomType = RoomType.Residential
};
@@ -81,7 +81,7 @@ internal class OrderControllerTest : BaseWebApiControllerTest
var response = await HttpClient.PostAsync("/api/orders/register", MakeContent(orderModel));
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
}
[Test]
@@ -101,7 +101,7 @@ internal class OrderControllerTest : BaseWebApiControllerTest
var response = await HttpClient.PutAsync("/api/orders/changeinfo", MakeContent(updatedModel));
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
}
[Test]
@@ -143,7 +143,7 @@ internal class OrderControllerTest : BaseWebApiControllerTest
var response = await HttpClient.PostAsync("/api/orders/register", MakeContent(invalidModel));
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]

View File

@@ -193,7 +193,7 @@ 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),
Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError),
"Type is incorrect");
Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest),
"Salary is incorrect");
@@ -226,8 +226,11 @@ internal class PostControllerTests : BaseWebApiControllerTest
Assert.That(actual.Id, Is.EqualTo(expected.PostId));
Assert.That(actual.PostName, Is.EqualTo(expected.PostName));
Assert.That(actual.PostType, Is.EqualTo(expected.PostType.ToString()));
Assert.That(JsonNode.Parse(actual.Configuration)!["Rate"]!.GetValue<double>(),
Is.EqualTo(expected.Configuration.Rate));
if (!string.IsNullOrEmpty(actual.Configuration))
{
Assert.That(JsonNode.Parse(actual.Configuration)!["Rate"]!.GetValue<double>(),
Is.EqualTo(expected.Configuration.Rate));
}
});
}
@@ -337,7 +340,7 @@ 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),
Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError),
"Type is incorrect");
Assert.That(responseWithSalaryIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest),
"Salary is incorrect");

View File

@@ -180,7 +180,8 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
{
//Arrange
var postId = Guid.NewGuid().ToString();
var post = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn(id: postId);
var configuration = new PostConfiguration { Rate = 100 };
var post = TwoFromTheCasketDbContext.InsertPostToDatabaseAndReturn(id: postId, configuration: configuration);
var master = TwoFromTheCasketDbContext.InsertMasterToDatabaseAndReturn(fio: "Иванов И.И.", postId: post.PostId);
TwoFromTheCasketDbContext.InsertOrderToDatabaseAndReturn(null);

View File

@@ -78,7 +78,7 @@ internal class ServiceControllerTests : BaseWebApiControllerTest
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => x.ServiceType == ServiceType.Plastering));
});
}
@@ -89,7 +89,7 @@ internal class ServiceControllerTests : BaseWebApiControllerTest
// Arrange
TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(Guid.NewGuid().ToString(), serviceName: "name1", masterId: _master.Id);
TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(Guid.NewGuid().ToString(), serviceName: "name2", masterId: _master.Id);
TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(Guid.NewGuid().ToString(), serviceName: "name3", masterId: Guid.NewGuid().ToString());
TwoFromTheCasketDbContext.InsertServiceToDatabaseAndReturn(Guid.NewGuid().ToString(), serviceName: "name3", masterId: _master.Id);
// Act
var response = await HttpClient.GetAsync($"/api/services/getmasterrecords?id={_master.Id}");

View File

@@ -1,44 +1,31 @@
using AutoMapper;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BindingModels;
using TwoFromTheCasketContratcs.BuisnessLogicsContracts;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.ViewModels;
namespace TwoFromTheCasketWebApi.Adapters;
internal class MasterAdapter : IMasterAdapter
internal class MasterAdapter(IMasterBuisnessLogicContract masterBusinessLogicContract, IStringLocalizer<Messages> localizer, ILogger<MasterAdapter> logger) : IMasterAdapter
{
private readonly IMasterBuisnessLogicContract _masterBuisnessLogicContract;
private readonly IMasterBuisnessLogicContract _masterBuisnessLogicContract = masterBusinessLogicContract;
private readonly ILogger _logger;
private readonly ILogger _logger = logger;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer = localizer;
private readonly IStringLocalizer<Messages> _localizer;
public MasterAdapter(IMasterBuisnessLogicContract masterBuisnessLogicContract, ILogger<MasterAdapter> logger, IStringLocalizer<Messages> localizer)
{
_masterBuisnessLogicContract = masterBuisnessLogicContract;
_logger = logger;
_localizer = localizer;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<MasterBindingModel, MasterDataModel>();
cfg.CreateMap<MasterDataModel, MasterViewModel>();
});
_mapper = new Mapper(config);
}
public MasterOperationResponse GetList(bool onlyActive)
{
try
{
return MasterOperationResponse.OK([.._masterBuisnessLogicContract.GetAllMasters().Select(x => _mapper.Map<MasterViewModel>(x))]);
return MasterOperationResponse.OK([.._masterBuisnessLogicContract.GetAllMasters().Select(x => CustomMapper.MapObject<MasterViewModel>(x))]);
}
catch (StorageException ex)
@@ -57,7 +44,7 @@ internal class MasterAdapter : IMasterAdapter
{
try
{
return MasterOperationResponse.OK(_mapper.Map<MasterViewModel>(_masterBuisnessLogicContract.GetMasterByData(data)));
return MasterOperationResponse.OK(CustomMapper.MapObject<MasterViewModel>(_masterBuisnessLogicContract.GetMasterByData(data)));
}
catch (ArgumentNullException ex)
{
@@ -88,7 +75,7 @@ internal class MasterAdapter : IMasterAdapter
{
return MasterOperationResponse.OK([
.. _masterBuisnessLogicContract.GetAllMastersByBirthDate(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), !onlyActive)
.Select(x => _mapper.Map<MasterViewModel>(x))
.Select(x => CustomMapper.MapObject < MasterViewModel >(x))
]);
}
catch (IncorrectDatesException ex)
@@ -116,7 +103,7 @@ internal class MasterAdapter : IMasterAdapter
{
return MasterOperationResponse.OK([
.. _masterBuisnessLogicContract.GetAllMastersByEmploymentDate(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), !onlyActive)
.Select(x => _mapper.Map<MasterViewModel>(x))
.Select(x => CustomMapper.MapObject < MasterViewModel >(x))
]);
}
catch (IncorrectDatesException ex)
@@ -143,7 +130,7 @@ internal class MasterAdapter : IMasterAdapter
try
{
return MasterOperationResponse.OK([.. _masterBuisnessLogicContract.
GetAllMastersByPost(postId, !onlyActive).Select(x => _mapper.Map<MasterViewModel>(x))]);
GetAllMastersByPost(postId, !onlyActive).Select(x => CustomMapper.MapObject < MasterViewModel >(x))]);
}
catch (ValidationException ex)
{
@@ -168,7 +155,7 @@ internal class MasterAdapter : IMasterAdapter
{
try
{
_masterBuisnessLogicContract.InsertMaster(_mapper.Map<MasterDataModel>(masterModel));
_masterBuisnessLogicContract.InsertMaster(CustomMapper.MapObject<MasterDataModel>(masterModel));
return MasterOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -202,7 +189,7 @@ internal class MasterAdapter : IMasterAdapter
{
try
{
_masterBuisnessLogicContract.UpdateMaster(_mapper.Map<MasterDataModel>(masterModel));
_masterBuisnessLogicContract.UpdateMaster(CustomMapper.MapObject<MasterDataModel>(masterModel));
return MasterOperationResponse.NoContent();
}
catch (ArgumentNullException ex)

View File

@@ -1,5 +1,4 @@
using AutoMapper;
using TwoFromTheCasketBuisnessLogic.Implementations;
using TwoFromTheCasketBuisnessLogic.Implementations;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BindingModels;
@@ -10,36 +9,24 @@ using TwoFromTheCasketContratcs.ViewModels;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketWebApi.Adapters;
internal class OrderAdapter : IOrderAdapter
internal class OrderAdapter(IOrderBuisnessLogicContract orderBuisnessLogicContract, ILogger logger, IStringLocalizer<Messages> localizer) : IOrderAdapter
{
private readonly IOrderBuisnessLogicContract _orderBuisnessLogicContract;
private readonly IOrderBuisnessLogicContract _orderBuisnessLogicContract = orderBuisnessLogicContract;
private readonly ILogger _logger;
private readonly ILogger _logger = logger;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public OrderAdapter(IOrderBuisnessLogicContract orderBuisnessLogicContract, ILogger<OrderAdapter> logger, IStringLocalizer<Messages> localizer)
{
_orderBuisnessLogicContract = orderBuisnessLogicContract;
_logger = logger;
_localizer = localizer;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<OrderBindingModel, OrderDataModel>();
cfg.CreateMap<OrderDataModel, OrderViewModel>();
});
_mapper = new Mapper(config);
}
private readonly IStringLocalizer<Messages> _localizer = localizer;
public OrderOperationResponse GetList()
{
try
{
return OrderOperationResponse.OK([.. _orderBuisnessLogicContract.GetAllOrder().Select(x => _mapper.Map<OrderViewModel>(x))]);
return OrderOperationResponse.OK([.. _orderBuisnessLogicContract.GetAllOrder().Select(x => CustomMapper.MapObject<OrderViewModel>(x))]);
}
catch (StorageException ex)
@@ -58,7 +45,7 @@ internal class OrderAdapter : IOrderAdapter
{
try
{
return OrderOperationResponse.OK(_mapper.Map<OrderViewModel>(_orderBuisnessLogicContract.GetOrderByData(data)));
return OrderOperationResponse.OK(CustomMapper.MapObjectWithNull<OrderViewModel>(_orderBuisnessLogicContract.GetOrderByData(data)));
}
catch (ArgumentNullException ex)
{
@@ -87,7 +74,7 @@ internal class OrderAdapter : IOrderAdapter
try
{
return OrderOperationResponse.OK(
_mapper.Map<OrderViewModel>(_orderBuisnessLogicContract.GetOrderByDate(fromDate.ToUniversalTime())));
CustomMapper.MapObject<OrderViewModel>(_orderBuisnessLogicContract.GetOrderByDate(fromDate.ToUniversalTime())));
}
catch (IncorrectDatesException)
@@ -113,7 +100,7 @@ internal class OrderAdapter : IOrderAdapter
{
try
{
_orderBuisnessLogicContract.InsertOrder(_mapper.Map<OrderDataModel>(orderModel));
_orderBuisnessLogicContract.InsertOrder(CustomMapper.MapObject<OrderDataModel>(orderModel));
return OrderOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -148,7 +135,7 @@ internal class OrderAdapter : IOrderAdapter
{
try
{
_orderBuisnessLogicContract.UpdateOrder(_mapper.Map<OrderDataModel>(orderModel));
_orderBuisnessLogicContract.UpdateOrder(CustomMapper.MapObject<OrderDataModel>(orderModel));
return OrderOperationResponse.NoContent();
}
catch (ArgumentNullException ex)

View File

@@ -1,5 +1,4 @@
using AutoMapper;
using System.Text.Json;
using System.Text.Json;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BindingModels;
@@ -9,41 +8,26 @@ using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.ViewModels;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.Mapper;
namespace TwoFromTheCasketWebApi.Adapters;
internal class PostAdapter : IPostAdapter
internal class PostAdapter(IPostBuisnessLogicContract postBusinessLogicContract, ILogger logger, IStringLocalizer<Messages> localizer) : IPostAdapter
{
private readonly IPostBuisnessLogicContract _postBusinessLogicContract;
private readonly IPostBuisnessLogicContract _postBusinessLogicContract = postBusinessLogicContract;
private readonly ILogger _logger;
private readonly ILogger _logger = logger;
private readonly Mapper _mapper;
private readonly JsonSerializerOptions _jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
private readonly IStringLocalizer<Messages> _localizer;
public PostAdapter(IPostBuisnessLogicContract postBusinessLogicContract, ILogger<PostAdapter> logger, IStringLocalizer<Messages> localizer)
{
_postBusinessLogicContract = postBusinessLogicContract;
_logger = logger;
_localizer = localizer;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<PostBindingModel, PostDataModel>();
cfg.CreateMap<PostDataModel, PostViewModel>()
.ForMember(x => x.Configuration, x =>
x.MapFrom(src =>
JsonSerializer.Serialize(src.ConfigurationModel, _jsonSerializerOptions)));
});
_mapper = new Mapper(config);
}
private readonly IStringLocalizer<Messages> _localizer = localizer;
public PostOperationResponse GetList()
{
try
{
return PostOperationResponse.OK([
.. _postBusinessLogicContract.GetAllPosts().Select(x => _mapper.Map<PostViewModel>(x))
.. _postBusinessLogicContract.GetAllPosts().Select(x => CustomMapper.MapObject<PostViewModel>(x))
]);
}
@@ -65,7 +49,7 @@ internal class PostAdapter : IPostAdapter
try
{
return PostOperationResponse.OK([
.. _postBusinessLogicContract.GetAllDataOfPost(id).Select(x => _mapper.Map<PostViewModel>(x))
.. _postBusinessLogicContract.GetAllDataOfPost(id).Select(x => CustomMapper.MapObject<PostViewModel>(x))
]);
}
catch (ArgumentNullException ex)
@@ -95,7 +79,7 @@ internal class PostAdapter : IPostAdapter
{
try
{
return PostOperationResponse.OK(_mapper.Map<PostViewModel>(_postBusinessLogicContract.GetPostByData(data)));
return PostOperationResponse.OK(CustomMapper.MapObject<PostViewModel>(_postBusinessLogicContract.GetPostByData(data)));
}
catch (ArgumentNullException ex)
{
@@ -129,7 +113,7 @@ internal class PostAdapter : IPostAdapter
{
try
{
_postBusinessLogicContract.InsertPost(_mapper.Map<PostDataModel>(postModel));
_postBusinessLogicContract.InsertPost(CustomMapper.MapObject<PostDataModel>(postModel));
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -164,7 +148,7 @@ internal class PostAdapter : IPostAdapter
{
try
{
_postBusinessLogicContract.UpdatePost(_mapper.Map<PostDataModel>(postModel));
_postBusinessLogicContract.UpdatePost(CustomMapper.MapObject<PostDataModel>(postModel));
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)

View File

@@ -1,39 +1,30 @@
using AutoMapper;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BuisnessLogicsContracts;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.ViewModels;
namespace TwoFromTheCasketWebApi.Adapters;
internal class ReportAdapter : IReportAdapter
internal class ReportAdapter(IReportContract reportContract, IStringLocalizer<Messages> localizer, ILogger<MasterAdapter> logger) : IReportAdapter
{
private readonly IReportContract _reportContract;
private readonly IReportContract _reportContract = reportContract;
private readonly ILogger _logger = logger;
private readonly IStringLocalizer<Messages> _localizer = localizer;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public ReportAdapter(IReportContract reportContract, ILogger<MasterAdapter> logger)
{
_reportContract = reportContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ServiceHistoryDataModel, ServiceHistoryViewModel>();
cfg.CreateMap<ServiceWithHistoryDataModel, ServiceWithHistoryViewModel>();
cfg.CreateMap<OrderDataModel, OrderViewModel>();
cfg.CreateMap<MasterSalaryByPeriodDataModel, MasterSalaryByPeriodViewModel>();
});
_mapper = new Mapper(config);
}
public async Task<ReportOperationResponse> CreateDocumentOrdersByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var stream = await _reportContract.CreateDocumentOrdersByPeriodAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct);
var stream = await _reportContract.CreateDocumentOrdersByPeriodAsync(dateStart, dateFinish, ct);
return SendStream(stream, "orders_by_period.xlsx");
}
catch (IncorrectDatesException ex)
@@ -58,40 +49,11 @@ internal class ReportAdapter : IReportAdapter
}
}
public async Task<ReportOperationResponse> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var stream = await _reportContract.CreateDocumentServicesWithHistoryAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct);
return SendStream(stream, "services.docx");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException in CreateDocumentServicesWithHistoryAsync");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var stream = await _reportContract.CreateDocumentSalaryByPeriodAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct);
var stream = await _reportContract.CreateDocumentSalaryByPeriodAsync(dateStart, dateFinish, ct);
return SendStream(stream, "salary_by_period.pdf");
}
catch (IncorrectDatesException ex)
@@ -120,8 +82,8 @@ internal class ReportAdapter : IReportAdapter
{
try
{
var orders = await _reportContract.GetDataOrderByPeriodAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct);
return ReportOperationResponse.OK(orders.Select(x => _mapper.Map<OrderViewModel>(x)).ToList());
var orders = await _reportContract.GetDataOrderByPeriodAsync(dateStart, dateFinish, ct);
return ReportOperationResponse.OK(orders.Select(x => CustomMapper.MapObject<OrderViewModel>(x)).ToList());
}
catch (IncorrectDatesException ex)
{
@@ -145,41 +107,12 @@ internal class ReportAdapter : IReportAdapter
}
}
public async Task<ReportOperationResponse> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var services = await _reportContract.GetDataServicesWithHistoryAsync(dateStart.ToUniversalTime(), dateFinish.ToUniversalTime(), ct);
return ReportOperationResponse.OK(services.Select(x => _mapper.Map<ServiceWithHistoryViewModel>(x)).ToList());
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException in GetDataServicesWithHistoryAsync");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var salaries = await _reportContract.GetDataSalaryByPeriodAsync(dateStart.ToUniversalTime() , dateFinish.ToUniversalTime(), ct);
return ReportOperationResponse.OK(salaries.Select(x => _mapper.Map<MasterSalaryByPeriodViewModel>(x)).ToList());
var salaries = await _reportContract.GetDataSalaryByPeriodAsync(dateStart, dateFinish, ct);
return ReportOperationResponse.OK(salaries.Select(x => CustomMapper.MapObject<MasterSalaryByPeriodViewModel>(x)).ToList());
}
catch (IncorrectDatesException ex)
{
@@ -203,6 +136,65 @@ internal class ReportAdapter : IReportAdapter
}
}
public async Task<ReportOperationResponse> GetDataServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var data = await _reportContract.GetDataServicesWithHistoryAsync(dateStart, dateFinish, ct);
var viewModels = data.Select(x => CustomMapper.MapObject<ServiceWithHistoryViewModel>(x)).ToList();
return ReportOperationResponse.OK(viewModels);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException in GetDataServicesWithHistoryAsync");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in GetDataServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> CreateDocumentServicesWithHistoryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
var stream = await _reportContract.CreateDocumentServicesWithHistoryAsync(dateStart, dateFinish, ct);
return SendStream(stream, "services_with_history.docx");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException in CreateDocumentServicesWithHistoryAsync");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException?.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in CreateDocumentServicesWithHistoryAsync: {message}", ex.Message);
return ReportOperationResponse.InternalServerError(ex.Message);
}
}
private static ReportOperationResponse SendStream(Stream stream, string fileName)
{
stream.Position = 0;

View File

@@ -1,56 +1,41 @@
using AutoMapper;
using TwoFromTheCasketBuisnessLogic.Implementations;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BuisnessLogicsContracts;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.ViewModels;
namespace TwoFromTheCasketWebApi.Adapters;
internal class SalaryAdapter : ISalaryAdapter
internal class SalaryAdapter(ISalaryBuisnessLogicContract salaryBusinessLogicContract, IStringLocalizer<Messages> localizer, ILogger<SalaryAdapter> logger) : ISalaryAdapter
{
private readonly ISalaryBuisnessLogicContract _salaryBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public SalaryAdapter(ISalaryBuisnessLogicContract salaryBusinessLogicContract, ILogger<SalaryAdapter> logger)
{
_salaryBusinessLogicContract = salaryBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SalaryDataModel, SalaryViewModel>()
.ForMember(dest => dest.SalarySize, opt => opt.MapFrom(src => src.Salary))
.ForMember(dest => dest.Id, opt => opt.Ignore());
});
_mapper = new Mapper(config);
}
private readonly ISalaryBuisnessLogicContract _salaryBusinessLogicContract = salaryBusinessLogicContract;
private readonly ILogger _logger = logger;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate)
{
try
{
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriod(fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => _mapper.Map<SalaryViewModel>(x))]);
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriod(fromDate.ToUniversalTime(), toDate.ToUniversalTime()).Select(x => CustomMapper.MapObject<SalaryViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
return SalaryOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
return SalaryOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDates"].Value, ex.Message));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
return SalaryOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -63,23 +48,27 @@ internal class SalaryAdapter : ISalaryAdapter
{
try
{
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriodByMaster(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), masterId).Select(x => _mapper.Map<SalaryViewModel>(x))]);
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriodByMaster(fromDate.ToUniversalTime(), toDate.ToUniversalTime(), masterId).Select(x => CustomMapper.MapObject<SalaryViewModel>(x))]);
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return SalaryOperationResponse.BadRequest(_localizer["AdapterMessageDataIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
return SalaryOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
return SalaryOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDates"].Value, ex.Message));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
return SalaryOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -95,16 +84,25 @@ internal class SalaryAdapter : ISalaryAdapter
_salaryBusinessLogicContract.CalculateSalaryByMonth(date.ToUniversalTime());
return SalaryOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return SalaryOperationResponse.BadRequest(_localizer["AdapterMessageDataIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return SalaryOperationResponse.NotFound($"Element not found: {ex.Message}");
return SalaryOperationResponse.NotFound(string.Format(_localizer["AdapterMessageNotFoundElementByData"].Value, date));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
return SalaryOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{

View File

@@ -1,7 +1,4 @@
using AutoMapper;
using Microsoft.OpenApi.Any;
using Moq;
using TwoFromTheCasketBuisnessLogic.Implementations;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.AdapterContracts;
using TwoFromTheCasketContratcs.AdapterContracts.OperationResponses;
using TwoFromTheCasketContratcs.BindingModels;
@@ -9,46 +6,28 @@ using TwoFromTheCasketContratcs.BuisnessLogicsContracts;
using TwoFromTheCasketContratcs.DataModels;
using TwoFromTheCasketContratcs.Enums;
using TwoFromTheCasketContratcs.Exceptions;
using TwoFromTheCasketContratcs.ViewModels;
using TwoFromTheCasketDatabase.Models;
using Microsoft.Extensions.Localization;
using TwoFromTheCasketContratcs.Mapper;
using TwoFromTheCasketContratcs.Resources;
using TwoFromTheCasketContratcs.ViewModels;
namespace TwoFromTheCasketWebApi.Adapters;
internal class ServiceAdapter : IServiceAdapter
internal class ServiceAdapter(IServiceBuisnessLogicContract serviceBuisnessLogicContract, IStringLocalizer<Messages> localizer, ILogger<ServiceAdapter> logger) : IServiceAdapter
{
private readonly IServiceBuisnessLogicContract _serviceBuisnessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public ServiceAdapter(IServiceBuisnessLogicContract serviceBuisnessLogicContract, ILogger<MasterAdapter> logger, IStringLocalizer<Messages> localizer)
{
_serviceBuisnessLogicContract = serviceBuisnessLogicContract;
_logger = logger;
_localizer = localizer;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ServiceBindingModel, ServiceDataModel>();
cfg.CreateMap<ServiceDataModel, ServiceBindingModel>();
cfg.CreateMap<ServiceDataModel, ServiceViewModel>();
});
_mapper = new Mapper(config);
}
private readonly IServiceBuisnessLogicContract _serviceBuisnessLogicContract = serviceBuisnessLogicContract;
private readonly ILogger _logger = logger;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public ServiceOperationResponse GetList(bool onlyActive)
{
try
{
return ServiceOperationResponse.OK([.. _serviceBuisnessLogicContract.GetAllServices(It.IsAny<bool>()).Select(x => _mapper.Map<ServiceViewModel>(x))]);
return ServiceOperationResponse.OK([.. _serviceBuisnessLogicContract.GetAllServices(!onlyActive).Select(x => CustomMapper.MapObject<ServiceViewModel>(x))]);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.InternalServerError($"Errorwhile working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -62,18 +41,17 @@ internal class ServiceAdapter : IServiceAdapter
try
{
return ServiceOperationResponse.OK([.. _serviceBuisnessLogicContract.
GetServicesByServiceType(serviceType, !onlyActive).Select(x => _mapper.Map<ServiceViewModel>(x))]);
GetServicesByServiceType(serviceType, !onlyActive).Select(x => CustomMapper.MapObject<ServiceViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ServiceOperationResponse.BadRequest($"{_localizer["ValidationExceptionMessageIncorrectField"]} {ex.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.InternalServerError(
$"Error while working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -87,18 +65,22 @@ internal class ServiceAdapter : IServiceAdapter
try
{
return ServiceOperationResponse.OK([.. _serviceBuisnessLogicContract.
GetServicesByMasterId(masterId, !onlyActive).Select(x => _mapper.Map<ServiceViewModel>(x))]);
GetServicesByMasterId(masterId, !onlyActive).Select(x => CustomMapper.MapObject<ServiceViewModel>(x))]);
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ServiceOperationResponse.BadRequest(_localizer["AdapterMessageDataIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ServiceOperationResponse.BadRequest($"{_localizer["ValidationExceptionMessageIncorrectField"]} {ex.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.InternalServerError(
$"Error while working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.InternalServerError(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -111,18 +93,18 @@ internal class ServiceAdapter : IServiceAdapter
{
try
{
_serviceBuisnessLogicContract.InsertService(_mapper.Map<ServiceDataModel>(serviceModel));
_serviceBuisnessLogicContract.InsertService(CustomMapper.MapObject<ServiceDataModel>(serviceModel));
return ServiceOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ServiceOperationResponse.BadRequest(_localizer["ValidationExceptionMessageEmptyField"]);
return ServiceOperationResponse.BadRequest(_localizer["AdapterMessageDataIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ServiceOperationResponse.BadRequest($"{_localizer["ValidationExceptionMessageIncorrectField"]} {ex.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (ElementExistsException ex)
{
@@ -132,8 +114,7 @@ internal class ServiceAdapter : IServiceAdapter
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.BadRequest(
$"Error while working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -145,23 +126,23 @@ internal class ServiceAdapter : IServiceAdapter
{
try
{
_serviceBuisnessLogicContract.UpdateService(_mapper.Map<ServiceDataModel>(serviceModel));
_serviceBuisnessLogicContract.UpdateService(CustomMapper.MapObject<ServiceDataModel>(serviceModel));
return ServiceOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ServiceOperationResponse.BadRequest(_localizer["ValidationExceptionMessageEmptyField"]);
return ServiceOperationResponse.BadRequest(_localizer["AdapterMessageDataIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ServiceOperationResponse.BadRequest($"{_localizer["ValidationExceptionMessageIncorrectField"]} {ex.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ServiceOperationResponse.BadRequest($"{_localizer["ElementNotFoundExceptionMessage"]} {serviceModel.Id}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageNotFoundElementById"].Value, serviceModel.Id));
}
catch (ElementExistsException ex)
{
@@ -171,13 +152,12 @@ internal class ServiceAdapter : IServiceAdapter
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ServiceOperationResponse.BadRequest($"Element by id: {serviceModel.Id} was deleted");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageElementWasDeleted"].Value, serviceModel.Id));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.BadRequest(
$"Error while working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{
@@ -196,28 +176,27 @@ internal class ServiceAdapter : IServiceAdapter
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ServiceOperationResponse.BadRequest(_localizer["ValidationExceptionMessageEmptyField"]);
return ServiceOperationResponse.BadRequest(_localizer["AdapterMessageIdIsEmpty"].Value);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ServiceOperationResponse.BadRequest($"{_localizer["ValidationExceptionMessageIncorrectField"]} {ex.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageIncorrectDataTransmitted"].Value, ex.Message));
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ServiceOperationResponse.BadRequest($"{_localizer["ElementNotFoundExceptionMessage"]} {id}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageNotFoundElementById"].Value, id));
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ServiceOperationResponse.BadRequest($"Element by id: {id} was deleted");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageElementWasDeleted"].Value, id));
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ServiceOperationResponse.BadRequest(
$"Error while working with data storage: {ex.InnerException!.Message}");
return ServiceOperationResponse.BadRequest(string.Format(_localizer["AdapterMessageErrorWhileWorkingWithStorage"].Value, ex.InnerException!.Message));
}
catch (Exception ex)
{