From 3791fac299006912392a28fe94094d0bdf665525 Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 11:22:30 +0400 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BC=D0=B5=D0=BD=D0=B0=20public=20?= =?UTF-8?q?=D0=BD=D0=B0=20internal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IClientBusinessLogicContract.cs | 2 +- .../IEmployeeBusinessLogicContract.cs | 2 +- .../IPostBusinessLogicContract.cs | 2 +- .../BusinessLogicContracts/IReportContract.cs | 2 +- .../ISalaryBusinessLogicContract.cs | 2 +- .../ISaleBusinessLogicContract.cs | 2 +- .../ITourBusinessLogicContract.cs | 2 +- .../DataModels/ClientDataModel.cs | 16 +- .../DataModels/EmployeeDataModel.cs | 26 +- .../DataModels/PostDataModel.cs | 23 +- .../DataModels/SalaryDataModel.cs | 12 +- .../DataModels/SaleDataModel.cs | 27 ++- .../DataModels/SaleTourDataModel.cs | 18 +- .../DataModels/TourDataModel.cs | 18 +- .../DataModels/TourHistoryDataModel.cs | 12 +- .../Exceptions/ElementDeletedException.cs | 11 +- .../Exceptions/ElementExistsException.cs | 17 +- .../Exceptions/ElementNotFoundException .cs | 14 +- .../Exceptions/IncorrectDatesException .cs | 12 +- .../Exceptions/NullListException.cs | 12 - .../Exceptions/StorageException .cs | 10 +- .../Infrastructure/IValidation.cs | 8 +- .../MagicCarpetContracts.csproj | 23 ++ .../Resources/Messages.Designer.cs | 225 ++++++++++++++++++ .../Resources/Messages.resx | 174 ++++++++++++++ .../IClientStorageContract.cs | 2 +- .../IEmployeeStorageContract.cs | 2 +- .../StoragesContracts/IPostStorageContract.cs | 2 +- .../ISalaryStorageContract.cs | 2 +- .../StoragesContracts/ISaleStorageContract.cs | 2 +- .../StoragesContracts/ITourStorageContract.cs | 2 +- .../Implementations/ClientStorageContract.cs | 32 +-- .../EmployeeStorageContract.cs | 31 +-- .../MagicCarpetWebApi/Program.cs | 26 ++ 34 files changed, 621 insertions(+), 152 deletions(-) delete mode 100644 MagicCarpetProject/MagicCarpetContracts/Exceptions/NullListException.cs create mode 100644 MagicCarpetProject/MagicCarpetContracts/Resources/Messages.Designer.cs create mode 100644 MagicCarpetProject/MagicCarpetContracts/Resources/Messages.resx diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IClientBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IClientBusinessLogicContract.cs index b3b53b0..95440ae 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IClientBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IClientBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface IClientBusinessLogicContract +internal interface IClientBusinessLogicContract { List GetAllClients(); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IEmployeeBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IEmployeeBusinessLogicContract.cs index 1e54281..c4341af 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IEmployeeBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IEmployeeBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface IEmployeeBusinessLogicContract +internal interface IEmployeeBusinessLogicContract { List GetAllEmployees(bool onlyActive = true); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IPostBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IPostBusinessLogicContract.cs index 0b1c47d..558b41d 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IPostBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IPostBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface IPostBusinessLogicContract +internal interface IPostBusinessLogicContract { List GetAllPosts(); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IReportContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IReportContract.cs index fc34c30..4d25ced 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IReportContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/IReportContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BusinessLogicContracts; -public interface IReportContract +internal interface IReportContract { Task> GetDataToursHistoryAsync(CancellationToken ct); Task CreateDocumentToursHistoryAsync(CancellationToken ct); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISalaryBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISalaryBusinessLogicContract.cs index a3f2747..ec3b463 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISalaryBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISalaryBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface ISalaryBusinessLogicContract +internal interface ISalaryBusinessLogicContract { List GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISaleBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISaleBusinessLogicContract.cs index 934d4fa..36ec76e 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISaleBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ISaleBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface ISaleBusinessLogicContract +internal interface ISaleBusinessLogicContract { List GetAllSalesByPeriod(DateTime fromDate, DateTime toDate); diff --git a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ITourBusinessLogicContract.cs b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ITourBusinessLogicContract.cs index b5f1772..ba3d04e 100644 --- a/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ITourBusinessLogicContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/BusinessLogicContracts/ITourBusinessLogicContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.BuisnessLogicContracts; -public interface ITourBusinessLogicContract +internal interface ITourBusinessLogicContract { List GetAllTours(); diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs index 8b4a400..607eae2 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/ClientDataModel.cs @@ -9,10 +9,12 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using ValidationException = MagicCarpetContracts.Exceptions.ValidationException; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; namespace MagicCarpetContracts.DataModels; -public class ClientDataModel(string id, string fIO, string phoneNumber, double discountSize) : IValidation +internal class ClientDataModel(string id, string fIO, string phoneNumber, double discountSize) : IValidation { public string Id { get; private set; } = id; @@ -22,21 +24,21 @@ public class ClientDataModel(string id, string fIO, string phoneNumber, double d public double DiscountSize { get; private set; } = discountSize; - public void Validate() + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) - throw new ValidationException("Field Id is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id")); if (!Id.IsGuid()) - throw new ValidationException("The value in the field Id is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id")); if (FIO.IsEmpty()) - throw new ValidationException("Field FIO is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "FIO")); if (PhoneNumber.IsEmpty()) - throw new ValidationException("Field PhoneNumber is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PhoneNumber")); if (!Regex.IsMatch(PhoneNumber, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$")) - throw new ValidationException("Field PhoneNumber is not a phone number"); + throw new ValidationException(localizer["ValidationExceptionIncorrectPhoneNumber"]); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs index 0cd84fa..e6ebeec 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/EmployeeDataModel.cs @@ -1,7 +1,9 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Linq; @@ -11,7 +13,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.DataModels; -public class EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation +internal class EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation { private readonly PostDataModel? _post; @@ -40,16 +42,16 @@ public class EmployeeDataModel(string id, string fio, string email, string postI public EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate) : this(id, fio, email, postId, birthDate, employmentDate, false) { } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) - throw new ValidationException("Field Id is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id")); if (!Id.IsGuid()) - throw new ValidationException("The value in the field Id is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id")); if (FIO.IsEmpty()) - throw new ValidationException("Field FIO is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "FIO")); if (Email.IsEmpty()) throw new ValidationException("Field Email is empty"); @@ -58,18 +60,20 @@ public class EmployeeDataModel(string id, string fio, string email, string postI throw new ValidationException("Field Email is not a valid email address"); if (PostId.IsEmpty()) - throw new ValidationException("Field PostId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostId")); if (!PostId.IsGuid()) - throw new ValidationException("The value in the field PostId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "PostId")); if (BirthDate.Date > DateTime.Now.AddYears(-18).Date) - throw new ValidationException($"Only adults can be hired (BirthDate = {BirthDate.ToShortDateString()})"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageMinorsBirthDate"], BirthDate.ToShortDateString())); if (EmploymentDate.Date < BirthDate.Date) - throw new ValidationException("The date of employment cannot be less than the date of birth"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmploymentDateAndBirthDate"], + EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString())); - if ((EmploymentDate - BirthDate).TotalDays / 365 < 18) - throw new ValidationException($"Only adults can be hired (EmploymentDate - {EmploymentDate.ToShortDateString()}, BirthDate - {BirthDate.ToShortDateString()})"); + if ((EmploymentDate - BirthDate).TotalDays / 365 < 18) + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageMinorsEmploymentDate"], + EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString())); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs index 938ec93..c8a9608 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/PostDataModel.cs @@ -11,10 +11,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; namespace MagicCarpetContracts.DataModels; -public class PostDataModel(string postId, string postName, PostType postType, PostConfiguration configuration) : IValidation +internal class PostDataModel(string postId, string postName, PostType postType, PostConfiguration configuration) : IValidation { public string Id { get; private set; } = postId; public string PostName { get; private set; } = postName; @@ -35,19 +37,24 @@ public class PostDataModel(string postId, string postName, PostType postType, Po } } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) - throw new ValidationException("Field Id is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id")); + if (!Id.IsGuid()) - throw new ValidationException("The value in the field Id is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id")); + if (PostName.IsEmpty()) - throw new ValidationException("Field PostName is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostName")); + if (PostType == PostType.None) - throw new ValidationException("Field PostType is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostType")); + if (ConfigurationModel is null) - throw new ValidationException("Field ConfigurationModel is not initialized"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotInitialized"], "ConfigurationModel")); + if (ConfigurationModel!.Rate <= 0) - throw new ValidationException("Field Rate is less or equal zero"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Rate")); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs index dc19dc6..e4df071 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SalaryDataModel.cs @@ -1,6 +1,8 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Linq; @@ -9,7 +11,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.DataModels; -public class SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary) : IValidation +internal class SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary) : IValidation { private readonly EmployeeDataModel? _employee; public string EmployeeId { get; private set; } = employeeId; @@ -25,15 +27,15 @@ public class SalaryDataModel(string employeeId, DateTime salaryDate, double empl _employee = employee; } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (EmployeeId.IsEmpty()) - throw new ValidationException("Field EmployeeId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "EmployeeId")); if (!EmployeeId.IsGuid()) - throw new ValidationException("The value in the field EmployeeId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "EmployeeId")); if (Salary <= 0) - throw new ValidationException("Field Salary is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Salary")); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs index cec1d30..cce55bb 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleDataModel.cs @@ -2,6 +2,8 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Linq; @@ -10,7 +12,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.DataModels; -public class SaleDataModel : IValidation +internal class SaleDataModel : IValidation { private readonly ClientDataModel? _client; @@ -83,27 +85,32 @@ public class SaleDataModel : IValidation public SaleDataModel(string id, string employeeId, string? clientId, int discountType, List tours) : this(id, employeeId, clientId, (DiscountType)discountType, false, tours) { } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) - throw new ValidationException("Field Id is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id")); if (!Id.IsGuid()) - throw new ValidationException("The value in the field Id is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id")); if (EmployeeId.IsEmpty()) - throw new ValidationException("Field EmployeeId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "WorkerId")); if (!EmployeeId.IsGuid()) - throw new ValidationException("The value in the field EmployeeId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "WorkerId")); if (!ClientId?.IsGuid() ?? !ClientId?.IsEmpty() ?? false) - throw new ValidationException("The value in the field BuyerId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "BuyerId")); if (Sum <= 0) - throw new ValidationException("Field Sum is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Sum")); - if ((Tours?.Count ?? 0) == 0) - throw new ValidationException("The sale must include tours"); + if (Tours is null) + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotInitialized"], "Tours")); + + if (Tours.Count == 0) + throw new ValidationException(localizer["ValidationExceptionMessageNoProductsInSale"]); + + Tours.ForEach(x => x.Validate(localizer)); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs index ec486c2..88574af 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/SaleTourDataModel.cs @@ -1,6 +1,8 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Diagnostics; @@ -10,7 +12,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.DataModels; -public class SaleTourDataModel(string saleId, string tourId, int count, double price) : IValidation +internal class SaleTourDataModel(string saleId, string tourId, int count, double price) : IValidation { private readonly TourDataModel? _tour; @@ -29,24 +31,24 @@ public class SaleTourDataModel(string saleId, string tourId, int count, double p _tour = tour; } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (SaleId.IsEmpty()) - throw new ValidationException("Field SaleId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SaleId")); if (!SaleId.IsGuid()) - throw new ValidationException("The value in the field SaleId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SaleId")); if (TourId.IsEmpty()) - throw new ValidationException("Field ProductId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "ITourIdd")); if (!TourId.IsGuid()) - throw new ValidationException("The value in the field ProductId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "TourId")); if (Count <= 0) - throw new ValidationException("Field Count is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Count")); if (Price <= 0) - throw new ValidationException("Field Price is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price")); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs index 04a7b05..164c04b 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourDataModel.cs @@ -2,6 +2,8 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Diagnostics; @@ -12,7 +14,7 @@ using System.Xml.Linq; namespace MagicCarpetContracts.DataModels; -public class TourDataModel(string id, string tourName, string tourCountry, double price, TourType tourType) : IValidation +internal class TourDataModel(string id, string tourName, string tourCountry, double price, TourType tourType) : IValidation { public string Id { get; private set; } = id; public string TourName { get; private set; } = tourName; @@ -20,19 +22,19 @@ public class TourDataModel(string id, string tourName, string tourCountry, doubl public double Price { get; private set; } = price; public TourType TourType { get; private set; } = tourType; - public void Validate() + public void Validate(IStringLocalizer localizer) { if (Id.IsEmpty()) - throw new ValidationException("Field Id is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id")); if (!Id.IsGuid()) - throw new ValidationException("The value in the field Id is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id")); if (TourName.IsEmpty()) - throw new ValidationException("Field TourName is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "TourName")); if (TourCountry.IsEmpty()) - throw new ValidationException("Field TourCountry is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "TourCountry")); if (Price <= 0) - throw new ValidationException("Field Price is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price")); if (TourType == TourType.None) - throw new ValidationException("Field Type is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "TourType")); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs index 691aa05..ac636ee 100644 --- a/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs +++ b/MagicCarpetProject/MagicCarpetContracts/DataModels/TourHistoryDataModel.cs @@ -1,6 +1,8 @@ using MagicCarpetContracts.Exceptions; using MagicCarpetContracts.Extensions; using MagicCarpetContracts.Infrastructure; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Linq; @@ -9,7 +11,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.DataModels; -public class TourHistoryDataModel(string tourId, double oldPrice) : IValidation +internal class TourHistoryDataModel(string tourId, double oldPrice) : IValidation { private readonly TourDataModel? _tour; @@ -27,15 +29,15 @@ public class TourHistoryDataModel(string tourId, double oldPrice) : IValidation _tour = tour; } - public void Validate() + public void Validate(IStringLocalizer localizer) { if (TourId.IsEmpty()) - throw new ValidationException("Field TourId is empty"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "TourId")); if (!TourId.IsGuid()) - throw new ValidationException("The value in the field TourId is not a unique identifier"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "TourId")); if (OldPrice <= 0) - throw new ValidationException("Field OldPrice is less than or equal to 0"); + throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "OldPrice")); } } diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementDeletedException.cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementDeletedException.cs index e06a7ed..d76a4b0 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementDeletedException.cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementDeletedException.cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +8,6 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; -public class ElementDeletedException : Exception -{ - public ElementDeletedException(string id) : base($"Cannot modify a deleted item (id: {id})") { } -} +internal class ElementDeletedException(string id, IStringLocalizer localizer) + : Exception(string.Format(localizer["ElementDeletedExceptionMessage"], id)) +{ } diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementExistsException.cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementExistsException.cs index 8d4f5a2..4f17938 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementExistsException.cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementExistsException.cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,15 +8,10 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; -public class ElementExistsException : Exception +internal class ElementExistsException(string paramName, string paramValue, IStringLocalizer localizer) : + Exception(string.Format(localizer["ElementExistsExceptionMessage"], paramValue, paramName)) { - public string ParamName { get; private set; } + public string ParamName { get; private set; } = paramName; - public string ParamValue { get; private set; } - - public ElementExistsException(string paramName, string paramValue) : base($"There is already an element with value{paramValue} of parameter {paramName}") - { - ParamName = paramName; - ParamValue = paramValue; - } + public string ParamValue { get; private set; } = paramValue; } diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs index ed82472..c949126 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/ElementNotFoundException .cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,12 +8,8 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; -public class ElementNotFoundException : Exception +internal class ElementNotFoundException(string value, IStringLocalizer localizer) : + Exception(string.Format(localizer["ElementNotFoundExceptionMessage"], value)) { - public string Value { get; private set; } - - public ElementNotFoundException(string value) : base($"Element not found at value = {value}") - { - Value = value; - } + public string Value { get; private set; } = value; } diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/IncorrectDatesException .cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/IncorrectDatesException .cs index c9b3600..79406d1 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/IncorrectDatesException .cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/IncorrectDatesException .cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,8 +8,6 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; -public class IncorrectDatesException : Exception -{ - public IncorrectDatesException(DateTime start, DateTime end) : base($"The end date must be later than the start date.. StartDate: " + - $"{start:dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}") { } -} +internal class IncorrectDatesException(DateTime start, DateTime end, IStringLocalizer localizer) : + Exception(string.Format(localizer["IncorrectDatesExceptionMessage"], start.ToShortDateString(), end.ToShortDateString())) +{ } diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/NullListException.cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/NullListException.cs deleted file mode 100644 index 64ca6ae..0000000 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/NullListException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MagicCarpetContracts.Exceptions; - -public class NullListException : Exception -{ - public NullListException() : base("The returned list is null") { } -} diff --git a/MagicCarpetProject/MagicCarpetContracts/Exceptions/StorageException .cs b/MagicCarpetProject/MagicCarpetContracts/Exceptions/StorageException .cs index d879520..87b1145 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Exceptions/StorageException .cs +++ b/MagicCarpetProject/MagicCarpetContracts/Exceptions/StorageException .cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +8,5 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Exceptions; -public class StorageException : Exception -{ - public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex) { } -} +internal class StorageException(Exception ex, IStringLocalizer localizer) : Exception(string.Format(localizer["StorageExceptionMessage"], ex.Message), ex) +{ } diff --git a/MagicCarpetProject/MagicCarpetContracts/Infrastructure/IValidation.cs b/MagicCarpetProject/MagicCarpetContracts/Infrastructure/IValidation.cs index 0ec8803..1aeb1ce 100644 --- a/MagicCarpetProject/MagicCarpetContracts/Infrastructure/IValidation.cs +++ b/MagicCarpetProject/MagicCarpetContracts/Infrastructure/IValidation.cs @@ -1,4 +1,6 @@ -using System; +using MagicCarpetContracts.Resources; +using Microsoft.Extensions.Localization; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,8 +8,8 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.Infrastructure; -public interface IValidation +internal interface IValidation { - void Validate(); + void Validate(IStringLocalizer localizer); } diff --git a/MagicCarpetProject/MagicCarpetContracts/MagicCarpetContracts.csproj b/MagicCarpetProject/MagicCarpetContracts/MagicCarpetContracts.csproj index 08494b9..ab87367 100644 --- a/MagicCarpetProject/MagicCarpetContracts/MagicCarpetContracts.csproj +++ b/MagicCarpetProject/MagicCarpetContracts/MagicCarpetContracts.csproj @@ -10,6 +10,29 @@ + + + + True + True + Messages.resx + + + + + + ResXFileCodeGenerator + Messages.Designer.cs + + + + + + + + + + diff --git a/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.Designer.cs b/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.Designer.cs new file mode 100644 index 0000000..70acebd --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.Designer.cs @@ -0,0 +1,225 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace MagicCarpetContracts.Resources { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Messages { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Messages() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MagicCarpetContracts.Resources.Messages", typeof(Messages).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Ищет локализованную строку, похожую на Нельзя изменить удаленный элемент (идентификатор: {0}). + /// + internal static string ElementDeletedExceptionMessage { + get { + return ResourceManager.GetString("ElementDeletedExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Уже существует элемент со значением {0} параметра {1}. + /// + internal static string ElementExistsExceptionMessage { + get { + return ResourceManager.GetString("ElementExistsExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Элемент не найден по значению = {0}. + /// + internal static string ElementNotFoundExceptionMessage { + get { + return ResourceManager.GetString("ElementNotFoundExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Дата окончания должна быть позже даты начала. Дата начала: {0}. ​​Дата окончания: {1}. + /// + internal static string IncorrectDatesExceptionMessage { + get { + return ResourceManager.GetString("IncorrectDatesExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Недостаточно данных для обработки: {0}. + /// + internal static string NotEnoughDataToProcessExceptionMessage { + get { + return ResourceManager.GetString("NotEnoughDataToProcessExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Не найдены данные. + /// + internal static string NotFoundDataMessage { + get { + return ResourceManager.GetString("NotFoundDataMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Ошибка при работе в хранилище: {0}. + /// + internal static string StorageExceptionMessage { + get { + return ResourceManager.GetString("StorageExceptionMessage", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Дата трудоустройства не может быть раньше даты рождения ({0}, {1}). + /// + internal static string ValidationExceptionMessageEmploymentDateAndBirthDate { + get { + return ResourceManager.GetString("ValidationExceptionMessageEmploymentDateAndBirthDate", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Значение в поле {0} пусто. + /// + internal static string ValidationExceptionMessageEmptyField { + get { + return ResourceManager.GetString("ValidationExceptionMessageEmptyField", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Некорректный формат ФИО. + /// + internal static string ValidationExceptionMessageIncorrectFIO { + get { + return ResourceManager.GetString("ValidationExceptionMessageIncorrectFIO", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Значение в поле Телефонный номер не является телефонным номером. + /// + internal static string ValidationExceptionMessageIncorrectPhoneNumber { + get { + return ResourceManager.GetString("ValidationExceptionMessageIncorrectPhoneNumber", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Значение в поле {0} меньше или равно 0. + /// + internal static string ValidationExceptionMessageLessOrEqualZero { + get { + return ResourceManager.GetString("ValidationExceptionMessageLessOrEqualZero", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Несовершеннолетние не могут быть приняты на работу (Дата рождения: {0}). + /// + internal static string ValidationExceptionMessageMinorsBirthDate { + get { + return ResourceManager.GetString("ValidationExceptionMessageMinorsBirthDate", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Несовершеннолетние не могут быть приняты на работу (Дата трудоустройства: {0}, Дата рождения: {1}). + /// + internal static string ValidationExceptionMessageMinorsEmploymentDate { + get { + return ResourceManager.GetString("ValidationExceptionMessageMinorsEmploymentDate", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Отсутствуют компоненты. + /// + internal static string ValidationExceptionMessageNoComponents { + get { + return ResourceManager.GetString("ValidationExceptionMessageNoComponents", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на В продаже должен быть хотя бы один товар. + /// + internal static string ValidationExceptionMessageNoProductsInSale { + get { + return ResourceManager.GetString("ValidationExceptionMessageNoProductsInSale", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Значение в поле {0} не является типом уникального идентификатора. + /// + internal static string ValidationExceptionMessageNotAId { + get { + return ResourceManager.GetString("ValidationExceptionMessageNotAId", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Значение в поле {0} не проинициализировано. + /// + internal static string ValidationExceptionMessageNotInitialized { + get { + return ResourceManager.GetString("ValidationExceptionMessageNotInitialized", resourceCulture); + } + } + } +} diff --git a/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.resx b/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.resx new file mode 100644 index 0000000..ddb48e0 --- /dev/null +++ b/MagicCarpetProject/MagicCarpetContracts/Resources/Messages.resx @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Нельзя изменить удаленный элемент (идентификатор: {0}) + + + Уже существует элемент со значением {0} параметра {1} + + + Элемент не найден по значению = {0} + + + Дата окончания должна быть позже даты начала. Дата начала: {0}. ​​Дата окончания: {1} + + + Недостаточно данных для обработки: {0} + + + Не найдены данные + + + Ошибка при работе в хранилище: {0} + + + Дата трудоустройства не может быть раньше даты рождения ({0}, {1}) + + + Значение в поле {0} пусто + + + Некорректный формат ФИО + + + Значение в поле Телефонный номер не является телефонным номером + + + Значение в поле {0} меньше или равно 0 + + + Несовершеннолетние не могут быть приняты на работу (Дата рождения: {0}) + + + Несовершеннолетние не могут быть приняты на работу (Дата трудоустройства: {0}, Дата рождения: {1}) + + + Отсутствуют компоненты + + + В продаже должен быть хотя бы один товар + + + Значение в поле {0} не является типом уникального идентификатора + + + Значение в поле {0} не проинициализировано + + \ No newline at end of file diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IClientStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IClientStorageContract.cs index a86cea1..7c204f9 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IClientStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IClientStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface IClientStorageContract +internal interface IClientStorageContract { List GetList(); diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IEmployeeStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IEmployeeStorageContract.cs index 597c882..950bd26 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IEmployeeStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IEmployeeStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface IEmployeeStorageContract +internal interface IEmployeeStorageContract { List GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null); diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IPostStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IPostStorageContract.cs index c65109f..42e7d83 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IPostStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/IPostStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface IPostStorageContract +internal interface IPostStorageContract { List GetList(); List GetPostWithHistory(string postId); diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISalaryStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISalaryStorageContract.cs index 8e24c19..56e4a22 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISalaryStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISalaryStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface ISalaryStorageContract +internal interface ISalaryStorageContract { List GetList(DateTime? startDate, DateTime? endDate, string? employeeId = null); diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISaleStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISaleStorageContract.cs index 220330d..a0b0a38 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISaleStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ISaleStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface ISaleStorageContract +internal interface ISaleStorageContract { List GetList(DateTime? startDate = null, DateTime? endDate = null, string? employeeId = null, string? clientId = null, string? tourId = null); diff --git a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ITourStorageContract.cs b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ITourStorageContract.cs index 9b374a6..5081efa 100644 --- a/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ITourStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetContracts/StoragesContracts/ITourStorageContract.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MagicCarpetContracts.StoragesContracts; -public interface ITourStorageContract +internal interface ITourStorageContract { List GetList(); List GetHistoryByTourId(string tourId); diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs index 57e4722..9a43259 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/ClientStorageContract.cs @@ -1,9 +1,11 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; using Npgsql; using System; using System.Collections.Generic; @@ -13,11 +15,12 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -public class ClientStorageContract : IClientStorageContract +internal class ClientStorageContract : IClientStorageContract { private readonly MagicCarpetDbContext _dbContext; private readonly Mapper _mapper; - public ClientStorageContract(MagicCarpetDbContext magicCarpetDbContext) + private readonly IStringLocalizer _localizer; + public ClientStorageContract(MagicCarpetDbContext magicCarpetDbContext, IStringLocalizer localizer) { _dbContext = magicCarpetDbContext; var config = new MapperConfiguration(cfg => @@ -25,6 +28,7 @@ public class ClientStorageContract : IClientStorageContract cfg.AddMaps(typeof(MagicCarpetDbContext).Assembly); }); _mapper = new Mapper(config); + _localizer = localizer; } public List GetList() { @@ -35,7 +39,7 @@ public class ClientStorageContract : IClientStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public ClientDataModel? GetElementById(string id) @@ -47,7 +51,7 @@ public class ClientStorageContract : IClientStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public ClientDataModel? GetElementByFIO(string fio) @@ -59,7 +63,7 @@ public class ClientStorageContract : IClientStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public ClientDataModel? GetElementByPhoneNumber(string phoneNumber) @@ -71,7 +75,7 @@ public class ClientStorageContract : IClientStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public void AddElement(ClientDataModel clientDataModel) @@ -84,24 +88,24 @@ public class ClientStorageContract : IClientStorageContract catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("Id", clientDataModel.Id); + throw new ElementExistsException("Id", clientDataModel.Id, _localizer); } catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" }) { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber); + throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber, _localizer); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public void UpdElement(ClientDataModel clientDataModel) { try { - var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id); + var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id, _localizer); _dbContext.Clients.Update(_mapper.Map(clientDataModel, element)); _dbContext.SaveChanges(); } @@ -113,19 +117,19 @@ public class ClientStorageContract : IClientStorageContract catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" }) { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber); + throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber, _localizer); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } public void DelElement(string id) { try { - var element = GetClientById(id) ?? throw new ElementNotFoundException(id); + var element = GetClientById(id) ?? throw new ElementNotFoundException(id, _localizer); _dbContext.Clients.Remove(element); _dbContext.SaveChanges(); } @@ -137,7 +141,7 @@ public class ClientStorageContract : IClientStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } private Client? GetClientById(string id) => _dbContext.Clients.FirstOrDefault(x => x.Id == id); diff --git a/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs b/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs index b492981..c4d2f91 100644 --- a/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs +++ b/MagicCarpetProject/MagicCarpetDatabase/Implementations/EmployeeStorageContract.cs @@ -1,8 +1,10 @@ using AutoMapper; using MagicCarpetContracts.DataModels; using MagicCarpetContracts.Exceptions; +using MagicCarpetContracts.Resources; using MagicCarpetContracts.StoragesContracts; using MagicCarpetDatabase.Models; +using Microsoft.Extensions.Localization; using System; using System.Collections.Generic; using System.Linq; @@ -11,12 +13,12 @@ using System.Threading.Tasks; namespace MagicCarpetDatabase.Implementations; -public class EmployeeStorageContract : IEmployeeStorageContract +internal class EmployeeStorageContract : IEmployeeStorageContract { private readonly MagicCarpetDbContext _dbContext; private readonly Mapper _mapper; - - public EmployeeStorageContract(MagicCarpetDbContext dbContext) + private readonly IStringLocalizer _localizer; + public EmployeeStorageContract(MagicCarpetDbContext dbContext, IStringLocalizer localizer) { _dbContext = dbContext; var config = new MapperConfiguration(cfg => @@ -27,6 +29,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract cfg.CreateMap(); }); _mapper = new Mapper(config); + _localizer = localizer; } public List GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null) @@ -55,7 +58,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -68,7 +71,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -81,7 +84,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -94,7 +97,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -108,12 +111,12 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict") { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("Id", employeeDataModel.Id); + throw new ElementExistsException("Id", employeeDataModel.Id, _localizer); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -121,7 +124,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract { try { - var element = GetEmployeeById(employeeDataModel.Id) ?? throw new ElementNotFoundException(employeeDataModel.Id); + var element = GetEmployeeById(employeeDataModel.Id) ?? throw new ElementNotFoundException(employeeDataModel.Id, _localizer); _dbContext.Employees.Update(_mapper.Map(employeeDataModel, element)); _dbContext.SaveChanges(); } @@ -133,7 +136,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -141,7 +144,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract { try { - var element = GetEmployeeById(id) ?? throw new ElementNotFoundException(id); + var element = GetEmployeeById(id) ?? throw new ElementNotFoundException(id, _localizer); element.IsDeleted = true; _dbContext.SaveChanges(); } @@ -153,7 +156,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } @@ -168,7 +171,7 @@ public class EmployeeStorageContract : IEmployeeStorageContract catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex, _localizer); } } diff --git a/MagicCarpetProject/MagicCarpetWebApi/Program.cs b/MagicCarpetProject/MagicCarpetWebApi/Program.cs index 8c82c68..015c006 100644 --- a/MagicCarpetProject/MagicCarpetWebApi/Program.cs +++ b/MagicCarpetProject/MagicCarpetWebApi/Program.cs @@ -11,9 +11,12 @@ using MagicCarpetWebApi; using MagicCarpetWebApi.Adapters; using MagicCarpetWebApi.Infrastructure; using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Serilog; +using System.Globalization; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; @@ -50,6 +53,22 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) }; }); +builder.Services.AddLocalization(); +builder.Services.Configure( + options => + { + var supportedCultures = new List + { + new("en-US"), + new("ru-RU"), + new("zh-CN") + }; + + options.DefaultRequestCulture = new RequestCulture(culture: "ru-RU", uiCulture: "ru-RU"); + options.SupportedCultures = supportedCultures; + options.SupportedUICultures = supportedCultures; + }); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -116,4 +135,11 @@ app.Map("/login/{username}", (string username) => app.MapControllers(); +var localizeOptions = +app.Services.GetService>(); +if (localizeOptions is not null) +{ + app.UseRequestLocalization(localizeOptions.Value); +} + app.Run(); \ No newline at end of file