3 Commits

Author SHA1 Message Date
user
94f2c60a08 Наследование ISaleStorage 2025-03-17 02:39:08 +04:00
user
e54574147a Revert "Добавил наследование от ISaleStorage"
This reverts commit 9045e90326.
2025-03-17 02:38:38 +04:00
user
9045e90326 Добавил наследование от ISaleStorage 2025-03-17 02:38:26 +04:00
172 changed files with 1181 additions and 11977 deletions

View File

@@ -6,21 +6,18 @@ using SquirrelContract.Extensions;
using System.Text.Json;
using System.Text.RegularExpressions;
using SquirrelContract.DataModels;
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelBusinessLogic.Implementations;
internal class ClientBusinessLogicContract(IClientStorageContract clientStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IClientBusinessLogicContract
internal class ClientBusinessLogicContract(IClientStorageContract clientStorageContract, ILogger logger) : IClientBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IClientStorageContract _clientStorageContract = clientStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<ClientDataModel> GetAllClients()
{
_logger.LogInformation("GetAllClients");
return _clientStorageContract.GetList();
return _clientStorageContract.GetList() ?? throw new NullListException();
}
public ClientDataModel GetClientByData(string data)
@@ -32,20 +29,20 @@ internal class ClientBusinessLogicContract(IClientStorageContract clientStorageC
}
if (data.IsGuid())
{
return _clientStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
return _clientStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
if (Regex.IsMatch(data, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$"))
{
return _clientStorageContract.GetElementByPhoneNumber(data) ?? throw new ElementNotFoundException(data, _localizer);
return _clientStorageContract.GetElementByPhoneNumber(data) ?? throw new ElementNotFoundException(data);
}
return _clientStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data, _localizer);
return _clientStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data);
}
public void InsertClient(ClientDataModel clientDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(clientDataModel));
ArgumentNullException.ThrowIfNull(clientDataModel);
clientDataModel.Validate(_localizer);
clientDataModel.Validate();
_clientStorageContract.AddElement(clientDataModel);
}
@@ -53,7 +50,7 @@ internal class ClientBusinessLogicContract(IClientStorageContract clientStorageC
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(clientDataModel));
ArgumentNullException.ThrowIfNull(clientDataModel);
clientDataModel.Validate(_localizer);
clientDataModel.Validate();
_clientStorageContract.UpdElement(clientDataModel);
}
@@ -66,7 +63,7 @@ internal class ClientBusinessLogicContract(IClientStorageContract clientStorageC
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_clientStorageContract.DelElement(id);
}

View File

@@ -1,25 +1,22 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace SquirrelBusinessLogic.Implementations;
internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ICocktailBusinessLogicContract
internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailStorageContract, ILogger logger) : ICocktailBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ICocktailStorageContract _cocktailStorageContract = cocktailStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<CocktailDataModel> GetAllCocktails()
{
_logger.LogInformation("GetAllCocktails");
return _cocktailStorageContract.GetList();
return _cocktailStorageContract.GetList() ?? throw new NullListException();
}
public List<CocktailHistoryDataModel> GetCocktailHistoryByCocktail(string cocktailId)
@@ -31,9 +28,9 @@ internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailSt
}
if (!cocktailId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "CocktailId"));
throw new ValidationException("The value in the field cocktailId is not a unique identifier.");
}
return _cocktailStorageContract.GetHistoryByCocktailId(cocktailId);
return _cocktailStorageContract.GetHistoryByCocktailId(cocktailId) ?? throw new NullListException();
}
public CocktailDataModel GetCocktailByData(string data)
@@ -45,16 +42,16 @@ internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailSt
}
if (data.IsGuid())
{
return _cocktailStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
return _cocktailStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _cocktailStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data, _localizer);
return _cocktailStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertCocktail(CocktailDataModel cocktailDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(cocktailDataModel));
ArgumentNullException.ThrowIfNull(cocktailDataModel);
cocktailDataModel.Validate(_localizer);
cocktailDataModel.Validate();
_cocktailStorageContract.AddElement(cocktailDataModel);
}
@@ -62,7 +59,7 @@ internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailSt
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(cocktailDataModel));
ArgumentNullException.ThrowIfNull(cocktailDataModel);
cocktailDataModel.Validate(_localizer);
cocktailDataModel.Validate();
_cocktailStorageContract.UpdElement(cocktailDataModel);
}
@@ -75,7 +72,7 @@ internal class CocktailBusinessLogicContract(ICocktailStorageContract cocktailSt
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_cocktailStorageContract.DelElement(id);
}

View File

@@ -1,26 +1,23 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace SquirrelBusinessLogic.Implementations;
internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IEmployeeBusinessLogicContract
internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeStorageContract, ILogger logger) : IEmployeeBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IEmployeeStorageContract _employeeStorageContract = employeeStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<EmployeeDataModel> GetAllEmployees(bool onlyActive = true)
{
_logger.LogInformation("GetAllEmployees params: {onlyActive}", onlyActive);
return _employeeStorageContract.GetList(onlyActive);
return _employeeStorageContract.GetList(onlyActive) ?? throw new NullListException();
}
public List<EmployeeDataModel> GetAllEmployeesByPost(string postId, bool onlyActive = true)
@@ -32,9 +29,9 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
}
if (!postId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "PostId"));
throw new ValidationException("The value in the field postId is not a unique identifier.");
}
return _employeeStorageContract.GetList(onlyActive, postId);
return _employeeStorageContract.GetList(onlyActive, postId) ?? throw new NullListException();
}
public List<EmployeeDataModel> GetAllEmployeesByBirthDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
@@ -42,9 +39,9 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
_logger.LogInformation("GetAllEmployees params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
return _employeeStorageContract.GetList(onlyActive, fromBirthDate: fromDate, toBirthDate: toDate);
return _employeeStorageContract.GetList(onlyActive, fromBirthDate: fromDate, toBirthDate: toDate) ?? throw new NullListException();
}
public List<EmployeeDataModel> GetAllEmployeesByEmploymentDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
@@ -52,9 +49,9 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
_logger.LogInformation("GetAllEmployees params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
return _employeeStorageContract.GetList(onlyActive, fromEmploymentDate: fromDate, toEmploymentDate: toDate);
return _employeeStorageContract.GetList(onlyActive, fromEmploymentDate: fromDate, toEmploymentDate: toDate) ?? throw new NullListException();
}
public EmployeeDataModel GetEmployeeByData(string data)
@@ -66,20 +63,20 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
}
if (data.IsGuid())
{
return _employeeStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
return _employeeStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
if (Regex.IsMatch(data, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
{
return _employeeStorageContract.GetElementByEmail(data) ?? throw new ElementNotFoundException(data, _localizer);
return _employeeStorageContract.GetElementByEmail(data) ?? throw new ElementNotFoundException(data);
}
return _employeeStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data, _localizer);
return _employeeStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data);
}
public void InsertEmployee(EmployeeDataModel employeeDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(employeeDataModel));
ArgumentNullException.ThrowIfNull(employeeDataModel);
employeeDataModel.Validate(_localizer);
employeeDataModel.Validate();
_employeeStorageContract.AddElement(employeeDataModel);
}
@@ -87,7 +84,7 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(employeeDataModel));
ArgumentNullException.ThrowIfNull(employeeDataModel);
employeeDataModel.Validate(_localizer);
employeeDataModel.Validate();
_employeeStorageContract.UpdElement(employeeDataModel);
}
@@ -100,7 +97,7 @@ internal class EmployeeBusinessLogicContract(IEmployeeStorageContract employeeSt
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_employeeStorageContract.DelElement(id);
}

View File

@@ -1,25 +1,21 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using System.Text.Json;
namespace SquirrelBusinessLogic.Implementations;
internal class PostBusinessLogicContract(IPostStorageContract postStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IPostBusinessLogicContract
internal class PostBusinessLogicContract(IPostStorageContract postStorageContract, ILogger logger) : IPostBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IPostStorageContract _postStorageContract = postStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<PostDataModel> GetAllPosts()
public List<PostDataModel> GetAllPosts(bool onlyActive = true)
{
_logger.LogInformation("GetAllPosts");
return _postStorageContract.GetList();
_logger.LogInformation("GetAllPosts params: {onlyActive}", onlyActive);
return _postStorageContract.GetList(onlyActive) ?? throw new NullListException();
}
public List<PostDataModel> GetAllDataOfPost(string postId)
@@ -31,9 +27,9 @@ internal class PostBusinessLogicContract(IPostStorageContract postStorageContrac
}
if (!postId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "PostId"));
throw new ValidationException("The value in the field postId is not a unique identifier.");
}
return _postStorageContract.GetPostWithHistory(postId);
return _postStorageContract.GetPostWithHistory(postId) ?? throw new NullListException();
}
public PostDataModel GetPostByData(string data)
@@ -45,16 +41,16 @@ internal class PostBusinessLogicContract(IPostStorageContract postStorageContrac
}
if (data.IsGuid())
{
return _postStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
return _postStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _postStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data, _localizer);
return _postStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertPost(PostDataModel postDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate(_localizer);
postDataModel.Validate();
_postStorageContract.AddElement(postDataModel);
}
@@ -62,7 +58,7 @@ internal class PostBusinessLogicContract(IPostStorageContract postStorageContrac
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate(_localizer);
postDataModel.Validate();
_postStorageContract.UpdElement(postDataModel);
}
@@ -75,7 +71,7 @@ internal class PostBusinessLogicContract(IPostStorageContract postStorageContrac
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_postStorageContract.DelElement(id);
}
@@ -89,7 +85,7 @@ internal class PostBusinessLogicContract(IPostStorageContract postStorageContrac
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_postStorageContract.ResElement(id);
}

View File

@@ -1,173 +0,0 @@
using SquirrelBusinessLogic.OfficePackage;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.StoragesContracts;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelBusinessLogic.Implementations;
internal class ReportContract : IReportContract
{
private readonly ICocktailStorageContract _cocktailStorageContract;
private readonly ISalaryStorageContract _salaryStorageContract;
private readonly ISaleStorageContract _saleStorageContract;
private readonly BaseWordBuilder _baseWordBuilder;
private readonly BaseExcelBuilder _baseExcelBuilder;
private readonly BasePdfBuilder _basePdfBuilder;
private readonly ILogger _logger;
private readonly IStringLocalizer<Messages> _localizer;
internal readonly string[] _documentHeader;
internal readonly string[] _tableHeader;
public ReportContract(ICocktailStorageContract cocktailStorageContract, ISaleStorageContract saleStorageContract, ISalaryStorageContract salaryStorageContract, BaseWordBuilder baseWordBuilder, BaseExcelBuilder baseExcelBuilder, BasePdfBuilder basePdfBuilder, ILogger logger, IStringLocalizer<Messages> localizer)
{
_cocktailStorageContract = cocktailStorageContract;
_saleStorageContract = saleStorageContract;
_salaryStorageContract = salaryStorageContract;
_baseWordBuilder = baseWordBuilder;
_baseExcelBuilder = baseExcelBuilder;
_basePdfBuilder = basePdfBuilder;
_logger = logger;
_localizer = localizer;
_documentHeader = [_localizer["DocumentDocCaptionCocktail"], _localizer["DocumentDocCaptionPreviousNames"], _localizer["DocumentDocCaptionData"]];
_tableHeader = [_localizer["DocumentExcelCaptionDate"], _localizer["DocumentExcelCaptionSum"], _localizer["DocumentExcelCaptionDiscount"], _localizer["DocumentExcelCaptionCocktail"], _localizer["DocumentExcelCaptionCount"]];
}
public Task<List<CocktailAndCocktailHistoryDataModel>> GetDataCocktailsHistoryAsync(CancellationToken ct)
{
_logger.LogInformation("Get data PostHistory");
return GetCocktailsHistoriesAsync(ct);
}
public async Task<Stream> CreateDocumentCocktailsHistoryAsync(CancellationToken ct)
{
_logger.LogInformation("Create report CocktailHistory");
var data = await GetCocktailsHistoriesAsync(ct) ?? throw new InvalidOperationException(_localizer["NotFoundDataMessage"]);
return _baseWordBuilder
.AddHeader(_localizer["DocumentDocHeader"])
.AddParagraph(string.Format(_localizer["DocumentDocSubHeader"], DateTime.Now))
.AddTable(
new[] { 3000, 3000, 3000 },
new List<string[]> { _documentHeader }
.Concat(data.SelectMany(x =>
new[] { new[] { x.CocktailName, "", "" } }
.Concat(x.Histories.Zip(x.Data, (price, date) => new[] { "", price, date }))
))
.ToList()
)
.Build();
}
private async Task<List<CocktailAndCocktailHistoryDataModel>> GetCocktailsHistoriesAsync(CancellationToken ct) =>
[.. (await _cocktailStorageContract.GetHistoriesListAsync(ct)).GroupBy(x => x.CocktailName).Select(x => new CocktailAndCocktailHistoryDataModel {
CocktailName = x.Key, Histories = [.. x.Select(y => y.OldPrice.ToString())], Data = [.. x.Select(y => y.ChangeDate.ToString())] })];
public async Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
var tableHeader1 = new string[]
{
_localizer["DocumentExcelHeaderEmployee"],
_localizer["DocumentExcelCaptionDate"],
_localizer["DocumentExcelCaptionSum"],
_localizer["DocumentExcelCaptionDiscount"],
_localizer["DocumentExcelCaptionCocktail"],
_localizer["DocumentExcelCaptionCount"]
};
_logger.LogInformation("Create report SalesByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
var data = await GetDataBySalesAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException(_localizer["NotFoundDataMessage"]); ;
var tableRows = new List<string[]>
{
tableHeader1
};
foreach (var sale in data)
{
tableRows.Add(new string[]
{
sale.EmployeeFIO ?? "",
sale.SaleDate.ToShortDateString(),
sale.Sum.ToString("N2"),
sale.Discount.ToString("N2"),
"", ""
});
foreach (var cocktail in sale.Cocktails ?? Enumerable.Empty<SaleCocktailDataModel>())
{
tableRows.Add(new string[]
{
"", "", "", "", cocktail.CocktailName, cocktail.Count.ToString("N2")
});
}
}
tableRows.Add(new string[]
{
_localizer["DocumentExcelCaptionTotal"], "", data.Sum(x => x.Sum).ToString("N2"), data.Sum(x => x.Discount).ToString("N2"), "", ""
});
return _baseExcelBuilder
.AddHeader(_localizer["DocumentExcelHeader"], 0, 6)
.AddParagraph(string.Format(_localizer["DocumentExcelSubHeader"], dateStart.ToLocalTime().ToShortDateString(), dateFinish.ToLocalTime().ToShortDateString()), 2)
.AddTable([15, 15, 10, 10, 25, 10], tableRows)
.Build();
}
public async Task<List<SaleDataModel>> GetDataBySalesAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
if (dateStart.IsDateNotOlder(dateFinish))
{
throw new IncorrectDatesException(dateStart, dateFinish, _localizer);
}
return [.. (await _saleStorageContract.GetListAsync(dateStart,
dateFinish, ct)).OrderBy(x => x.SaleDate)];
}
public Task<List<SaleDataModel>> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Get data SalesByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
return GetDataBySalesAsync(dateStart, dateFinish, ct);
}
public Task<List<EmployeeSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Get data SalaryByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
return GetDataBySalaryAsync(dateStart, dateFinish, ct);
}
private async Task<List<EmployeeSalaryByPeriodDataModel>> GetDataBySalaryAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
if (dateStart.IsDateNotOlder(dateFinish))
{
throw new IncorrectDatesException(dateStart, dateFinish, _localizer);
}
return [.. (await _salaryStorageContract.GetListAsync(dateStart, dateFinish, ct))
.GroupBy(x => x.EmployeeId)
.Select(x => new EmployeeSalaryByPeriodDataModel {
EmployeeFIO = x.First().EmployeeFIO,
TotalSalary = x.Sum(y => y.Salary),
FromPeriod = x.Min(y => y.SalaryDate),
ToPeriod = x.Max(y => y.SalaryDate)
})
.OrderBy(x => x.EmployeeFIO)];
}
public async Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Create report SalaryByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
var data = await GetDataBySalaryAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException(_localizer["NotFoundDataMessage"]);
return _basePdfBuilder
.AddHeader(_localizer["DocumentPdfHeader"])
.AddParagraph(string.Format(_localizer["DocumentPdfSubHeader"], dateStart.ToLocalTime().ToShortDateString(), dateFinish.ToLocalTime().ToShortDateString()))
.AddPieChart(_localizer["DocumentPdfDiagramCaption"], [.. data.Select(x => (x.EmployeeFIO, x.TotalSalary))])
.Build();
}
}

View File

@@ -1,44 +1,35 @@
using BarBelochkaContract.DataModels;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Infastructure.PostConfigurations;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
namespace SquirrelBusinessLogic.Implementations;
internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract,
ISaleStorageContract saleStorageContract, IPostStorageContract postStorageContract, IEmployeeStorageContract employeeStorageContract, IStringLocalizer<Messages> localizer, ILogger logger, IConfigurationSalary сonfiguration) : ISalaryBusinessLogicContract
ISaleStorageContract saleStorageContract, IPostStorageContract postStorageContract, IEmployeeStorageContract employeeStorageContract, ILogger logger) : ISalaryBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISalaryStorageContract _salaryStorageContract = salaryStorageContract;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
private readonly IPostStorageContract _postStorageContract = postStorageContract;
private readonly IEmployeeStorageContract _employeeStorageContract = employeeStorageContract;
private readonly IConfigurationSalary _salaryConfiguration = сonfiguration;
private readonly IStringLocalizer<Messages> _localizer = localizer;
private readonly Lock _lockObject = new();
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
return _salaryStorageContract.GetList(fromDate, toDate);
return _salaryStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
}
public List<SalaryDataModel> GetAllSalariesByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId)
{
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
if (employeeId.IsEmpty())
{
@@ -46,10 +37,10 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
}
if (!employeeId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "EmployeeId"));
throw new ValidationException("The value in the field employeeId is not a unique identifier.");
}
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}, {employeeId}", fromDate, toDate, employeeId);
return _salaryStorageContract.GetList(fromDate, toDate, employeeId);
return _salaryStorageContract.GetList(fromDate, toDate, employeeId) ?? throw new NullListException();
}
public void CalculateSalaryByMounth(DateTime date)
@@ -57,70 +48,16 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
_logger.LogInformation("CalculateSalaryByMounth: {date}", date);
var startDate = new DateTime(date.Year, date.Month, 1);
var finishDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
var employees = _employeeStorageContract.GetList();
var employees = _employeeStorageContract.GetList() ?? throw new NullListException();
foreach (var employee in employees)
{
var sales = _saleStorageContract.GetList(startDate, finishDate, employeeId: employee.Id);
var post = _postStorageContract.GetElementById(employee.PostId) ?? throw new ElementNotFoundException(employee.PostId, _localizer);
var salary = post.ConfigurationModel switch
{
null => 0,
BartenderPostConfiguration cpc => CalculateSalaryForBartender(sales, startDate, finishDate, cpc),
ManagerPostConfiguration spc => CalculateSalaryForManager(startDate, finishDate, spc),
PostConfiguration pc => pc.Rate,
};
var sales = _saleStorageContract.GetList(startDate, finishDate, employeeId: employee.Id)?.Sum(x => x.Sum) ??
throw new NullListException();
var post = _postStorageContract.GetElementById(employee.PostId) ??
throw new NullListException();
var salary = post.Salary + sales * 0.1;
_logger.LogDebug("The employee {employeeId} was paid a salary of {salary}", employee.Id, salary);
_salaryStorageContract.AddElement(new SalaryDataModel(employee.Id, finishDate, salary));
}
}
private double CalculateSalaryForBartender(List<SaleDataModel> sales, DateTime startDate, DateTime finishDate, BartenderPostConfiguration config)
{
var tasks = new List<Task>();
var calcPercent = 0.0;
for (var date = startDate; date < finishDate; date = date.AddDays(1))
{
tasks.Add(Task.Factory.StartNew((object? obj) =>
{
var dateInTask = (DateTime)obj!;
var salesInDay = sales.Where(x => x.SaleDate >= dateInTask && x.SaleDate <= dateInTask.AddDays(1)).ToArray();
if (salesInDay.Length > 0)
{
lock (_lockObject)
{
calcPercent += (salesInDay.Sum(x => x.Sum) / salesInDay.Length) * config.SalePercent;
}
}
}, date));
}
var calcBonusTask = Task.Run(() =>
{
return sales.Where(x => x.Sum > _salaryConfiguration.ExtraSaleSum).Sum(x => x.Sum) * config.BonusForExtraSales;
});
try
{
Task.WaitAll([Task.WhenAll(tasks), calcBonusTask]);
}
catch (AggregateException agEx)
{
foreach (var ex in agEx.InnerExceptions)
{
_logger.LogError(ex, "Error in the cashier payroll process");
}
return 0;
}
return config.Rate + calcPercent + calcBonusTask.Result;
}
private double CalculateSalaryForManager(DateTime startDate, DateTime finishDate, ManagerPostConfiguration config)
{
try
{
return config.Rate + config.PersonalCountTrendPremium * _employeeStorageContract.GetEmployeeTrend(startDate, finishDate);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in the supervisor payroll process");
return 0;
}
}
}

View File

@@ -1,31 +1,27 @@
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using SquirrelContract.BusinessLogicContracts;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using System.Text.Json;
namespace SquirrelBusinessLogic.Implementations;
internal class SaleBusinessLogicContract(ISaleStorageContract
saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISaleBusinessLogicContract
saleStorageContract, ILogger logger) : ISaleBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSales params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
return _saleStorageContract.GetList(fromDate, toDate);
return _saleStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByEmployeeByPeriod(string employeeId, DateTime fromDate, DateTime toDate)
@@ -33,7 +29,7 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
_logger.LogInformation("GetAllSales params: {employeeId}, {fromDate}, {toDate}", employeeId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
if (employeeId.IsEmpty())
{
@@ -41,9 +37,9 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
}
if (!employeeId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "EmployeeId"));
throw new ValidationException("The value in the field employeeId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, employeeId: employeeId);
return _saleStorageContract.GetList(fromDate, toDate, employeeId: employeeId) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByClientByPeriod(string clientId, DateTime fromDate, DateTime toDate)
@@ -51,7 +47,7 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
_logger.LogInformation("GetAllSales params: {buyerId}, {fromDate}, {toDate}", clientId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
if (clientId.IsEmpty())
{
@@ -59,9 +55,9 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
}
if (!clientId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "ClientId"));
throw new ValidationException("The value in the field clientId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, clientId: clientId);
return _saleStorageContract.GetList(fromDate, toDate, clientId: clientId) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByCocktailByPeriod(string cocktailId, DateTime fromDate, DateTime toDate)
@@ -69,7 +65,7 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
_logger.LogInformation("GetAllSales params: {cocktailId}, {fromDate}, {toDate}", cocktailId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate, _localizer);
throw new IncorrectDatesException(fromDate, toDate);
}
if (cocktailId.IsEmpty())
{
@@ -77,9 +73,9 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
}
if (!cocktailId.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "cocktailId"));
throw new ValidationException("The value in the field cocktailId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, cocktailId: cocktailId);
return _saleStorageContract.GetList(fromDate, toDate, cocktailId: cocktailId) ?? throw new NullListException();
}
public SaleDataModel GetSaleByData(string data)
@@ -91,16 +87,16 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
}
if (!data.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
return _saleStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
return _saleStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
public void InsertSale(SaleDataModel saleDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(saleDataModel));
ArgumentNullException.ThrowIfNull(saleDataModel);
saleDataModel.Validate(_localizer);
saleDataModel.Validate();
_saleStorageContract.AddElement(saleDataModel);
}
@@ -113,7 +109,7 @@ saleStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISa
}
if (!id.IsGuid())
{
throw new ValidationException(string.Format(_localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("Id is not a unique identifier");
}
_saleStorageContract.DelElement(id);
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelBusinessLogic.OfficePackage;
public abstract class BaseExcelBuilder
{
public abstract BaseExcelBuilder AddHeader(string header, int startIndex, int count);
public abstract BaseExcelBuilder AddParagraph(string text, int columnIndex);
public abstract BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelBusinessLogic.OfficePackage;
public abstract class BasePdfBuilder
{
public abstract BasePdfBuilder AddHeader(string header);
public abstract BasePdfBuilder AddParagraph(string text);
public abstract BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data);
public abstract Stream Build();
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelBusinessLogic.OfficePackage;
public abstract class BaseWordBuilder
{
public abstract BaseWordBuilder AddHeader(string header);
public abstract BaseWordBuilder AddParagraph(string text);
public abstract BaseWordBuilder AddTable(int[] widths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -1,85 +0,0 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace SquirrelBusinessLogic.OfficePackage;
public class MigraDocPdfBuilder : BasePdfBuilder
{
private readonly Document _document;
public MigraDocPdfBuilder()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_document = new Document();
DefineStyles();
}
public override BasePdfBuilder AddHeader(string header)
{
_document.AddSection().AddParagraph(header, "NormalBold");
return this;
}
public override BasePdfBuilder AddParagraph(string text)
{
_document.LastSection.AddParagraph(text, "Normal");
return this;
}
public override BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data)
{
if (data == null || data.Count == 0)
{
return this;
}
var chart = new Chart(ChartType.Pie2D);
var series = chart.SeriesCollection.AddSeries();
series.Add(data.Select(x => x.Value).ToArray());
var xseries = chart.XValues.AddXSeries();
xseries.Add(data.Select(x => x.Caption).ToArray());
chart.DataLabel.Type = DataLabelType.Percent;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
chart.Width = Unit.FromCentimeter(16);
chart.Height = Unit.FromCentimeter(12);
chart.TopArea.AddParagraph(title);
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.TopArea.AddLegend();
_document.LastSection.Add(chart);
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(stream);
return stream;
}
private void DefineStyles()
{
var style = _document.Styles.AddStyle("NormalBold", "Normal");
style.Font.Bold = true;
}
}

View File

@@ -1,303 +0,0 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace SquirrelBusinessLogic.OfficePackage;
public class OpenXmlExcelBuilder : BaseExcelBuilder
{
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public OpenXmlExcelBuilder()
{
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public override BaseExcelBuilder AddHeader(string header, int startIndex, int count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference =
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public override BaseExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public override BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
{
if (columnsWidths == null || columnsWidths.Length == 0)
{
throw new ArgumentNullException(nameof(columnsWidths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != columnsWidths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
uint counter = 1;
int coef = 2;
_columns.Append(columnsWidths.Select(x => new Column
{
Min = counter,
Max = counter++,
Width = x * coef,
CustomWidth = true
}));
for (var j = 0; j < data.First().Length; ++j)
{
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
for (var i = 1; i < data.Count - 1; ++i)
{
for (var j = 0; j < data[i].Length; ++j)
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
GenerateStyle(workbookpart);
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
if (_columns.HasChildren)
{
worksheetPart.Worksheet.Append(_columns);
}
worksheetPart.Worksheet.Append(_sheetData);
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист 1"
};
sheets.Append(sheet);
if (_mergeCells.HasChildren)
{
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
}
return stream;
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2, KnownFonts = BooleanValue.FromBoolean(true) };
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) }
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) },
Bold = new Bold()
});
workbookStylesPart.Stylesheet.Append(fonts);
// Default Fill
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill() { PatternType = new EnumValue<PatternValues>(PatternValues.None) }
});
workbookStylesPart.Stylesheet.Append(fills);
// Default Border
var borders = new Borders() { Count = 2 };
borders.Append(new Border
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
borders.Append(new Border
{
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin },
RightBorder = new RightBorder() { Style = BorderStyleValues.Thin },
TopBorder = new TopBorder() { Style = BorderStyleValues.Thin },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }
});
workbookStylesPart.Stylesheet.Append(borders);
// Default cell format and a date cell format
var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorder = 1,
BoldTextWithoutBorder = 2,
BoldTextWithBorder = 3
}
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
{
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex;
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>()
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
private static string GetExcelColumnName(int columnNumber)
{
columnNumber += 1;
int dividend = columnNumber;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
}

View File

@@ -1,94 +0,0 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace SquirrelBusinessLogic.OfficePackage;
public class OpenXmlWordBuilder : BaseWordBuilder
{
private readonly Document _document;
private readonly Body _body;
public OpenXmlWordBuilder()
{
_document = new Document();
_body = _document.AppendChild(new Body());
}
public override BaseWordBuilder AddHeader(string header)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new RunProperties(new Bold()));
run.AppendChild(new Text(header));
return this;
}
public override BaseWordBuilder AddParagraph(string text)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text(text));
return this;
}
public override BaseWordBuilder AddTable(int[] widths, List<string[]> data)
{
if (widths == null || widths.Length == 0)
{
throw new ArgumentNullException(nameof(widths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != widths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
var table = new Table();
table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 }
)
));
// Заголовок
var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j)
{
tr.Append(new TableCell(
new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
}
table.Append(tr);
// Данные
table.Append(data.Skip(1).Select(x =>
new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y))))))));
_body.Append(table);
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
var mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = _document;
return stream;
}
}

View File

@@ -8,14 +8,11 @@
<ItemGroup>
<InternalsVisibleTo Include="SquirrelTests" />
<InternalsVisibleTo Include="SquirrelWebApi" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -11,8 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquirrelBusinessLogic", "Sq
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquirrelDatabase", "SquirrelDatabase\SquirrelDatabase.csproj", "{A8A7A434-A278-4362-8D34-C2E3CAA938C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquirrelWebApi", "SquirrelWebApi\SquirrelWebApi.csproj", "{45D1F24F-AFCD-4259-88C2-3076E38254A9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -35,15 +33,8 @@ Global
{A8A7A434-A278-4362-8D34-C2E3CAA938C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8A7A434-A278-4362-8D34-C2E3CAA938C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8A7A434-A278-4362-8D34-C2E3CAA938C1}.Release|Any CPU.Build.0 = Release|Any CPU
{45D1F24F-AFCD-4259-88C2-3076E38254A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45D1F24F-AFCD-4259-88C2-3076E38254A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45D1F24F-AFCD-4259-88C2-3076E38254A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45D1F24F-AFCD-4259-88C2-3076E38254A9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E3B65E92-8603-4ED7-8214-9DA9A305DAFF}
EndGlobalSection
EndGlobal

View File

@@ -1,16 +0,0 @@
namespace SquirrelContract.AdapterContracts;
using SquirrelContract.AdapterContracts.OperationResponses;
using SquirrelContract.BindingModels;
public interface IClientAdapter
{
ClientOperationResponse GetList();
ClientOperationResponse GetElement(string data);
ClientOperationResponse RegisterClient(ClientBindingModel clientModel);
ClientOperationResponse ChangeClientInfo(ClientBindingModel clientModel);
ClientOperationResponse RemoveClient(string id);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.BindingModels;
using SquirrelContract.AdapterContracts.OperationResponses;
namespace SquirrelContract.AdapterContracts;
public interface ICocktailAdapter
{
CocktailOperationResponse GetList(bool includeDeleted);
CocktailOperationResponse GetHistory(string id);
CocktailOperationResponse GetElement(string data);
CocktailOperationResponse RegisterCocktail(CocktailBindingModel cocktailModel);
CocktailOperationResponse ChangeCocktailInfo(CocktailBindingModel cocktailModel);
CocktailOperationResponse RemoveCocktail(string id);
}

View File

@@ -1,23 +0,0 @@
using SquirrelContract.AdapterContracts.OperationResponses;
using SquirrelContract.BindingModels;
namespace SquirrelContract.AdapterContracts;
public interface IEmployeeAdapter
{
EmployeeOperationResponse GetList(bool includeDeleted);
EmployeeOperationResponse GetPostList(string id, bool includeDeleted);
EmployeeOperationResponse GetListByBirthDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
EmployeeOperationResponse GetListByEmploymentDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
EmployeeOperationResponse GetElement(string data);
EmployeeOperationResponse RegisterEmployee(EmployeeBindingModel employeeModel);
EmployeeOperationResponse ChangeEmployeeInfo(EmployeeBindingModel employeeModel);
EmployeeOperationResponse RemoveEmployee(string id);
}

View File

@@ -1,21 +0,0 @@
using SquirrelContract.AdapterContracts.OperationResponses;
using SquirrelContract.BindingModels;
namespace SquirrelContract.AdapterContracts;
public interface IPostAdapter
{
PostOperationResponse GetList();
PostOperationResponse GetHistory(string id);
PostOperationResponse GetElement(string data);
PostOperationResponse RegisterPost(PostBindingModel postModel);
PostOperationResponse ChangePostInfo(PostBindingModel postModel);
PostOperationResponse RemovePost(string id);
PostOperationResponse RestorePost(string id);
}

View File

@@ -1,13 +0,0 @@
using SquirrelContract.AdapterContracts.OperationResponses;
namespace SquirrelContract.AdapterContracts;
public interface IReportAdapter
{
Task<ReportOperationResponse> GetDataCocktailsHistoryAsync(CancellationToken ct);
Task<ReportOperationResponse> GetDataBySalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentCocktailsHistoryAsync(CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -1,10 +0,0 @@
using SquirrelContract.AdapterContracts.OperationResponses;
namespace SquirrelContract.AdapterContracts;
public interface ISalaryAdapter
{
SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetListByPeriodByEmployee(DateTime fromDate, DateTime toDate, string employeeId);
SalaryOperationResponse CalculateSalary(DateTime date);
}

View File

@@ -1,21 +0,0 @@
using SquirrelContract.AdapterContracts.OperationResponses;
using SquirrelContract.BindingModels;
namespace SquirrelContract.AdapterContracts;
public interface ISaleAdapter
{
SaleOperationResponse GetList(DateTime fromDate, DateTime toDate);
SaleOperationResponse GetEmployeeList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetClientList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetCocktailList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetElement(string id);
SaleOperationResponse MakeSale(SaleBindingModel saleModel);
SaleOperationResponse CancelSale(string id);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.ViewModels;
using SquirrelContract.Infrastructure;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class ClientOperationResponse : OperationResponse
{
public static ClientOperationResponse OK(List<ClientViewModel> data) => OK<ClientOperationResponse, List<ClientViewModel>>(data);
public static ClientOperationResponse OK(ClientViewModel data) => OK<ClientOperationResponse, ClientViewModel>(data);
public static ClientOperationResponse NoContent() => NoContent<ClientOperationResponse>();
public static ClientOperationResponse BadRequest(string message) => BadRequest<ClientOperationResponse>(message);
public static ClientOperationResponse NotFound(string message) => NotFound<ClientOperationResponse>(message);
public static ClientOperationResponse InternalServerError(string message) => InternalServerError<ClientOperationResponse>(message);
}

View File

@@ -1,21 +0,0 @@
using SquirrelContract.ViewModels;
using SquirrelContract.Infrastructure;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class CocktailOperationResponse : OperationResponse
{
public static CocktailOperationResponse OK(List<CocktailViewModel> data) => OK<CocktailOperationResponse, List<CocktailViewModel>>(data);
public static CocktailOperationResponse OK(List<CocktailHistoryViewModel> data) => OK<CocktailOperationResponse, List<CocktailHistoryViewModel>>(data);
public static CocktailOperationResponse OK(CocktailViewModel data) => OK<CocktailOperationResponse, CocktailViewModel>(data);
public static CocktailOperationResponse NoContent() => NoContent<CocktailOperationResponse>();
public static CocktailOperationResponse NotFound(string message) => NotFound<CocktailOperationResponse>(message);
public static CocktailOperationResponse BadRequest(string message) => BadRequest<CocktailOperationResponse>(message);
public static CocktailOperationResponse InternalServerError(string message) => InternalServerError<CocktailOperationResponse>(message);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.ViewModels;
using SquirrelContract.Infrastructure;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class EmployeeOperationResponse : OperationResponse
{
public static EmployeeOperationResponse OK(List<EmployeeViewModel> data) => OK<EmployeeOperationResponse, List<EmployeeViewModel>>(data);
public static EmployeeOperationResponse OK(EmployeeViewModel data) => OK<EmployeeOperationResponse, EmployeeViewModel>(data);
public static EmployeeOperationResponse NoContent() => NoContent<EmployeeOperationResponse>();
public static EmployeeOperationResponse NotFound(string message) => NotFound<EmployeeOperationResponse>(message);
public static EmployeeOperationResponse BadRequest(string message) => BadRequest<EmployeeOperationResponse>(message);
public static EmployeeOperationResponse InternalServerError(string message) => InternalServerError<EmployeeOperationResponse>(message);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.Infrastructure;
using SquirrelContract.ViewModels;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class PostOperationResponse : OperationResponse
{
public static PostOperationResponse OK(List<PostViewModel> data) => OK<PostOperationResponse, List<PostViewModel>>(data);
public static PostOperationResponse OK(PostViewModel data) => OK<PostOperationResponse, PostViewModel>(data);
public static PostOperationResponse NoContent() => NoContent<PostOperationResponse>();
public static PostOperationResponse NotFound(string message) => NotFound<PostOperationResponse>(message);
public static PostOperationResponse BadRequest(string message) => BadRequest<PostOperationResponse>(message);
public static PostOperationResponse InternalServerError(string message) => InternalServerError<PostOperationResponse>(message);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.Infrastructure;
using SquirrelContract.ViewModels;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class ReportOperationResponse : OperationResponse
{
public static ReportOperationResponse OK(List<CocktailAndCocktailHistoryViewModel> data) => OK<ReportOperationResponse, List<CocktailAndCocktailHistoryViewModel>>(data);
public static ReportOperationResponse OK(List<SaleViewModel> data) => OK<ReportOperationResponse, List<SaleViewModel>>(data);
public static ReportOperationResponse OK(List<EmployeeSalaryByPeriodViewModel> data) => OK<ReportOperationResponse, List<EmployeeSalaryByPeriodViewModel>>(data);
public static ReportOperationResponse OK(Stream data, string fileName) => OK<ReportOperationResponse, Stream>(data, fileName);
public static ReportOperationResponse BadRequest(string message) => BadRequest<ReportOperationResponse>(message);
public static ReportOperationResponse InternalServerError(string message) => InternalServerError<ReportOperationResponse>(message);
}

View File

@@ -1,13 +0,0 @@
using SquirrelContract.Infrastructure;
using SquirrelContract.ViewModels;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class SalaryOperationResponse : OperationResponse
{
public static SalaryOperationResponse OK(List<SalaryViewModel> data) => OK<SalaryOperationResponse, List<SalaryViewModel>>(data);
public static SalaryOperationResponse NoContent() => NoContent<SalaryOperationResponse>();
public static SalaryOperationResponse NotFound(string message) => NotFound<SalaryOperationResponse>(message);
public static SalaryOperationResponse BadRequest(string message) => BadRequest<SalaryOperationResponse>(message);
public static SalaryOperationResponse InternalServerError(string message) => InternalServerError<SalaryOperationResponse>(message);
}

View File

@@ -1,19 +0,0 @@
using SquirrelContract.ViewModels;
using SquirrelContract.Infrastructure;
namespace SquirrelContract.AdapterContracts.OperationResponses;
public class SaleOperationResponse : OperationResponse
{
public static SaleOperationResponse OK(List<SaleViewModel> data) => OK<SaleOperationResponse, List<SaleViewModel>>(data);
public static SaleOperationResponse OK(SaleViewModel data) => OK<SaleOperationResponse, SaleViewModel>(data);
public static SaleOperationResponse NoContent() => NoContent<SaleOperationResponse>();
public static SaleOperationResponse NotFound(string message) => NotFound<SaleOperationResponse>(message);
public static SaleOperationResponse BadRequest(string message) => BadRequest<SaleOperationResponse>(message);
public static SaleOperationResponse InternalServerError(string message) => InternalServerError<SaleOperationResponse>(message);
}

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.BindingModels;
public class ClientBindingModel
{
public string? Id { get; set; }
public string? FIO { get; set; }
public string? PhoneNumber { get; set; }
public double DiscountSize { get; set; }
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelContract.BindingModels;
public class CocktailBindingModel
{
public string? Id { get; set; }
public string? CocktailName { get; set; }
public double Price { get; set; }
public string? BaseAlcohol { get; set; }
}

View File

@@ -1,16 +0,0 @@
namespace SquirrelContract.BindingModels;
public class EmployeeBindingModel
{
public string? Id { get; set; }
public string? FIO { get; set; }
public string? Email { get; set; }
public string? PostId { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
}

View File

@@ -1,14 +0,0 @@
namespace SquirrelContract.BindingModels;
public class PostBindingModel
{
public string? Id { get; set; }
public string? PostId => Id;
public string? PostName { get; set; }
public string? PostType { get; set; }
public string? ConfigurationJson { get; set; }
}

View File

@@ -1,14 +0,0 @@
namespace SquirrelContract.BindingModels;
public class SaleBindingModel
{
public string? Id { get; set; }
public string? EmployeeId { get; set; }
public string? ClientId { get; set; }
public int DiscountType { get; set; }
public List<SaleCocktailBindingModel>? Cocktails { get; set; }
}

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.BindingModels;
public class SaleCocktailBindingModel
{
public string? SaleId { get; set; }
public string? CocktailId { get; set; }
public int Count { get; set; }
public double Price { get; set; }
}

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface IClientBusinessLogicContract
public interface IClientBusinessLogicContract
{
List<ClientDataModel> GetAllClients();

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface ICocktailBusinessLogicContract
public interface ICocktailBusinessLogicContract
{
List<CocktailDataModel> GetAllCocktails();

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface IEmployeeBusinessLogicContract
public interface IEmployeeBusinessLogicContract
{
List<EmployeeDataModel> GetAllEmployees(bool onlyActive = true);

View File

@@ -2,9 +2,9 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface IPostBusinessLogicContract
public interface IPostBusinessLogicContract
{
List<PostDataModel> GetAllPosts();
List<PostDataModel> GetAllPosts(bool onlyActive);
List<PostDataModel> GetAllDataOfPost(string postId);

View File

@@ -1,13 +0,0 @@
using SquirrelContract.DataModels;
namespace SquirrelContract.BusinessLogicContracts;
internal interface IReportContract
{
Task<List<CocktailAndCocktailHistoryDataModel>> GetDataCocktailsHistoryAsync(CancellationToken ct);
Task<Stream> CreateDocumentCocktailsHistoryAsync(CancellationToken ct);
Task<List<SaleDataModel>> GetDataBySalesAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<List<EmployeeSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface ISalaryBusinessLogicContract
public interface ISalaryBusinessLogicContract
{
List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate);

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.BusinessLogicContracts;
internal interface ISaleBusinessLogicContract
public interface ISaleBusinessLogicContract
{
List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate);

View File

@@ -1,33 +1,32 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Exceptions;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
using System.Text.RegularExpressions;
namespace SquirrelContract.DataModels;
internal class ClientDataModel(string id, string fio, string phoneNumber, double discountSize) : IValidation
public class ClientDataModel(string id, string fio, string phoneNumber, double discountSize) : IValidation
{
public string Id { get; private set; } = id;
public string FIO { get; private set;} = fio;
public string PhoneNumber { get; private set;} = phoneNumber;
public double DiscountSize { get; private set; } = discountSize;
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("The value in the field Id is not a unique identifier");
if (FIO.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "FIO"));
throw new ValidationException("Field FIO is empty");
if (PhoneNumber.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PhoneNumber"));
throw new ValidationException("Field PhoneNumber is empty");
if (!Regex.IsMatch(PhoneNumber, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$"))
throw new ValidationException(localizer["ValidationExceptionMessageIncorrectPhoneNumber"]);
throw new ValidationException("Field PhoneNumber is not a phone number");
}
}

View File

@@ -1,8 +0,0 @@
namespace SquirrelContract.DataModels;
public class CocktailAndCocktailHistoryDataModel
{
public required string CocktailName { get; set; }
public required List<string> Histories { get; set; }
public required List<string> Data { get; set; }
}

View File

@@ -1,34 +1,32 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Enums;
using SquirrelContract.Enums;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
namespace SquirrelContract.DataModels;
internal class CocktailDataModel(string id, string cocktailName, double price, AlcoholType baseAlcohol) : IValidation
public class CocktailDataModel(string id, string cocktailName, double price, AlcoholType baseAlcohol) : IValidation
{
public string Id { get; private set; } = id;
public string CocktailName { get; private set; } = cocktailName;
public double Price { get; private set; } = price;
public AlcoholType BaseAlcohol { get; private set; } = baseAlcohol;
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("The value in the field Id is not a unique identifier");
if (CocktailName.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "CocktailName"));
throw new ValidationException("Field CocktailName is empty");
if (Price <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price"));
throw new ValidationException("Field Price is less than or equal to 0");
if (BaseAlcohol == AlcoholType.None)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "BaseAlcohol"));
throw new ValidationException("Field BaseAlcohol is empty");
}
}

View File

@@ -1,38 +1,26 @@
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.DataModels;
internal class CocktailHistoryDataModel(string cocktailId, double oldPrice) : IValidation
public class CocktailHistoryDataModel(string cocktailId, double oldPrice) : IValidation
{
private readonly CocktailDataModel? _cocktail;
public string CocktailId { get; private set; } = cocktailId;
public double OldPrice { get; private set; } = oldPrice;
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
public string CocktailName => _cocktail?.CocktailName ?? string.Empty;
public CocktailHistoryDataModel(string cocktailId, double oldPrice, DateTime changeDate, CocktailDataModel cocktail) : this(cocktailId, oldPrice)
{
ChangeDate = changeDate;
_cocktail = cocktail;
}
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (CocktailId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "CocktailId"));
throw new ValidationException("Field CocktailId is empty");
if (!CocktailId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "CocktailId"));
throw new ValidationException("The value in the field CocktailId is not a unique identifier");
if (OldPrice <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "OldPrice"));
throw new ValidationException("Field OldPrice is less than or equal to 0");
}
}

View File

@@ -1,16 +1,12 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Exceptions;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
using System.Text.RegularExpressions;
namespace SquirrelContract.DataModels;
internal class EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation
public class EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation
{
private readonly PostDataModel? _post;
public string Id { get; private set; } = id;
public string FIO { get; private set; } = fio;
@@ -19,53 +15,42 @@ internal class EmployeeDataModel(string id, string fio, string email, string pos
public string PostId { get; private set; } = postId;
public DateTime BirthDate { get; private set; } = birthDate.ToUniversalTime();
public DateTime BirthDate { get; private set; } = birthDate;
public DateTime EmploymentDate { get; private set; } = employmentDate.ToUniversalTime();
public DateTime EmploymentDate { get; private set; } = employmentDate;
public bool IsDeleted { get; private set; } = isDeleted;
public string PostName => _post?.PostName ?? string.Empty;
public EmployeeDataModel(string id, string fio, string email, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted, PostDataModel post) : this(id, fio, email, postId, birthDate, employmentDate, isDeleted)
{
_post = post;
}
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(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("The value in the field Id is not a unique identifier");
if (FIO.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "FIO"));
throw new ValidationException("Field FIO is empty");
if (Email.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Email"));
throw new ValidationException("Field Email is empty");
if (!Regex.IsMatch(Email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
throw new ValidationException(localizer["ValidationExceptionMessageIncorrectEmail"]);
throw new ValidationException("Field Email is not a valid email address");
if (PostId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "PostId"));
throw new ValidationException("Field PostId is empty");
if (!PostId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "PostId"));
throw new ValidationException("The value in the field PostId is not a unique identifier");
if (BirthDate.Date > DateTime.Now.AddYears(-18).Date)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageMinorsBirthDate"], BirthDate.ToShortDateString()));
throw new ValidationException($"Only adults can be hired (BirthDate = {BirthDate.ToShortDateString()})");
if (EmploymentDate.Date < BirthDate.Date)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmploymentDateAndBirthDate"],
EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString()));
throw new ValidationException("The date of employment cannot be less than the date of birth");
if ((EmploymentDate - BirthDate).TotalDays / 365 < 18) // EmploymentDate.Year - BirthDate.Year
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageMinorsEmploymentDate"],
EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString()));
throw new ValidationException($"Only adults can be hired (EmploymentDate - {EmploymentDate.ToShortDateString()}, BirthDate - {BirthDate.ToShortDateString()})");
}
}

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.DataModels;
public class EmployeeSalaryByPeriodDataModel
{
public required string EmployeeFIO { get; set; }
public double TotalSalary { get; set; }
public DateTime FromPeriod { get; set; }
public DateTime ToPeriod { get; set; }
}

View File

@@ -1,16 +1,11 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using SquirrelContract.Enums;
using SquirrelContract.Enums;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Infastructure.PostConfigurations;
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.DataModels;
internal class PostDataModel(string postId, string postName, PostType postType, PostConfiguration configuration) : IValidation
public class PostDataModel(string postId, string postName, PostType postType, double salary, bool isActual, DateTime changeDate) : IValidation
{
public string Id { get; private set; } = postId;
@@ -18,39 +13,27 @@ internal class PostDataModel(string postId, string postName, PostType postType,
public PostType PostType { get; private set; } = postType;
public PostConfiguration ConfigurationModel { get; private set; } = configuration;
public double Salary { get; private set; } = salary;
public PostDataModel(string postId, string postName, PostType postType, string configurationJson) : this(postId, postName, postType, (PostConfiguration)null)
{
var obj = JToken.Parse(configurationJson);
if (obj is not null)
{
ConfigurationModel = obj.Value<string>("Type") switch
{
nameof(BartenderPostConfiguration) => JsonConvert.DeserializeObject<BartenderPostConfiguration>(configurationJson)!,
nameof(ManagerPostConfiguration) => JsonConvert.DeserializeObject<ManagerPostConfiguration>(configurationJson)!,
_ => JsonConvert.DeserializeObject<PostConfiguration>(configurationJson)!,
};
}
}
public bool IsActual { get; private set; } = isActual;
public void Validate(IStringLocalizer<Messages> localizer)
public DateTime ChangeDate { get; private set; } = changeDate;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("The value in the field Id is not a unique identifier");
if (PostName.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostName"));
throw new ValidationException("Field PostName is empty");
if (PostType == PostType.None)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostType"));
throw new ValidationException("Field PostType is empty");
if (ConfigurationModel is null)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotInitialized"], "ConfigurationModel"));
if (ConfigurationModel!.Rate <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Rate"));
if (Salary <= 0)
throw new ValidationException("Field Salary is empty");
}
}

View File

@@ -1,38 +1,26 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
namespace BarBelochkaContract.DataModels;
internal class SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary) : IValidation
public class SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary) : IValidation
{
private readonly EmployeeDataModel? _employee;
public string EmployeeId { get; private set; } = employeeId;
public DateTime SalaryDate { get; private set; } = salaryDate;
public double Salary { get; private set; } = employeeSalary;
public string EmployeeFIO => _employee?.FIO ?? string.Empty;
public SalaryDataModel(string employeeId, DateTime salaryDate, double employeeSalary, EmployeeDataModel employee) : this(employeeId, salaryDate, employeeSalary)
{
_employee = employee;
}
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (EmployeeId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "EmployeeId"));
throw new ValidationException("Field EmployeeId is empty");
if (!EmployeeId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "EmployeeId"));
throw new ValidationException("The value in the field EmployeeId is not a unique identifier");
if (Salary <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Salary"));
throw new ValidationException("Field Salary is less than or equal to 0");
}
}

View File

@@ -1,48 +1,32 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Exceptions;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
namespace SquirrelContract.DataModels;
internal class SaleCocktailDataModel(string saleId, string cocktailId, int count, double price) : IValidation
public class SaleCocktailDataModel(string saleId, string cocktailId, int count) : IValidation
{
private readonly CocktailDataModel? _cocktail;
public string SaleId { get; private set; } = saleId;
public string CocktailId { get; private set; } = cocktailId;
public int Count { get; private set; } = count;
public double Price { get; private set; } = price;
public string CocktailName => _cocktail?.CocktailName ?? string.Empty;
public SaleCocktailDataModel(string saleId, string cocktailId, int count, double price, CocktailDataModel cocktail) : this(saleId, cocktailId, count, price)
{
_cocktail = cocktail;
}
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (SaleId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SaleId"));
throw new ValidationException("Field SaleId is empty");
if (!SaleId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SaleId"));
throw new ValidationException("The value in the field SaleId is not a unique identifier");
if (CocktailId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "IProductIdd"));
throw new ValidationException("Field ProductId is empty");
if (!CocktailId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "ProductId"));
throw new ValidationException("The value in the field ProductId is not a unique identifier");
if (Count <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Count"));
if (Price <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price"));
throw new ValidationException("Field Count is less than or equal to 0");
}
}

View File

@@ -1,108 +1,51 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Enums;
using SquirrelContract.Enums;
using SquirrelContract.Exceptions;
using SquirrelContract.Extensions;
using SquirrelContract.Infastructure;
using SquirrelContract.Resources;
namespace SquirrelContract.DataModels;
internal class SaleDataModel : IValidation
public class SaleDataModel(string id, string employeeId, string? clientId, double sum, DiscountType discountType, double discount, bool isCancel, List<SaleCocktailDataModel> saleCocktails) : IValidation
{
private readonly ClientDataModel? _client;
public string Id { get; private set; } = id;
private readonly EmployeeDataModel? _employee;
public string EmployeeId { get; private set; } = employeeId;
public string Id { get; private set; }
public string EmployeeId { get; private set; }
public string? ClientId { get; private set; }
public string? ClientId { get; private set; } = clientId;
public DateTime SaleDate { get; private set; } = DateTime.UtcNow;
public double Sum { get; private set; }
public double Sum { get; private set; } = sum;
public DiscountType DiscountType { get; private set; }
public DiscountType DiscountType { get; private set; } = discountType;
public double Discount { get; private set; }
public double Discount { get; private set; } = discount;
public bool IsCancel { get; private set; } = isCancel;
public bool IsCancel { get; private set; }
public List<SaleCocktailDataModel> Cocktails { get; private set; } = saleCocktails;
public List<SaleCocktailDataModel>? Cocktails { get; private set; }
public string ClientFIO => _client?.FIO ?? string.Empty;
public string EmployeeFIO => _employee?.FIO ?? string.Empty;
public SaleDataModel(string id, string employeeId, string? clientId, DiscountType discountType, bool isCancel, List<SaleCocktailDataModel> saleCocktails)
{
Id = id;
EmployeeId = employeeId;
ClientId = clientId;
DiscountType = discountType;
IsCancel = isCancel;
Cocktails = saleCocktails;
var percent = 0.0;
foreach (DiscountType elem in Enum.GetValues<DiscountType>())
{
if ((elem & discountType) != 0)
{
switch (elem)
{
case DiscountType.None:
break;
case DiscountType.OnSale:
percent += 0.1;
break;
case DiscountType.RegularCustomer:
percent += 0.5;
break;
case DiscountType.Certificate:
percent += 0.3;
break;
}
}
}
Sum = Cocktails?.Sum(x => x.Price * x.Count) ?? 0;
Discount = Sum * percent;
}
public SaleDataModel(string id, string employeeId, string? clientId, double sum, DiscountType discountType, double discount, bool isCancel, List<SaleCocktailDataModel> saleCocktails, EmployeeDataModel employee, ClientDataModel? client) : this(id, employeeId, clientId, discountType, isCancel, saleCocktails)
{
Sum = sum;
Discount = discount;
_employee = employee;
_client = client;
}
public SaleDataModel(string id, string employeeId, string? clientId, int discountType, List<SaleCocktailDataModel> cocktails) : this(id, employeeId, clientId, (DiscountType)discountType, false, cocktails) { }
public void Validate(IStringLocalizer<Messages> localizer)
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
throw new ValidationException("The value in the field Id is not a unique identifier");
if (EmployeeId.IsEmpty())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "EmployeeId"));
throw new ValidationException("Field EmployeeId is empty");
if (!EmployeeId.IsGuid())
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "EmployeeId"));
throw new ValidationException("The value in the field EmployeeId is not a unique identifier");
if (!ClientId?.IsGuid() ?? !ClientId?.IsEmpty() ?? false)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "ClientId"));
throw new ValidationException("The value in the field BuyerId is not a unique identifier");
if (Sum <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Sum"));
throw new ValidationException("Field Sum is less than or equal to 0");
if (Cocktails is null)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotInitialized"], "Cocktails"));
if (Cocktails.Count == 0)
throw new ValidationException(localizer["ValidationExceptionMessageNoCocktailsInSale"]);
Cocktails.ForEach(x => x.Validate(localizer));
if ((Cocktails?.Count ?? 0) == 0)
throw new ValidationException("The sale must include cocktails");
}
}

View File

@@ -1,10 +1,11 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.Exceptions;
namespace SquirrelContract.Exceptions;
internal class ElementNotFoundException(string value, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["ElementNotFoundExceptionMessage"], value))
public class ElementNotFoundException : Exception
{
public string Value { get; private set; } = value;
public string Value { get; private set; }
public ElementNotFoundException(string value) : base($"Element not found at value = {value}")
{
Value = value;
}
}

View File

@@ -1,12 +1,14 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.Exceptions;
namespace SquirrelContract.Exceptions;
internal class ElementExistsException(string paramName, string paramValue, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["ElementExistsExceptionMessage"], paramValue, paramName))
public class ElementExistsException : Exception
{
public string ParamName { get; private set; } = paramName;
public string ParamName { get; private set; }
public string ParamValue { get; private set; } = paramValue;
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;
}
}

View File

@@ -1,8 +1,6 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.Exceptions;
namespace SquirrelContract.Exceptions;
internal class IncorrectDatesException(DateTime start, DateTime end, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["IncorrectDatesExceptionMessage"], start.ToShortDateString(), end.ToShortDateString()))
{ }
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}") { }
}

View File

@@ -0,0 +1,6 @@
namespace SquirrelContract.Exceptions;
public class NullListException : Exception
{
public NullListException() : base("The returned list is null") { }
}

View File

@@ -1,8 +1,6 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.Exceptions;
namespace SquirrelContract.Exceptions;
internal class StorageException(Exception ex, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["StorageExceptionMessage"], ex.Message), ex)
{ }
public class StorageException : Exception
{
public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex) { }
}

View File

@@ -1,7 +0,0 @@
namespace SquirrelContract.Infastructure;
public interface IConfigurationSalary
{
double ExtraSaleSum { get; }
int MaxConcurrentThreads { get; }
}

View File

@@ -1,9 +1,6 @@
using Microsoft.Extensions.Localization;
using SquirrelContract.Resources;
namespace SquirrelContract.Infastructure;
namespace SquirrelContract.Infastructure;
internal interface IValidation
public interface IValidation
{
void Validate(IStringLocalizer<Messages> localizer);
void Validate();
}

View File

@@ -1,49 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net;
namespace SquirrelContract.Infrastructure;
public class OperationResponse
{
protected HttpStatusCode StatusCode { get; set; }
protected object? Result { get; set; }
protected string? FileName { get; set; }
public IActionResult GetResponse(HttpRequest request, HttpResponse response)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(response);
response.StatusCode = (int)StatusCode;
if (Result is null)
{
return new StatusCodeResult((int)StatusCode);
}
if (Result is Stream stream)
{
return new FileStreamResult(stream, "application/octetstream")
{
FileDownloadName = FileName
};
}
return new ObjectResult(Result);
}
protected static TResult OK<TResult, TData>(TData data) where TResult :
OperationResponse, new() => new() { StatusCode = HttpStatusCode.OK, Result = data };
protected static TResult OK<TResult, TData>(TData data, string fileName) where TResult : OperationResponse, new()
=> new() { StatusCode = HttpStatusCode.OK, Result = data, FileName = fileName };
protected static TResult NoContent<TResult>() where TResult : OperationResponse, new() => new() { StatusCode = HttpStatusCode.NoContent };
protected static TResult BadRequest<TResult>(string? errorMessage = null)
where TResult : OperationResponse, new() => new() { StatusCode = HttpStatusCode.BadRequest, Result = errorMessage };
protected static TResult NotFound<TResult>(string? errorMessage = null)
where TResult : OperationResponse, new() => new() { StatusCode = HttpStatusCode.NotFound, Result = errorMessage };
protected static TResult InternalServerError<TResult>(string? errorMessage = null)
where TResult : OperationResponse, new() => new() { StatusCode = HttpStatusCode.InternalServerError, Result = errorMessage };
}

View File

@@ -1,17 +0,0 @@
using Microsoft.Extensions.Configuration;
namespace SquirrelContract.Infastructure.PostConfigurations;
public class BartenderPostConfiguration : PostConfiguration
{
public override string Type => nameof(BartenderPostConfiguration);
public double SalePercent { get; set; }
public double BonusForExtraSales { get; set; }
public BartenderPostConfiguration(IConfiguration? config = null)
{
if (config != null)
{
config.GetSection("BartenderSettings");
}
}
}

View File

@@ -1,7 +0,0 @@
namespace SquirrelContract.Infastructure.PostConfigurations;
public class ManagerPostConfiguration : PostConfiguration
{
public override string Type => nameof(ManagerPostConfiguration);
public double PersonalCountTrendPremium { get; set; }
}

View File

@@ -1,10 +0,0 @@
using System.Globalization;
namespace SquirrelContract.Infastructure.PostConfigurations;
public class PostConfiguration
{
public virtual string Type => nameof(PostConfiguration);
public double Rate { get; set; }
public string CultureName { get; set; } = CultureInfo.CurrentCulture.Name;
}

View File

@@ -1,432 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SquirrelContract.Resources {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом 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() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[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("SquirrelContract.Resources.Messages", typeof(Messages).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Элемент по данным: {0} был удален.
/// </summary>
internal static string AdapterMessageElementDeletedException {
get {
return ResourceManager.GetString("AdapterMessageElementDeletedException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Не найден элемент по данным: {0}.
/// </summary>
internal static string AdapterMessageElementNotFoundException {
get {
return ResourceManager.GetString("AdapterMessageElementNotFoundException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Данные пусты.
/// </summary>
internal static string AdapterMessageEmptyDate {
get {
return ResourceManager.GetString("AdapterMessageEmptyDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Неправильные даты: {0}.
/// </summary>
internal static string AdapterMessageIncorrectDatesException {
get {
return ResourceManager.GetString("AdapterMessageIncorrectDatesException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Ошибка при обработке данных: {0}.
/// </summary>
internal static string AdapterMessageInvalidOperationException {
get {
return ResourceManager.GetString("AdapterMessageInvalidOperationException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Ошибка при работе с хранилищем данных: {0}.
/// </summary>
internal static string AdapterMessageStorageException {
get {
return ResourceManager.GetString("AdapterMessageStorageException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Переданы неверные данные: {0}.
/// </summary>
internal static string AdapterMessageValidationException {
get {
return ResourceManager.GetString("AdapterMessageValidationException", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Коктель.
/// </summary>
internal static string DocumentDocCaptionCocktail {
get {
return ResourceManager.GetString("DocumentDocCaptionCocktail", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Дата.
/// </summary>
internal static string DocumentDocCaptionData {
get {
return ResourceManager.GetString("DocumentDocCaptionData", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Предыдущие названия.
/// </summary>
internal static string DocumentDocCaptionPreviousNames {
get {
return ResourceManager.GetString("DocumentDocCaptionPreviousNames", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на История изменения коктелей.
/// </summary>
internal static string DocumentDocHeader {
get {
return ResourceManager.GetString("DocumentDocHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Сформировано на дату {0}.
/// </summary>
internal static string DocumentDocSubHeader {
get {
return ResourceManager.GetString("DocumentDocSubHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Товар.
/// </summary>
internal static string DocumentExcelCaptionCocktail {
get {
return ResourceManager.GetString("DocumentExcelCaptionCocktail", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Кол-во.
/// </summary>
internal static string DocumentExcelCaptionCount {
get {
return ResourceManager.GetString("DocumentExcelCaptionCount", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Дата.
/// </summary>
internal static string DocumentExcelCaptionDate {
get {
return ResourceManager.GetString("DocumentExcelCaptionDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Скидка.
/// </summary>
internal static string DocumentExcelCaptionDiscount {
get {
return ResourceManager.GetString("DocumentExcelCaptionDiscount", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Сумма.
/// </summary>
internal static string DocumentExcelCaptionSum {
get {
return ResourceManager.GetString("DocumentExcelCaptionSum", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Всего.
/// </summary>
internal static string DocumentExcelCaptionTotal {
get {
return ResourceManager.GetString("DocumentExcelCaptionTotal", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Продажи за период.
/// </summary>
internal static string DocumentExcelHeader {
get {
return ResourceManager.GetString("DocumentExcelHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Сотрудник.
/// </summary>
internal static string DocumentExcelHeaderEmployee {
get {
return ResourceManager.GetString("DocumentExcelHeaderEmployee", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на c {0} по {1}.
/// </summary>
internal static string DocumentExcelSubHeader {
get {
return ResourceManager.GetString("DocumentExcelSubHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Начисления.
/// </summary>
internal static string DocumentPdfDiagramCaption {
get {
return ResourceManager.GetString("DocumentPdfDiagramCaption", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Зарплатная ведомость.
/// </summary>
internal static string DocumentPdfHeader {
get {
return ResourceManager.GetString("DocumentPdfHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на за период с {0} по {1}.
/// </summary>
internal static string DocumentPdfSubHeader {
get {
return ResourceManager.GetString("DocumentPdfSubHeader", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Нельзя изменить удаленный элемент (идентификатор: {0}).
/// </summary>
internal static string ElementDeletedExceptionMessage {
get {
return ResourceManager.GetString("ElementDeletedExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Уже существует элемент со значением {0} параметра {1}.
/// </summary>
internal static string ElementExistsExceptionMessage {
get {
return ResourceManager.GetString("ElementExistsExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Элемент не найден по значению = {0}.
/// </summary>
internal static string ElementNotFoundExceptionMessage {
get {
return ResourceManager.GetString("ElementNotFoundExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Дата окончания должна быть позже даты начала. Дата начала: {0}. ​​Дата окончания: {1}.
/// </summary>
internal static string IncorrectDatesExceptionMessage {
get {
return ResourceManager.GetString("IncorrectDatesExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Недостаточно данных для обработки: {0}.
/// </summary>
internal static string NotEnoughDataToProcessExceptionMessage {
get {
return ResourceManager.GetString("NotEnoughDataToProcessExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Не найдены данные.
/// </summary>
internal static string NotFoundDataMessage {
get {
return ResourceManager.GetString("NotFoundDataMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Ошибка при работе в хранилище: {0}.
/// </summary>
internal static string StorageExceptionMessage {
get {
return ResourceManager.GetString("StorageExceptionMessage", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Дата трудоустройства не может быть раньше даты рождения ({0}, {1}).
/// </summary>
internal static string ValidationExceptionMessageEmploymentDateAndBirthDate {
get {
return ResourceManager.GetString("ValidationExceptionMessageEmploymentDateAndBirthDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле {0} пусто.
/// </summary>
internal static string ValidationExceptionMessageEmptyField {
get {
return ResourceManager.GetString("ValidationExceptionMessageEmptyField", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Фамилия не корректна.
/// </summary>
internal static string ValidationExceptionMessageIncorrectFIO_ {
get {
return ResourceManager.GetString("ValidationExceptionMessageIncorrectFIO ", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле Телефонный номер не является телефонным номером.
/// </summary>
internal static string ValidationExceptionMessageIncorrectPhoneNumber {
get {
return ResourceManager.GetString("ValidationExceptionMessageIncorrectPhoneNumber", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле {0} меньше или равно 0.
/// </summary>
internal static string ValidationExceptionMessageLessOrEqualZero {
get {
return ResourceManager.GetString("ValidationExceptionMessageLessOrEqualZero", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Несовершеннолетние не могут быть приняты на работу (Дата рождения: {0}).
/// </summary>
internal static string ValidationExceptionMessageMinorsBirthDate {
get {
return ResourceManager.GetString("ValidationExceptionMessageMinorsBirthDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Несовершеннолетние не могут быть приняты на работу (Дата трудоустройства {0}, Дата рождения: {1}).
/// </summary>
internal static string ValidationExceptionMessageMinorsEmploymentDate {
get {
return ResourceManager.GetString("ValidationExceptionMessageMinorsEmploymentDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на В продаже должен быть хотя бы один товар.
/// </summary>
internal static string ValidationExceptionMessageNoProductsInSale {
get {
return ResourceManager.GetString("ValidationExceptionMessageNoProductsInSale", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле {0} не является типом уникального идентификатора.
/// </summary>
internal static string ValidationExceptionMessageNotAId {
get {
return ResourceManager.GetString("ValidationExceptionMessageNotAId", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле {0} не проиницализировано.
/// </summary>
internal static string ValidationExceptionMessageNotInitialized {
get {
return ResourceManager.GetString("ValidationExceptionMessageNotInitialized", resourceCulture);
}
}
}
}

View File

@@ -1,243 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DocumentDocCaptionCocktail" xml:space="preserve">
<value>Cocktail</value>
</data>
<data name="DocumentDocHeader" xml:space="preserve">
<value>The history of cocktail changes</value>
</data>
<data name="DocumentDocSubHeader" xml:space="preserve">
<value>Make In Date {0}</value>
</data>
<data name="DocumentExcelCaptionCount" xml:space="preserve">
<value>Count</value>
</data>
<data name="DocumentExcelCaptionDate" xml:space="preserve">
<value>Date</value>
</data>
<data name="DocumentExcelCaptionDiscount" xml:space="preserve">
<value>Discount</value>
</data>
<data name="DocumentExcelCaptionCocktail" xml:space="preserve">
<value>Cocktail</value>
</data>
<data name="DocumentExcelCaptionSum" xml:space="preserve">
<value>Sum</value>
</data>
<data name="DocumentExcelCaptionTotal" xml:space="preserve">
<value>Total</value>
</data>
<data name="DocumentExcelHeader" xml:space="preserve">
<value>Sales for the period</value>
</data>
<data name="DocumentExcelSubHeader" xml:space="preserve">
<value>from {0} to {1}</value>
</data>
<data name="DocumentPdfHeader" xml:space="preserve">
<value>Payroll</value>
</data>
<data name="DocumentPdfSubHeader" xml:space="preserve">
<value>for the period from {0} to {1}</value>
</data>
<data name="DocumentPdfDiagramCaption" xml:space="preserve">
<value>Accruals</value>
</data>
<data name="NotFoundDataMessage" xml:space="preserve">
<value>No data found</value>
</data>
<data name="ValidationExceptionMessageNotAId" xml:space="preserve">
<value>The value in the {0} field is not a unique identifier type.</value>
</data>
<data name="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>The value in field {0} is empty</value>
</data>
<data name="ValidationExceptionMessageIncorrectPhoneNumber" xml:space="preserve">
<value>The value in the Phone Number field is not a phone number.</value>
</data>
<data name="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>The value in field {0} is not initialized</value>
</data>
<data name="ValidationExceptionMessageLessOrEqualZero" xml:space="preserve">
<value>The value in field {0} is less than or equal to 0</value>
</data>
<data name="ValidationExceptionMessageNoProductsInSale" xml:space="preserve">
<value>There must be at least one product on sale.</value>
</data>
<data name="ValidationExceptionMessageMinorsBirthDate" xml:space="preserve">
<value>Minors cannot be hired (BirthDate = {0})</value>
</data>
<data name="ValidationExceptionMessageMinorsEmploymentDate" xml:space="preserve">
<value>Minors cannot be hired (EmploymentDate: {0}, BirthDate {1})</value>
</data>
<data name="ValidationExceptionMessageEmploymentDateAndBirthDate" xml:space="preserve">
<value>Date of employment cannot be earlier than date of birth ({0}, {1})</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>Error while working with data storage: {0}</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>Data is empty</value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>Not found element by data: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>Incorrect data transmitted: {0}</value>
</data>
<data name="AdapterMessageElementDeletedException" xml:space="preserve">
<value>The item according to the data: {0} has been deleted</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>Error processing data: {0}</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>Incorrect dates: {0}</value>
</data>
<data name="ElementDeletedExceptionMessage" xml:space="preserve">
<value>Cannot modify a deleted item (id: {0})</value>
</data>
<data name="ElementExistsExceptionMessage" xml:space="preserve">
<value>There is already an element with value {0} of parameter {1}</value>
</data>
<data name="ElementNotFoundExceptionMessage" xml:space="preserve">
<value>Element not found at value = {0}</value>
</data>
<data name="IncorrectDatesExceptionMessage" xml:space="preserve">
<value>The end date must be later than the start date.. StartDate: {0}. EndDate: {1}</value>
</data>
<data name="NotEnoughDataToProcessExceptionMessage" xml:space="preserve">
<value>Not enough data to process: {0}</value>
</data>
<data name="StorageExceptionMessage" xml:space="preserve">
<value>Error while working in storage: {0}</value>
</data>
<data name="DocumentExcelHeaderEmployee" xml:space="preserve">
<value>Employee</value>
</data>
<data name="DocumentDocCaptionPreviousNames" xml:space="preserve">
<value>Previous names</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>Data</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO " xml:space="preserve">
<value>Fio is not correct</value>
</data>
</root>

View File

@@ -1,243 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DocumentDocCaptionCocktail" xml:space="preserve">
<value>Коктель</value>
</data>
<data name="DocumentDocHeader" xml:space="preserve">
<value>История изменения коктелей</value>
</data>
<data name="DocumentDocSubHeader" xml:space="preserve">
<value>Сформировано на дату {0}</value>
</data>
<data name="DocumentExcelCaptionCount" xml:space="preserve">
<value>Кол-во</value>
</data>
<data name="DocumentExcelCaptionDate" xml:space="preserve">
<value>Дата</value>
</data>
<data name="DocumentExcelCaptionDiscount" xml:space="preserve">
<value>Скидка</value>
</data>
<data name="DocumentExcelCaptionCocktail" xml:space="preserve">
<value>Товар</value>
</data>
<data name="DocumentExcelCaptionSum" xml:space="preserve">
<value>Сумма</value>
</data>
<data name="DocumentExcelCaptionTotal" xml:space="preserve">
<value>Всего</value>
</data>
<data name="DocumentExcelHeader" xml:space="preserve">
<value>Продажи за период</value>
</data>
<data name="DocumentExcelSubHeader" xml:space="preserve">
<value>c {0} по {1}</value>
</data>
<data name="DocumentPdfHeader" xml:space="preserve">
<value>Зарплатная ведомость</value>
</data>
<data name="DocumentPdfSubHeader" xml:space="preserve">
<value>за период с {0} по {1}</value>
</data>
<data name="DocumentPdfDiagramCaption" xml:space="preserve">
<value>Начисления</value>
</data>
<data name="NotFoundDataMessage" xml:space="preserve">
<value>Не найдены данные</value>
</data>
<data name="ValidationExceptionMessageNotAId" xml:space="preserve">
<value>Значение в поле {0} не является типом уникального идентификатора</value>
</data>
<data name="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>Значение в поле {0} пусто</value>
</data>
<data name="ValidationExceptionMessageIncorrectPhoneNumber" xml:space="preserve">
<value>Значение в поле Телефонный номер не является телефонным номером</value>
</data>
<data name="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>Значение в поле {0} не проиницализировано</value>
</data>
<data name="ValidationExceptionMessageLessOrEqualZero" xml:space="preserve">
<value>Значение в поле {0} меньше или равно 0</value>
</data>
<data name="ValidationExceptionMessageNoProductsInSale" xml:space="preserve">
<value>В продаже должен быть хотя бы один товар</value>
</data>
<data name="ValidationExceptionMessageMinorsBirthDate" xml:space="preserve">
<value>Несовершеннолетние не могут быть приняты на работу (Дата рождения: {0})</value>
</data>
<data name="ValidationExceptionMessageMinorsEmploymentDate" xml:space="preserve">
<value>Несовершеннолетние не могут быть приняты на работу (Дата трудоустройства {0}, Дата рождения: {1})</value>
</data>
<data name="ValidationExceptionMessageEmploymentDateAndBirthDate" xml:space="preserve">
<value>Дата трудоустройства не может быть раньше даты рождения ({0}, {1})</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>Ошибка при работе с хранилищем данных: {0}</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>Данные пусты</value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>Не найден элемент по данным: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>Переданы неверные данные: {0}</value>
</data>
<data name="AdapterMessageElementDeletedException" xml:space="preserve">
<value>Элемент по данным: {0} был удален</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>Ошибка при обработке данных: {0}</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>Неправильные даты: {0}</value>
</data>
<data name="ElementDeletedExceptionMessage" xml:space="preserve">
<value>Нельзя изменить удаленный элемент (идентификатор: {0})</value>
</data>
<data name="ElementExistsExceptionMessage" xml:space="preserve">
<value>Уже существует элемент со значением {0} параметра {1}</value>
</data>
<data name="ElementNotFoundExceptionMessage" xml:space="preserve">
<value>Элемент не найден по значению = {0}</value>
</data>
<data name="IncorrectDatesExceptionMessage" xml:space="preserve">
<value>Дата окончания должна быть позже даты начала. Дата начала: {0}. ​​Дата окончания: {1}</value>
</data>
<data name="NotEnoughDataToProcessExceptionMessage" xml:space="preserve">
<value>Недостаточно данных для обработки: {0}</value>
</data>
<data name="StorageExceptionMessage" xml:space="preserve">
<value>Ошибка при работе в хранилище: {0}</value>
</data>
<data name="DocumentExcelHeaderEmployee" xml:space="preserve">
<value>Сотрудник</value>
</data>
<data name="DocumentDocCaptionPreviousNames" xml:space="preserve">
<value>Предыдущие названия</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>Дата</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO " xml:space="preserve">
<value>Фамилия не корректна</value>
</data>
</root>

View File

@@ -1,243 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DocumentDocCaptionCocktail" xml:space="preserve">
<value>鸡尾酒会</value>
</data>
<data name="DocumentDocHeader" xml:space="preserve">
<value>鸡尾酒变化的历史</value>
</data>
<data name="DocumentDocSubHeader" xml:space="preserve">
<value>在日期{0}生成</value>
</data>
<data name="DocumentExcelCaptionCount" xml:space="preserve">
<value>数量</value>
</data>
<data name="DocumentExcelCaptionDate" xml:space="preserve">
<value>日期</value>
</data>
<data name="DocumentExcelCaptionDiscount" xml:space="preserve">
<value>折扣优惠</value>
</data>
<data name="DocumentExcelCaptionCocktail" xml:space="preserve">
<value>鸡尾酒会</value>
</data>
<data name="DocumentExcelCaptionSum" xml:space="preserve">
<value>金额</value>
</data>
<data name="DocumentExcelCaptionTotal" xml:space="preserve">
<value>总计</value>
</data>
<data name="DocumentExcelHeader" xml:space="preserve">
<value>期间的销售额</value>
</data>
<data name="DocumentExcelSubHeader" xml:space="preserve">
<value>从{0}到{1}</value>
</data>
<data name="DocumentPdfHeader" xml:space="preserve">
<value>薪金表</value>
</data>
<data name="DocumentPdfSubHeader" xml:space="preserve">
<value>从{0}到{1}的期间</value>
</data>
<data name="DocumentPdfDiagramCaption" xml:space="preserve">
<value>应计事项</value>
</data>
<data name="NotFoundDataMessage" xml:space="preserve">
<value>未找到数据</value>
</data>
<data name="ValidationExceptionMessageNotAId" xml:space="preserve">
<value>字段 {0} 的值不是唯一标识符类型</value>
</data>
<data name="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>字段 {0} 的值为空</value>
</data>
<data name="ValidationExceptionMessageIncorrectPhoneNumber" xml:space="preserve">
<value>电话号码字段中的值不是电话号码。</value>
</data>
<data name="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>{0}字段中的值未初始化</value>
</data>
<data name="ValidationExceptionMessageLessOrEqualZero" xml:space="preserve">
<value>{0}字段中的值小于或等于0</value>
</data>
<data name="ValidationExceptionMessageNoProductsInSale" xml:space="preserve">
<value>必须至少有一种产品在售。</value>
</data>
<data name="ValidationExceptionMessageMinorsBirthDate" xml:space="preserve">
<value>未成年人不能就业(出生日期:{0}</value>
</data>
<data name="ValidationExceptionMessageMinorsEmploymentDate" xml:space="preserve">
<value>未成年人不能就业(就业日期:{0},出生日期:{1}</value>
</data>
<data name="ValidationExceptionMessageEmploymentDateAndBirthDate" xml:space="preserve">
<value>就业日期不能早于出生日期({0},{1})</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>使用数据仓库时出错:{0}</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>数据为空</value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>未找到元素数据: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>传递的数据不正确: {0}</value>
</data>
<data name="AdapterMessageElementDeletedException" xml:space="preserve">
<value>根据数据的项目:{0}已被删除</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>数据处理过程中的错误:{0}</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>不正确的日期:{0}</value>
</data>
<data name="ElementDeletedExceptionMessage" xml:space="preserve">
<value>无法更改已删除的项目(id:{0})</value>
</data>
<data name="ElementExistsExceptionMessage" xml:space="preserve">
<value>已经有一个具有参数{1}的值{0}的元素</value>
</data>
<data name="ElementNotFoundExceptionMessage" xml:space="preserve">
<value>值={0}未找到该元素</value>
</data>
<data name="IncorrectDatesExceptionMessage" xml:space="preserve">
<value>结束日期必须晚于开始日期。 开始日期:{0}。 ​​结束日期:{1}</value>
</data>
<data name="NotEnoughDataToProcessExceptionMessage" xml:space="preserve">
<value>处理数据不足:{0}</value>
</data>
<data name="StorageExceptionMessage" xml:space="preserve">
<value>在存储中工作时出错:{0}</value>
</data>
<data name="DocumentExcelHeaderEmployee" xml:space="preserve">
<value>工人</value>
</data>
<data name="DocumentDocCaptionPreviousNames" xml:space="preserve">
<value>以前的名字</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>日期</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO " xml:space="preserve">
<value>名称格式不正确</value>
</data>
</root>

View File

@@ -6,34 +6,4 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Messages.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Messages.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Messages.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Messages.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="SquirrelBusinessLogic" />
<InternalsVisibleTo Include="SquirrelDatabase" />
<InternalsVisibleTo Include="SquirrelWebApi" />
<InternalsVisibleTo Include="SquirrelTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.StoragesContracts;
internal interface IClientStorageContract
public interface IClientStorageContract
{
List<ClientDataModel> GetList();

View File

@@ -2,11 +2,10 @@
namespace SquirrelContract.StoragesContracts;
internal interface ICocktailStorageContract
public interface ICocktailStorageContract
{
List<CocktailDataModel> GetList();
List<CocktailHistoryDataModel> GetHistoryByCocktailId(string cocktailId);
Task<List<CocktailHistoryDataModel>> GetHistoriesListAsync(CancellationToken ct);
CocktailDataModel? GetElementById(string id);
CocktailDataModel? GetElementByName(string name);
void AddElement(CocktailDataModel cocktailDataModel);

View File

@@ -2,7 +2,7 @@
namespace SquirrelContract.StoragesContracts;
internal interface IEmployeeStorageContract
public interface IEmployeeStorageContract
{
List<EmployeeDataModel> GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null);
@@ -17,6 +17,4 @@ internal interface IEmployeeStorageContract
void UpdElement(EmployeeDataModel employeeDataModel);
void DelElement(string id);
int GetEmployeeTrend(DateTime fromPeriod, DateTime toPeriod);
}

View File

@@ -2,9 +2,9 @@
namespace SquirrelContract.StoragesContracts;
internal interface IPostStorageContract
public interface IPostStorageContract
{
List<PostDataModel> GetList();
List<PostDataModel> GetList(bool onlyActual = true);
List<PostDataModel> GetPostWithHistory(string postId);
PostDataModel? GetElementById(string id);
PostDataModel? GetElementByName(string name);

View File

@@ -2,9 +2,9 @@
namespace SquirrelContract.StoragesContracts;
internal interface ISalaryStorageContract
public interface ISalaryStorageContract
{
List<SalaryDataModel> GetList(DateTime? startDate, DateTime? endDate, string? employeeId = null);
Task<List<SalaryDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? employeeId = null);
void AddElement(SalaryDataModel salaryDataModel);
}

View File

@@ -2,12 +2,10 @@
namespace SquirrelContract.StoragesContracts;
internal interface ISaleStorageContract
public interface ISaleStorageContract
{
List<SaleDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? employeeId = null, string? clientId = null, string? cocktailId = null);
Task<List<SaleDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
SaleDataModel? GetElementById(string id);
void AddElement(SaleDataModel saleDataModel);

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.ViewModels;
public class ClientViewModel
{
public required string Id { get; set; }
public required string FIO { get; set; }
public required string PhoneNumber { get; set; }
public double DiscountSize { get; set; }
}

View File

@@ -1,8 +0,0 @@
namespace SquirrelContract.ViewModels;
public class CocktailAndCocktailHistoryViewModel
{
public required string CocktailName { get; set; }
public required List<string> Histories { get; set; }
public required List<string> Data { get; set; }
}

View File

@@ -1,10 +0,0 @@
namespace SquirrelContract.ViewModels;
public class CocktailHistoryViewModel
{
public required string CocktailName { get; set; }
public double OldPrice { get; set; }
public DateTime ChangeDate { get; set; }
}

View File

@@ -1,13 +0,0 @@
namespace SquirrelContract.ViewModels;
public class CocktailViewModel
{
public required string Id { get; set; }
public required string CocktailName { get; set; }
public required string BaseAlcohol { get; set; }
public double Price { get; set; }
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelContract.ViewModels;
public class EmployeeSalaryByPeriodViewModel
{
public required string EmployeeFIO { get; set; }
public double TotalSalary { get; set; }
public DateTime FromPeriod { get; set; }
public DateTime ToPeriod { get; set; }
}

View File

@@ -1,20 +0,0 @@
namespace SquirrelContract.ViewModels;
public class EmployeeViewModel
{
public required string Id { get; set; }
public required string FIO { get; set; }
public string Email { get; set; }
public required string PostId { get; set; }
public required string PostName { get; set; }
public bool IsDeleted { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
}

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.ViewModels;
public class PostViewModel
{
public required string Id { get; set; }
public required string PostName { get; set; }
public required string PostType { get; set; }
public required string Configuration { get; set; }
}

View File

@@ -1,9 +0,0 @@
namespace SquirrelContract.ViewModels;
public class SalaryViewModel
{
public required string EmployeeId { get; set; }
public required string EmployeeFIO { get; set; }
public DateTime SalaryDate { get; set; }
public double Salary { get; set; }
}

View File

@@ -1,12 +0,0 @@
namespace SquirrelContract.ViewModels;
public class SaleCocktailViewModel
{
public required string CocktailId { get; set; }
public required string CocktailName { get; set; }
public int Count { get; set; }
public double Price { get; set; }
}

View File

@@ -1,26 +0,0 @@
namespace SquirrelContract.ViewModels;
public class SaleViewModel
{
public required string Id { get; set; }
public required string EmployeeId { get; set; }
public required string EmployeeFIO { get; set; }
public string? ClientId { get; set; }
public string? ClientFIO { get; set; }
public DateTime SaleDate { get; set; }
public double Sum { get; set; }
public required string DiscountType { get; set; }
public double Discount { get; set; }
public bool IsCancel { get; set; }
public required List<SaleCocktailViewModel> Cocktails { get; set; }
}

View File

@@ -1,8 +0,0 @@
using SquirrelContract.Infastructure;
namespace SquirrelDatabase;
class DefaultConfigurationDatabase : IConfigurationDatabase
{
public string ConnectionString => "";
}

View File

@@ -1,24 +1,20 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
using System;
namespace SquirrelDatabase.Implementations;
internal class ClientStorageContract : IClientStorageContract
public class ClientStorageContract : IClientStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public ClientStorageContract(SquirrelDbContext squirrelDbContext, IStringLocalizer<Messages> localizer)
public ClientStorageContract(SquirrelDbContext squirrelDbContext)
{
_dbContext = squirrelDbContext;
var config = new MapperConfiguration(cfg =>
@@ -26,8 +22,6 @@ internal class ClientStorageContract : IClientStorageContract
cfg.AddMaps(typeof(SquirrelDbContext).Assembly);
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<ClientDataModel> GetList()
@@ -39,7 +33,7 @@ internal class ClientStorageContract : IClientStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -52,7 +46,7 @@ internal class ClientStorageContract : IClientStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -65,7 +59,7 @@ internal class ClientStorageContract : IClientStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -78,7 +72,7 @@ internal class ClientStorageContract : IClientStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -92,22 +86,17 @@ internal class ClientStorageContract : IClientStorageContract
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", clientDataModel.Id, _localizer);
throw new ElementExistsException("Id", clientDataModel.Id);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "PK_Clients" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", clientDataModel.Id, _localizer);
throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -115,7 +104,7 @@ internal class ClientStorageContract : IClientStorageContract
{
try
{
var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id, _localizer);
var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id);
_dbContext.Clients.Update(_mapper.Map(clientDataModel, element));
_dbContext.SaveChanges();
}
@@ -127,12 +116,12 @@ internal class ClientStorageContract : IClientStorageContract
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber, _localizer);
throw new ElementExistsException("PhoneNumber", clientDataModel.PhoneNumber);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -140,7 +129,7 @@ internal class ClientStorageContract : IClientStorageContract
{
try
{
var element = GetClientById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetClientById(id) ?? throw new ElementNotFoundException(id);
_dbContext.Clients.Remove(element);
_dbContext.SaveChanges();
}
@@ -152,7 +141,7 @@ internal class ClientStorageContract : IClientStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}

View File

@@ -1,45 +1,28 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
namespace SquirrelDatabase.Implementations;
internal class CocktailStorageContract : ICocktailStorageContract
public class CocktailStorageContract : ICocktailStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public CocktailStorageContract(SquirrelDbContext dbContext, IStringLocalizer<Messages> localizer)
public CocktailStorageContract(SquirrelDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Cocktail, CocktailDataModel>();
cfg.CreateMap<CocktailDataModel, Cocktail>();
cfg.CreateMap<CocktailHistory, CocktailHistoryDataModel>()
.ConstructUsing(src => new CocktailHistoryDataModel(
src.CocktailId.ToString(),
src.OldPrice,
src.ChangeDate,
new CocktailDataModel(
src.Cocktail.Id.ToString(),
src.Cocktail.CocktailName,
src.Cocktail.Price,
src.Cocktail.BaseAlcohol
)
));
cfg.CreateMap<CocktailHistory, CocktailHistoryDataModel>();
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<CocktailDataModel> GetList()
@@ -51,7 +34,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -59,25 +42,12 @@ internal class CocktailStorageContract : ICocktailStorageContract
{
try
{
return [.. _dbContext.CocktailHistories.Include(x => x.Cocktail).Where(x => x.CocktailId == cocktailId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<CocktailHistoryDataModel>(x))];
return [.. _dbContext.CocktailHistories.Where(x => x.CocktailId == cocktailId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<CocktailHistoryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public async Task<List<CocktailHistoryDataModel>> GetHistoriesListAsync(CancellationToken ct)
{
try
{
return [.. await _dbContext.CocktailHistories.Include(x => x.Cocktail).Select(x => _mapper.Map<CocktailHistoryDataModel>(x)).ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -90,7 +60,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -103,7 +73,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -117,22 +87,17 @@ internal class CocktailStorageContract : ICocktailStorageContract
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", cocktailDataModel.Id, _localizer);
throw new ElementExistsException("Id", cocktailDataModel.Id);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Cocktails_CocktailName" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("CocktailName", cocktailDataModel.CocktailName, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "PK_Cocktails" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", cocktailDataModel.Id, _localizer);
throw new ElementExistsException("CocktailName", cocktailDataModel.CocktailName);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -140,39 +105,24 @@ internal class CocktailStorageContract : ICocktailStorageContract
{
try
{
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetCocktailById(cocktailDataModel.Id) ?? throw new ElementNotFoundException(cocktailDataModel.Id, _localizer);
if (element.Price != cocktailDataModel.Price)
{
_dbContext.CocktailHistories.Add(new CocktailHistory() { CocktailId = element.Id, OldPrice = element.Price });
_dbContext.SaveChanges();
}
_dbContext.Cocktails.Update(_mapper.Map(cocktailDataModel, element));
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
var element = GetCocktailById(cocktailDataModel.Id) ?? throw new ElementNotFoundException(cocktailDataModel.Id);
_dbContext.Cocktails.Update(_mapper.Map(cocktailDataModel, element));
_dbContext.SaveChanges();
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Cocktails_CocktailName" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("CocktailName", cocktailDataModel.CocktailName, _localizer);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Cocktails_CocktailName" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("CocktailName", cocktailDataModel.CocktailName);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -180,7 +130,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
{
try
{
var element = GetCocktailById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetCocktailById(id) ?? throw new ElementNotFoundException(id);
_dbContext.Cocktails.Remove(element);
_dbContext.SaveChanges();
}
@@ -192,7 +142,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -200,7 +150,7 @@ internal class CocktailStorageContract : ICocktailStorageContract
{
try
{
var element = GetCocktailById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetCocktailById(id) ?? throw new ElementNotFoundException(id);
_dbContext.SaveChanges();
}
catch

View File

@@ -1,35 +1,24 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
namespace SquirrelDatabase.Implementations;
internal class EmployeeStorageContract : IEmployeeStorageContract
public class EmployeeStorageContract : IEmployeeStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public EmployeeStorageContract(SquirrelDbContext dbContext, IStringLocalizer<Messages> localizer)
public EmployeeStorageContract(SquirrelDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<Employee, EmployeeDataModel>();
cfg.CreateMap<EmployeeDataModel, Employee>();
cfg.AddMaps(typeof(SquirrelDbContext).Assembly);
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<EmployeeDataModel> GetList(bool onlyActive = true, string? postId = null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime? fromEmploymentDate = null, DateTime? toEmploymentDate = null)
@@ -47,18 +36,18 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
}
if (fromBirthDate is not null && toBirthDate is not null)
{
query = query.Where(x => x.BirthDate >= DateTime.SpecifyKind(fromBirthDate ?? DateTime.UtcNow, DateTimeKind.Utc) && x.BirthDate <= DateTime.SpecifyKind(toBirthDate ?? DateTime.UtcNow, DateTimeKind.Utc));
query = query.Where(x => x.BirthDate >= fromBirthDate && x.BirthDate <= toBirthDate);
}
if (fromEmploymentDate is not null && toEmploymentDate is not null)
{
query = query.Where(x => x.EmploymentDate >= DateTime.SpecifyKind(fromEmploymentDate ?? DateTime.UtcNow, DateTimeKind.Utc) && x.EmploymentDate <= DateTime.SpecifyKind(toEmploymentDate ?? DateTime.UtcNow, DateTimeKind.Utc));
query = query.Where(x => x.EmploymentDate >= fromEmploymentDate && x.EmploymentDate <= toEmploymentDate);
}
return [.. JoinPost(query).Select(x => _mapper.Map<EmployeeDataModel>(x))];
return [.. query.Select(x => _mapper.Map<EmployeeDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -71,7 +60,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -79,12 +68,12 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
return _mapper.Map<EmployeeDataModel>(AddPost(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)));
return _mapper.Map<EmployeeDataModel>(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -92,12 +81,12 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
return _mapper.Map<EmployeeDataModel>(AddPost(_dbContext.Employees.FirstOrDefault(x => x.Email == email && !x.IsDeleted)));
return _mapper.Map<EmployeeDataModel>(_dbContext.Employees.FirstOrDefault(x => x.Email == email));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -111,17 +100,12 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", employeeDataModel.Id, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "PK_Employees" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", employeeDataModel.Id, _localizer);
throw new ElementExistsException("Id", employeeDataModel.Id);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -129,7 +113,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
var element = GetEmployeeById(employeeDataModel.Id) ?? throw new ElementNotFoundException(employeeDataModel.Id, _localizer);
var element = GetEmployeeById(employeeDataModel.Id) ?? throw new ElementNotFoundException(employeeDataModel.Id);
_dbContext.Employees.Update(_mapper.Map(employeeDataModel, element));
_dbContext.SaveChanges();
}
@@ -141,7 +125,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -149,7 +133,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
var element = GetEmployeeById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetEmployeeById(id) ?? throw new ElementNotFoundException(id);
element.IsDeleted = true;
_dbContext.SaveChanges();
}
@@ -161,31 +145,9 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
public int GetEmployeeTrend(DateTime fromPeriod, DateTime toPeriod)
{
try
{
var countWorkersOnBegining = _dbContext.Employees.Count(x => x.EmploymentDate < fromPeriod && (!x.IsDeleted || x.DateOfDelete > fromPeriod));
var countWorkersOnEnding = _dbContext.Employees.Count(x => x.EmploymentDate < toPeriod && (!x.IsDeleted || x.DateOfDelete > toPeriod));
return countWorkersOnEnding - countWorkersOnBegining;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
private Employee? GetEmployeeById(string id) => AddPost(_dbContext.Employees.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
private IQueryable<Employee> JoinPost(IQueryable<Employee> query)
=> query.GroupJoin(_dbContext.Posts.Where(x => x.IsActual), x => x.PostId, y => y.PostId, (x, y) => new { Employee = x, Post = y })
.SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) => x.Employee.AddPost(y));
private Employee? AddPost(Employee? employee)
=> employee?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == employee.PostId && x.IsActual));
private Employee? GetEmployeeById(string id) => _dbContext.Employees.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
}

View File

@@ -1,23 +1,19 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
namespace SquirrelDatabase.Implementations;
internal class PostStorageContract : IPostStorageContract
public class PostStorageContract : IPostStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public PostStorageContract(SquirrelDbContext dbContext, IStringLocalizer<Messages> localizer)
public PostStorageContract(SquirrelDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
@@ -28,24 +24,26 @@ internal class PostStorageContract : IPostStorageContract
.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));
.ForMember(x => x.ChangeDate, x => x.MapFrom(src => DateTime.UtcNow));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<PostDataModel> GetList()
public List<PostDataModel> GetList(bool onlyActual = true)
{
try
{
return [.. _dbContext.Posts.Select(x => _mapper.Map<PostDataModel>(x))];
var query = _dbContext.Posts.AsQueryable();
if (onlyActual)
{
query = query.Where(x => x.IsActual);
}
return [.. query.Select(x => _mapper.Map<PostDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -58,7 +56,7 @@ internal class PostStorageContract : IPostStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -71,7 +69,7 @@ internal class PostStorageContract : IPostStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -84,7 +82,7 @@ internal class PostStorageContract : IPostStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -98,17 +96,17 @@ internal class PostStorageContract : IPostStorageContract
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
throw new ElementExistsException("PostName", postDataModel.PostName);
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostId_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
throw new ElementExistsException("PostId", postDataModel.Id);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -119,7 +117,7 @@ internal class PostStorageContract : IPostStorageContract
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetPostById(postDataModel.Id) ?? throw new ElementNotFoundException(postDataModel.Id, _localizer);
var element = GetPostById(postDataModel.Id) ?? throw new ElementNotFoundException(postDataModel.Id);
if (!element.IsActual)
{
throw new ElementDeletedException(postDataModel.Id);
@@ -140,7 +138,7 @@ internal class PostStorageContract : IPostStorageContract
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Posts_PostName_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName", postDataModel.PostName, _localizer);
throw new ElementExistsException("PostName", postDataModel.PostName);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
@@ -150,7 +148,7 @@ internal class PostStorageContract : IPostStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -158,7 +156,7 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetPostById(id) ?? throw new ElementNotFoundException(id);
if (!element.IsActual)
{
throw new ElementDeletedException(id);
@@ -177,7 +175,7 @@ internal class PostStorageContract : IPostStorageContract
{
try
{
var element = GetPostById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetPostById(id) ?? throw new ElementNotFoundException(id);
element.IsActual = true;
_dbContext.SaveChanges();
}

View File

@@ -1,70 +1,43 @@
using AutoMapper;
using BarBelochkaContract.DataModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
namespace SquirrelDatabase.Implementations;
internal class SalaryStorageContract : ISalaryStorageContract
public class SalaryStorageContract : ISalaryStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public SalaryStorageContract(SquirrelDbContext dbContext, IStringLocalizer<Messages> localizer)
public SalaryStorageContract(SquirrelDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Employee, EmployeeDataModel>();
cfg.CreateMap<Salary, SalaryDataModel>();
cfg.CreateMap<SalaryDataModel, Salary>()
.ForMember(dest => dest.EmployeeSalary, opt => opt.MapFrom(src => src.Salary));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<SalaryDataModel> GetList(DateTime? startDate, DateTime? endDate, string? employeeId = null)
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? employeeId = null)
{
try
{
var query = _dbContext.Salaries.Include(d => d.Employee).AsQueryable();
if (startDate.HasValue)
query = query.Where(x => x.SalaryDate >= DateTime.SpecifyKind(startDate ?? DateTime.UtcNow, DateTimeKind.Utc));
if (endDate.HasValue)
query = query.Where(x => x.SalaryDate <= DateTime.SpecifyKind(endDate ?? DateTime.UtcNow, DateTimeKind.Utc));
if (employeeId != null)
var query = _dbContext.Salaries.Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate);
if (employeeId is not null)
{
query = query.Where(x => x.EmployeeId == employeeId);
}
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public async Task<List<SalaryDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
{
try
{
return [.. await _dbContext.Salaries.Include(x =>
x.Employee).Where(x => x.SalaryDate >= DateTime.SpecifyKind(startDate, DateTimeKind.Utc) &&
x.SalaryDate <= DateTime.SpecifyKind(endDate, DateTimeKind.Utc))
.Select(x => _mapper.Map<SalaryDataModel>(x)).ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -78,7 +51,7 @@ internal class SalaryStorageContract : ISalaryStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
}

View File

@@ -1,92 +1,59 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using SquirrelContract.DataModels;
using SquirrelContract.Exceptions;
using SquirrelContract.Resources;
using SquirrelContract.StoragesContracts;
using SquirrelDatabase.Models;
namespace SquirrelDatabase.Implementations;
internal class SaleStorageContract : ISaleStorageContract
public class SaleStorageContract : ISaleStorageContract
{
private readonly SquirrelDbContext _dbContext;
private readonly Mapper _mapper;
private readonly IStringLocalizer<Messages> _localizer;
public SaleStorageContract(SquirrelDbContext dbContext, IStringLocalizer<Messages> localizer)
public SaleStorageContract(SquirrelDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Client, ClientDataModel>();
cfg.CreateMap<Cocktail, CocktailDataModel>();
cfg.CreateMap<Employee, EmployeeDataModel>();
{
cfg.CreateMap<SaleCocktail, SaleCocktailDataModel>();
cfg.CreateMap<SaleCocktailDataModel, SaleCocktail>()
.ForMember(x => x.Cocktail, x => x.Ignore());
cfg.CreateMap<SaleCocktailDataModel, SaleCocktail>();
cfg.CreateMap<Sale, SaleDataModel>();
cfg.CreateMap<SaleDataModel, Sale>()
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
.ForMember(x => x.SaleCocktails, x => x.MapFrom(src => src.Cocktails))
.ForMember(x => x.Employee, x => x.Ignore())
.ForMember(x => x.Client, x => x.Ignore());
.ForMember(x => x.SaleCocktails, x => x.MapFrom(src => src.Cocktails));
});
_mapper = new Mapper(config);
_localizer = localizer;
}
public List<SaleDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? employeeId = null, string? clientId = null, string? cocktailId = null)
{
try
{
var query = _dbContext.Sales
.Include(r => r.Employee)
.Include(r => r.Client)
.Include(r => r.SaleCocktails)!
.ThenInclude(d => d.Cocktail)
.AsQueryable();
if (startDate.HasValue)
query = query.Where(x => x.SaleDate >= DateTime.SpecifyKind(startDate ?? DateTime.UtcNow, DateTimeKind.Utc));
if (endDate.HasValue)
query = query.Where(x => x.SaleDate <= DateTime.SpecifyKind(endDate ?? DateTime.UtcNow, DateTimeKind.Utc));
if (employeeId != null)
var query = _dbContext.Sales.Include(x => x.SaleCocktails).AsQueryable();
if (startDate is not null && endDate is not null)
{
query = query.Where(x => x.SaleDate >= startDate && x.SaleDate < endDate);
}
if (employeeId is not null)
{
query = query.Where(x => x.EmployeeId == employeeId);
if (clientId != null)
}
if (clientId is not null)
{
query = query.Where(x => x.ClientId == clientId);
if (cocktailId != null)
}
if (cocktailId is not null)
{
query = query.Where(x => x.SaleCocktails!.Any(y => y.CocktailId == cocktailId));
var s = query.ToList();
}
return [.. query.Select(x => _mapper.Map<SaleDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public async Task<List<SaleDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
{
try
{
return [.. await _dbContext.Sales
.Include(x => x.Employee)
.Include(x => x.Client)
.Include(x => x.SaleCocktails)!
.ThenInclude(sc => sc.Cocktail)
.Where(x => x.SaleDate >= DateTime.SpecifyKind(startDate, DateTimeKind.Utc)
&& x.SaleDate < DateTime.SpecifyKind(endDate, DateTimeKind.Utc))
.Select(x => _mapper.Map<SaleDataModel>(x))
.ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -99,7 +66,7 @@ internal class SaleStorageContract : ISaleStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -113,7 +80,7 @@ internal class SaleStorageContract : ISaleStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
@@ -121,7 +88,7 @@ internal class SaleStorageContract : ISaleStorageContract
{
try
{
var element = GetSaleById(id) ?? throw new ElementNotFoundException(id, _localizer);
var element = GetSaleById(id) ?? throw new ElementNotFoundException(id);
if (element.IsCancel)
{
throw new ElementDeletedException(id);
@@ -137,9 +104,9 @@ internal class SaleStorageContract : ISaleStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
throw new StorageException(ex);
}
}
private Sale? GetSaleById(string id) => _dbContext.Sales.Include(x => x.Client).Include(x => x.Employee).Include(x => x.SaleCocktails)!.ThenInclude(x => x.Cocktail).FirstOrDefault(x => x.Id == id);
private Sale? GetSaleById(string id) => _dbContext.Sales.FirstOrDefault(x => x.Id == id);
}

View File

@@ -1,330 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SquirrelDatabase;
#nullable disable
namespace SquirrelDatabase.Migrations
{
[DbContext(typeof(SquirrelDbContext))]
[Migration("20250407181533_FirstMigration")]
partial class FirstMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<double>("DiscountSize")
.HasColumnType("double precision");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("BaseAlcohol")
.HasColumnType("integer");
b.Property<string>("CocktailName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailName")
.IsUnique();
b.ToTable("Cocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("CocktailId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailId");
b.ToTable("CocktailHistories");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("EmploymentDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Employees");
});
modelBuilder.Entity("SquirrelDatabase.Models.Post", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<bool>("IsActual")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PostName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PostType")
.HasColumnType("integer");
b.Property<double>("Salary")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("PostId", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.HasIndex("PostName", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.ToTable("Posts");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("EmployeeSalary")
.HasColumnType("double precision");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<double>("Discount")
.HasColumnType("double precision");
b.Property<int>("DiscountType")
.HasColumnType("integer");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("SaleDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EmployeeId");
b.ToTable("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.Property<string>("SaleId")
.HasColumnType("text");
b.Property<string>("CocktailId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("SaleId", "CocktailId");
b.HasIndex("CocktailId");
b.ToTable("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("CocktailHistories")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Salaries")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.HasOne("SquirrelDatabase.Models.Client", "Client")
.WithMany("Sales")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Sales")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("SaleCocktails")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SquirrelDatabase.Models.Sale", "Sale")
.WithMany("SaleCocktails")
.HasForeignKey("SaleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
b.Navigation("Sale");
});
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Navigation("CocktailHistories");
b.Navigation("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Navigation("Salaries");
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Navigation("SaleCocktails");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,252 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SquirrelDatabase.Migrations
{
/// <inheritdoc />
public partial class FirstMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
FIO = table.Column<string>(type: "text", nullable: false),
PhoneNumber = table.Column<string>(type: "text", nullable: false),
DiscountSize = table.Column<double>(type: "double precision", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Cocktails",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
CocktailName = table.Column<string>(type: "text", nullable: false),
Price = table.Column<double>(type: "double precision", nullable: false),
BaseAlcohol = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Cocktails", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Employees",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
FIO = table.Column<string>(type: "text", nullable: false),
Email = table.Column<string>(type: "text", nullable: false),
PostId = table.Column<string>(type: "text", nullable: false),
BirthDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
EmploymentDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Employees", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Posts",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
PostId = table.Column<string>(type: "text", nullable: false),
PostName = table.Column<string>(type: "text", nullable: false),
PostType = table.Column<int>(type: "integer", nullable: false),
Salary = table.Column<double>(type: "double precision", nullable: false),
IsActual = table.Column<bool>(type: "boolean", nullable: false),
ChangeDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Posts", x => x.Id);
});
migrationBuilder.CreateTable(
name: "CocktailHistories",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
CocktailId = table.Column<string>(type: "text", nullable: false),
OldPrice = table.Column<double>(type: "double precision", nullable: false),
ChangeDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CocktailHistories", x => x.Id);
table.ForeignKey(
name: "FK_CocktailHistories_Cocktails_CocktailId",
column: x => x.CocktailId,
principalTable: "Cocktails",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Salaries",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
EmployeeId = table.Column<string>(type: "text", nullable: false),
SalaryDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
EmployeeSalary = table.Column<double>(type: "double precision", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Salaries", x => x.Id);
table.ForeignKey(
name: "FK_Salaries_Employees_EmployeeId",
column: x => x.EmployeeId,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Sales",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
EmployeeId = table.Column<string>(type: "text", nullable: false),
ClientId = table.Column<string>(type: "text", nullable: true),
SaleDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
Sum = table.Column<double>(type: "double precision", nullable: false),
DiscountType = table.Column<int>(type: "integer", nullable: false),
Discount = table.Column<double>(type: "double precision", nullable: false),
IsCancel = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Sales", x => x.Id);
table.ForeignKey(
name: "FK_Sales_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_Sales_Employees_EmployeeId",
column: x => x.EmployeeId,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SaleCocktails",
columns: table => new
{
SaleId = table.Column<string>(type: "text", nullable: false),
CocktailId = table.Column<string>(type: "text", nullable: false),
Count = table.Column<int>(type: "integer", nullable: false),
Price = table.Column<double>(type: "double precision", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SaleCocktails", x => new { x.SaleId, x.CocktailId });
table.ForeignKey(
name: "FK_SaleCocktails_Cocktails_CocktailId",
column: x => x.CocktailId,
principalTable: "Cocktails",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_SaleCocktails_Sales_SaleId",
column: x => x.SaleId,
principalTable: "Sales",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Clients_PhoneNumber",
table: "Clients",
column: "PhoneNumber",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_CocktailHistories_CocktailId",
table: "CocktailHistories",
column: "CocktailId");
migrationBuilder.CreateIndex(
name: "IX_Cocktails_CocktailName",
table: "Cocktails",
column: "CocktailName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Posts_PostId_IsActual",
table: "Posts",
columns: new[] { "PostId", "IsActual" },
unique: true,
filter: "\"IsActual\" = TRUE");
migrationBuilder.CreateIndex(
name: "IX_Posts_PostName_IsActual",
table: "Posts",
columns: new[] { "PostName", "IsActual" },
unique: true,
filter: "\"IsActual\" = TRUE");
migrationBuilder.CreateIndex(
name: "IX_Salaries_EmployeeId",
table: "Salaries",
column: "EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_SaleCocktails_CocktailId",
table: "SaleCocktails",
column: "CocktailId");
migrationBuilder.CreateIndex(
name: "IX_Sales_ClientId",
table: "Sales",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Sales_EmployeeId",
table: "Sales",
column: "EmployeeId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "CocktailHistories");
migrationBuilder.DropTable(
name: "Posts");
migrationBuilder.DropTable(
name: "Salaries");
migrationBuilder.DropTable(
name: "SaleCocktails");
migrationBuilder.DropTable(
name: "Cocktails");
migrationBuilder.DropTable(
name: "Sales");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Employees");
}
}
}

View File

@@ -1,331 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SquirrelDatabase;
#nullable disable
namespace SquirrelDatabase.Migrations
{
[DbContext(typeof(SquirrelDbContext))]
[Migration("20250407203820_ChangeFieldsInPost")]
partial class ChangeFieldsInPost
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<double>("DiscountSize")
.HasColumnType("double precision");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("BaseAlcohol")
.HasColumnType("integer");
b.Property<string>("CocktailName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailName")
.IsUnique();
b.ToTable("Cocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("CocktailId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailId");
b.ToTable("CocktailHistories");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("EmploymentDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Employees");
});
modelBuilder.Entity("SquirrelDatabase.Models.Post", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Configuration")
.IsRequired()
.HasColumnType("jsonb");
b.Property<bool>("IsActual")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PostName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PostType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PostId", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.HasIndex("PostName", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.ToTable("Posts");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("EmployeeSalary")
.HasColumnType("double precision");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<double>("Discount")
.HasColumnType("double precision");
b.Property<int>("DiscountType")
.HasColumnType("integer");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("SaleDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EmployeeId");
b.ToTable("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.Property<string>("SaleId")
.HasColumnType("text");
b.Property<string>("CocktailId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("SaleId", "CocktailId");
b.HasIndex("CocktailId");
b.ToTable("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("CocktailHistories")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Salaries")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.HasOne("SquirrelDatabase.Models.Client", "Client")
.WithMany("Sales")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Sales")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("SaleCocktails")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SquirrelDatabase.Models.Sale", "Sale")
.WithMany("SaleCocktails")
.HasForeignKey("SaleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
b.Navigation("Sale");
});
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Navigation("CocktailHistories");
b.Navigation("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Navigation("Salaries");
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Navigation("SaleCocktails");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,40 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SquirrelDatabase.Migrations
{
/// <inheritdoc />
public partial class ChangeFieldsInPost : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Salary",
table: "Posts");
migrationBuilder.AddColumn<string>(
name: "Configuration",
table: "Posts",
type: "jsonb",
nullable: false,
defaultValue: "{\"Rate\": 0, \"Type\": \"PostConfiguration\"}");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Configuration",
table: "Posts");
migrationBuilder.AddColumn<double>(
name: "Salary",
table: "Posts",
type: "double precision",
nullable: false,
defaultValue: 0.0);
}
}
}

View File

@@ -1,334 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SquirrelDatabase;
#nullable disable
namespace SquirrelDatabase.Migrations
{
[DbContext(typeof(SquirrelDbContext))]
[Migration("20250408214441_ChangeEmployee")]
partial class ChangeEmployee
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<double>("DiscountSize")
.HasColumnType("double precision");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("BaseAlcohol")
.HasColumnType("integer");
b.Property<string>("CocktailName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailName")
.IsUnique();
b.ToTable("Cocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("CocktailId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailId");
b.ToTable("CocktailHistories");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<DateTime?>("DateOfDelete")
.HasColumnType("timestamp without time zone");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("EmploymentDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Employees");
});
modelBuilder.Entity("SquirrelDatabase.Models.Post", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Configuration")
.IsRequired()
.HasColumnType("jsonb");
b.Property<bool>("IsActual")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PostName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PostType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PostId", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.HasIndex("PostName", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.ToTable("Posts");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("EmployeeSalary")
.HasColumnType("double precision");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<double>("Discount")
.HasColumnType("double precision");
b.Property<int>("DiscountType")
.HasColumnType("integer");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("SaleDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EmployeeId");
b.ToTable("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.Property<string>("SaleId")
.HasColumnType("text");
b.Property<string>("CocktailId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("SaleId", "CocktailId");
b.HasIndex("CocktailId");
b.ToTable("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("CocktailHistories")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Salaries")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.HasOne("SquirrelDatabase.Models.Client", "Client")
.WithMany("Sales")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Sales")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("SaleCocktails")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SquirrelDatabase.Models.Sale", "Sale")
.WithMany("SaleCocktails")
.HasForeignKey("SaleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
b.Navigation("Sale");
});
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Navigation("CocktailHistories");
b.Navigation("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Navigation("Salaries");
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Navigation("SaleCocktails");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -1,29 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SquirrelDatabase.Migrations
{
/// <inheritdoc />
public partial class ChangeEmployee : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "DateOfDelete",
table: "Employees",
type: "timestamp without time zone",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DateOfDelete",
table: "Employees");
}
}
}

View File

@@ -1,331 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SquirrelDatabase;
#nullable disable
namespace SquirrelDatabase.Migrations
{
[DbContext(typeof(SquirrelDbContext))]
partial class SquirrelDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<double>("DiscountSize")
.HasColumnType("double precision");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("PhoneNumber")
.IsUnique();
b.ToTable("Clients");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("BaseAlcohol")
.HasColumnType("integer");
b.Property<string>("CocktailName")
.IsRequired()
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailName")
.IsUnique();
b.ToTable("Cocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("CocktailId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("CocktailId");
b.ToTable("CocktailHistories");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<DateTime?>("DateOfDelete")
.HasColumnType("timestamp without time zone");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("EmploymentDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Employees");
});
modelBuilder.Entity("SquirrelDatabase.Models.Post", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Configuration")
.IsRequired()
.HasColumnType("jsonb");
b.Property<bool>("IsActual")
.HasColumnType("boolean");
b.Property<string>("PostId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PostName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PostType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("PostId", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.HasIndex("PostName", "IsActual")
.IsUnique()
.HasFilter("\"IsActual\" = TRUE");
b.ToTable("Posts");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("EmployeeSalary")
.HasColumnType("double precision");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.HasKey("Id");
b.HasIndex("EmployeeId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ClientId")
.HasColumnType("text");
b.Property<double>("Discount")
.HasColumnType("double precision");
b.Property<int>("DiscountType")
.HasColumnType("integer");
b.Property<string>("EmployeeId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("SaleDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EmployeeId");
b.ToTable("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.Property<string>("SaleId")
.HasColumnType("text");
b.Property<string>("CocktailId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("SaleId", "CocktailId");
b.HasIndex("CocktailId");
b.ToTable("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.CocktailHistory", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("CocktailHistories")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
});
modelBuilder.Entity("SquirrelDatabase.Models.Salary", b =>
{
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Salaries")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.HasOne("SquirrelDatabase.Models.Client", "Client")
.WithMany("Sales")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("SquirrelDatabase.Models.Employee", "Employee")
.WithMany("Sales")
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Employee");
});
modelBuilder.Entity("SquirrelDatabase.Models.SaleCocktail", b =>
{
b.HasOne("SquirrelDatabase.Models.Cocktail", "Cocktail")
.WithMany("SaleCocktails")
.HasForeignKey("CocktailId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SquirrelDatabase.Models.Sale", "Sale")
.WithMany("SaleCocktails")
.HasForeignKey("SaleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Cocktail");
b.Navigation("Sale");
});
modelBuilder.Entity("SquirrelDatabase.Models.Client", b =>
{
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Cocktail", b =>
{
b.Navigation("CocktailHistories");
b.Navigation("SaleCocktails");
});
modelBuilder.Entity("SquirrelDatabase.Models.Employee", b =>
{
b.Navigation("Salaries");
b.Navigation("Sales");
});
modelBuilder.Entity("SquirrelDatabase.Models.Sale", b =>
{
b.Navigation("SaleCocktails");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -13,7 +13,7 @@ public class Employee
public string Email { get; set; }
public required string PostId { get; set; }
public string PostId { get; set; }
public DateTime BirthDate { get; set; }
@@ -21,20 +21,9 @@ public class Employee
public bool IsDeleted { get; set; }
public DateTime? DateOfDelete { get; set; }
[NotMapped]
public Post? Post { get; set; }
[ForeignKey("EmployeeId")]
public List<Salary>? Salaries { get; set; }
[ForeignKey("EmployeeId")]
public List<Sale>? Sales { get; set; }
public Employee AddPost(Post? post)
{
Post = post;
return this;
}
}

View File

@@ -1,7 +1,6 @@
using AutoMapper;
using SquirrelContract.DataModels;
using SquirrelContract.Enums;
using SquirrelContract.Infastructure.PostConfigurations;
namespace SquirrelDatabase.Models;
@@ -15,7 +14,7 @@ public class Post
public PostType PostType { get; set; }
public required PostConfiguration Configuration { get; set; }
public double Salary { get; set; }
public bool IsActual { get; set; }

Some files were not shown because too many files have changed in this diff Show More