12 Commits

Author SHA1 Message Date
75e352ce26 лаба 8 готова 2025-05-21 20:37:22 +04:00
ef4d6f8248 допил 7 2025-04-24 10:28:47 +04:00
f35736a424 5 тестов доделать 2025-04-24 04:22:23 +04:00
7aee0da4ed dates + strings 2025-04-24 00:06:05 +04:00
3736a923c7 nums 2025-04-23 17:18:48 +04:00
29d974f2c1 all done lab_6 2025-04-22 23:47:23 +04:00
04966ef9e5 excel done 2025-04-22 22:26:05 +04:00
eff45b4815 изменил всё под историчность сущности 2025-04-22 18:33:27 +04:00
9968b6d69e переделать под software history, 39min 2025-04-22 00:40:03 +04:00
b1a49bfde3 calculate salaryyy 2025-04-18 00:57:59 +04:00
9f03eaa09e changes in worker 2025-04-17 22:57:21 +04:00
1b8b1a06f8 first migration 2025-04-17 18:07:41 +04:00
141 changed files with 7331 additions and 1431 deletions

View File

@@ -5,15 +5,17 @@ using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using System.Text.Json;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class ManufacturerBusinessLogicContract(IManufacturerStorageContract
manufacturerStorageContract, ILogger logger) : IManufacturerBusinessLogicContract
manufacturerStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IManufacturerBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IManufacturerStorageContract _manufacturerStorageContract
= manufacturerStorageContract;
private readonly IManufacturerStorageContract _manufacturerStorageContract = manufacturerStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<ManufacturerDataModel> GetAllManufacturers()
{
_logger.LogInformation("GetAllManufacturers");
@@ -30,18 +32,18 @@ manufacturerStorageContract, ILogger logger) : IManufacturerBusinessLogicContrac
if (data.IsGuid())
{
return _manufacturerStorageContract.GetElementById(data) ??
throw new ElementNotFoundException(data);
throw new ElementNotFoundException(data, _localizer);
}
return _manufacturerStorageContract.GetElementByName(data) ??
_manufacturerStorageContract.GetElementByOldName(data) ??
throw new ElementNotFoundException(data);
throw new ElementNotFoundException(data, _localizer);
}
public void InsertManufacturer(ManufacturerDataModel manufacturerDataModel)
{
_logger.LogInformation("New data: {json}",
JsonSerializer.Serialize(manufacturerDataModel));
ArgumentNullException.ThrowIfNull(manufacturerDataModel);
manufacturerDataModel.Validate();
manufacturerDataModel.Validate(_localizer);
_manufacturerStorageContract.AddElement(manufacturerDataModel);
}
public void UpdateManufacturer(ManufacturerDataModel manufacturerDataModel)
@@ -49,7 +51,7 @@ manufacturerStorageContract, ILogger logger) : IManufacturerBusinessLogicContrac
_logger.LogInformation("Update data: {json}",
JsonSerializer.Serialize(manufacturerDataModel));
ArgumentNullException.ThrowIfNull(manufacturerDataModel);
manufacturerDataModel.Validate();
manufacturerDataModel.Validate(_localizer);
_manufacturerStorageContract.UpdElement(manufacturerDataModel);
}
public void DeleteManufacturer(string id)
@@ -61,7 +63,7 @@ manufacturerStorageContract, ILogger logger) : IManufacturerBusinessLogicContrac
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_manufacturerStorageContract.DelElement(id);
}

View File

@@ -1,9 +1,11 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using System;
using System.Collections.Generic;
@@ -15,11 +17,12 @@ using System.Threading.Tasks;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class PostBusinessLogicContract(IPostStorageContract
postStorageContract, ILogger logger) : IPostBusinessLogicContract
postStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IPostBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IPostStorageContract _postStorageContract =
postStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<PostDataModel> GetAllPosts()
{
_logger.LogInformation("GetAllPosts");
@@ -34,7 +37,7 @@ postStorageContract, ILogger logger) : IPostBusinessLogicContract
}
if (!postId.IsGuid())
{
throw new ValidationException("The value in the field postId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "PostId"));
}
return _postStorageContract.GetPostWithHistory(postId) ?? throw new
NullListException();
@@ -49,17 +52,17 @@ postStorageContract, ILogger logger) : IPostBusinessLogicContract
if (data.IsGuid())
{
return _postStorageContract.GetElementById(data) ?? throw new
ElementNotFoundException(data);
ElementNotFoundException(data, _localizer);
}
return _postStorageContract.GetElementByName(data) ?? throw new
ElementNotFoundException(data);
ElementNotFoundException(data, _localizer);
}
public void InsertPost(PostDataModel postDataModel)
{
_logger.LogInformation("New data: {json}",
JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate();
postDataModel.Validate(_localizer);
_postStorageContract.AddElement(postDataModel);
}
public void UpdatePost(PostDataModel postDataModel)
@@ -67,7 +70,7 @@ postStorageContract, ILogger logger) : IPostBusinessLogicContract
_logger.LogInformation("Update data: {json}",
JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate();
postDataModel.Validate(_localizer);
_postStorageContract.UpdElement(postDataModel);
}
public void DeletePost(string id)
@@ -79,7 +82,7 @@ postStorageContract, ILogger logger) : IPostBusinessLogicContract
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_postStorageContract.DelElement(id);
}
@@ -91,8 +94,8 @@ postStorageContract, ILogger logger) : IPostBusinessLogicContract
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
{
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_postStorageContract.ResElement(id);
}

View File

@@ -0,0 +1,172 @@
using DocumentFormat.OpenXml.Wordprocessing;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareBusinessLogic.OfficePackage;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class ReportContract : IReportContract
{
private readonly ISoftwareStorageContract _softwareStorageContract;
private readonly IRequestStorageContract _requestStorageContract;
private readonly ISalaryStorageContract _salaryStorageContract;
private readonly BaseWordBuilder _baseWordBuilder;
private readonly BaseExcelBuilder _baseExcelBuilder;
private readonly BasePdfBuilder _basePdfBuilder;
private readonly IStringLocalizer<Messages> _localizer ;
private readonly ILogger _logger;
internal readonly string[] tableHeader;
internal readonly string[] documentHeader;
public ReportContract(ISoftwareStorageContract softwareStorageContract,
IRequestStorageContract requestStorageContract,
ISalaryStorageContract salaryStorageContract,
BaseWordBuilder baseWordBuilder,
BaseExcelBuilder baseExcelBuilder,
BasePdfBuilder basePdfBuilder, IStringLocalizer<Messages> localizer, ILogger logger)
{
_softwareStorageContract = softwareStorageContract;
_requestStorageContract = requestStorageContract;
_salaryStorageContract = salaryStorageContract;
_baseWordBuilder = baseWordBuilder;
_baseExcelBuilder = baseExcelBuilder;
_basePdfBuilder = basePdfBuilder;
_localizer = localizer;
_logger = logger;
tableHeader = [_localizer["DocumentExcelCaptionDate"], _localizer["DocumentExcelCaptionSum"], _localizer["DocumentExcelCaptionSoftware"], _localizer["DocumentExcelCaptionCount"]];
documentHeader = [_localizer["DocumentDocCaptionSoftware"], _localizer["DocumentDocCaptionOldPrice"], _localizer["DocumentDocCaptionData"]];
}
public Task<List<HistoryOfSoftwareDataModel>> GetDataSoftwaresByHistoryAsync(CancellationToken ct)
{
_logger.LogInformation("Get data SoftwaresByManufacturer");
return GetDataBySoftwaresAsync(ct);
}
private async Task<List<HistoryOfSoftwareDataModel>> GetDataBySoftwaresAsync(CancellationToken ct)
=> [.. (await _softwareStorageContract.GetListAsync(ct)).GroupBy(x => x.SoftwareName).Select(x => new HistoryOfSoftwareDataModel {
SoftwareName = x.Key, Histories = [.. x.Select(y => y.OldPrice.ToString())], Data = [.. x.Select(y => y.ChangeDate.ToString())] })];
public async Task<Stream> CreateDocumentSoftwaresByHistoryAsync(CancellationToken ct)
{
_logger.LogInformation("Create report HistoryBySoftware");
var data = await GetDataBySoftwaresAsync(ct) ?? throw new InvalidOperationException("No found data");
var tableData = new List<string[]>
{
documentHeader
};
foreach (var software in data)
{
tableData.Add(new string[] { software.SoftwareName, "", "" });
var pairs = software.Histories.Zip(software.Data,
(price, date) => new string[] { "", price, date });
tableData.AddRange(pairs);
}
return _baseWordBuilder
.AddHeader(_localizer["DocumentDocHeader"])
.AddParagraph(string.Format(_localizer["DocumentDocSubHeader"], DateTime.Now))
.AddTable(
widths: new[] { 3000, 3000, 3000 },
data: tableData
)
.Build();
}
public Task<List<RequestDataModel>> GetDataRequestByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Get data RequestsByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
return GetDataByRequestsAsync(dateStart, dateFinish, ct);
}
private async Task<List<RequestDataModel>> GetDataByRequestsAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
if (dateStart.IsDateNotOlder(dateFinish))
{
throw new IncorrectDatesException(dateStart, dateFinish, _localizer);
}
return [.. (await _requestStorageContract.GetListAsync(dateStart, dateFinish, ct)).OrderBy(x => x.RequestDate)];
}
public async Task<Stream> CreateDocumentRequestsByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Create report RequestsByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
var data = await GetDataByRequestsAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
var tableHeader = new string[] { "Дата", "Email", "Сумма", "ПО", "Количество" };
return _baseExcelBuilder
.AddHeader(_localizer["DocumentExcelHeader"], 0, 5)
.AddParagraph($"c {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
.AddTable(
[10, 10, 10, 10, 10],
[.. new List<string[]>() { tableHeader }
.Union(data.SelectMany(x =>
(new List<string[]>() {
new string[] {
x.RequestDate.ToShortDateString(),
x.Email,
x.Sum.ToString("N2"),
"",
""
}
})
.Union(x.Softwares!.Select(y => new string[] {
"",
"",
"",
y.SoftwareName,
y.Count.ToString("N2")
}))
.ToArray()
)
.Union([[
_localizer["DocumentExcelCaptionTotal"],
"",
data.Sum(x => x.Sum).ToString("N2"),
"",
""
]]))
])
.Build();
}
public Task<List<WorkerSalaryByPeriodDataModel>> 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<WorkerSalaryByPeriodDataModel>> 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.WorkerFIO).Select(x => new
WorkerSalaryByPeriodDataModel { WorkerFIO = x.Key, TotalSalary = x.Sum(y => y.Salary),
FromPeriod = x.Min(y => y.SalaryDate), ToPeriod = x.Max(y => y.SalaryDate) }).OrderBy(x => x.WorkerFIO)];
}
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("No found data");
return _basePdfBuilder
.AddHeader(_localizer["DocumentPdfHeader"])
.AddParagraph(string.Format(_localizer["DocumentPdfSubHeader"], dateStart.ToLocalTime().ToShortDateString(), dateFinish.ToLocalTime().ToShortDateString()))
.AddPieChart(_localizer["DocumentPdfDiagramCaption"], [.. data.Select(x => (x.WorkerFIO, x.TotalSalary))]).Build();
}
}

View File

@@ -1,8 +1,10 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using System;
using System.Collections.Generic;
@@ -13,17 +15,18 @@ using System.Threading.Tasks;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class RequestBusinessLogicContract(IRequestStorageContract requestStorageContract, ILogger logger) : IRequestBusinessLogicContract
internal class RequestBusinessLogicContract(IRequestStorageContract requestStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IRequestBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IRequestStorageContract _requestStorageContract =
requestStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<RequestDataModel> GetAllRequestsByPeriod(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllRequests params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
return _requestStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
@@ -33,7 +36,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
_logger.LogInformation("GetAllRequests params: {workerId}, {fromDate}, { toDate} ", workerId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
if (workerId.IsEmpty())
{
@@ -41,7 +44,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
}
if (!workerId.IsGuid())
{
throw new ValidationException("The value in the field workerId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "WorkerId"));
}
return _requestStorageContract.GetList(fromDate, toDate, workerId:
workerId) ?? throw new NullListException();
@@ -52,7 +55,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
_logger.LogInformation("GetAllRequests params: {softwareId}, {fromDate}, { toDate} ", softwareId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
if (softwareId.IsEmpty())
{
@@ -60,7 +63,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
}
if (!softwareId.IsGuid())
{
throw new ValidationException("The value in the field softwareId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SoftwareId"));
}
return _requestStorageContract.GetList(fromDate, toDate, softwareId:
softwareId) ?? throw new NullListException();
@@ -75,9 +78,9 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
}
if (!data.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
return _requestStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
return _requestStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data, _localizer);
}
public void InsertRequest(RequestDataModel requestDataModel)
@@ -85,7 +88,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
_logger.LogInformation("New data: {json}",
JsonSerializer.Serialize(requestDataModel));
ArgumentNullException.ThrowIfNull(requestDataModel);
requestDataModel.Validate();
requestDataModel.Validate(_localizer);
_requestStorageContract.AddElement(requestDataModel);
}
@@ -98,7 +101,7 @@ internal class RequestBusinessLogicContract(IRequestStorageContract requestStora
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_requestStorageContract.DelElement(id);

View File

@@ -1,25 +1,28 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract,
IRequestStorageContract requestStorageContract, IPostStorageContract postStorageContract,
IWorkerStorageContract workerStorageContract, ILogger logger) : ISalaryBusinessLogicContract
IWorkerStorageContract workerStorageContract, IStringLocalizer<Messages> localizer, ILogger logger, IConfigurationSalary сonfiguration) : ISalaryBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISalaryStorageContract _salaryStorageContract =
salaryStorageContract;
private readonly IRequestStorageContract _requestStorageContract =
requestStorageContract;
private readonly IPostStorageContract _postStorageContract =
postStorageContract;
private readonly IWorkerStorageContract _workerStorageContract =
workerStorageContract;
private readonly ISalaryStorageContract _salaryStorageContract = salaryStorageContract;
private readonly IRequestStorageContract _requestStorageContract = requestStorageContract;
private readonly IPostStorageContract _postStorageContract = postStorageContract;
private readonly IWorkerStorageContract _workerStorageContract = workerStorageContract;
private readonly IConfigurationSalary _salaryConfiguration = сonfiguration;
private readonly Lock _lockObject = new();
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate,
DateTime toDate)
{
@@ -27,17 +30,24 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
return _salaryStorageContract.GetList(fromDate, toDate) ?? throw new
NullListException();
var result = _salaryStorageContract.GetList(fromDate, toDate);
if (result == null)
{
throw new NullListException();
}
return result;
}
public List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime
fromDate, DateTime toDate, string workerId)
{
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
if (workerId.IsEmpty())
{
@@ -45,7 +55,7 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
}
if (!workerId.IsGuid())
{
throw new ValidationException("The value in the field workerId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "WorkerId"));
}
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}, { workerId} ", fromDate, toDate, workerId);
return _salaryStorageContract.GetList(fromDate, toDate, workerId) ??
@@ -61,14 +71,84 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
var workers = _workerStorageContract.GetList() ?? throw new NullListException();
foreach (var worker in workers)
{
var requests = _requestStorageContract.GetList(startDate, finishDate, workerId: worker.Id)?.Sum(x => x.Sum) ??
throw new NullListException();
var requests = _requestStorageContract.GetList(startDate, finishDate, workerId: worker.Id) ?? throw new NullListException();
var post = _postStorageContract.GetElementById(worker.PostId) ??
throw new NullListException();
var salary = post.Salary + requests * 0.1;
var salary = worker.ConfigurationModel switch
{
null => 0,
CashierPostConfiguration cpc => CalculateSalaryForCashier(requests, startDate, finishDate, cpc),
SupervisorPostConfiguration spc => CalculateSalaryForSupervisor(startDate, finishDate, spc),
PostConfiguration pc => pc.Rate,
};
_logger.LogDebug("The employee {workerId} was paid a salary of {salary}", worker.Id, salary);
_salaryStorageContract.AddElement(new SalaryDataModel(worker.Id, finishDate, salary));
}
}
private double CalculateSalaryForCashier(List<RequestDataModel> requests, DateTime startDate, DateTime finishDate, CashierPostConfiguration config)
{
var parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = _salaryConfiguration.MaxConcurrentThreads
};
double calcPercent = 0.0;
var dates = new List<DateTime>();
for (var date = startDate; date < finishDate; date = date.AddDays(1))
{
dates.Add(date);
}
Parallel.ForEach(dates, parallelOptions, date =>
{
var requestsInDay = requests.Where(x => x.RequestDate >= date && x.RequestDate < date.AddDays(1)).ToArray();
if (requestsInDay.Length > 0)
{
double dailySum = requestsInDay.Sum(x => x.Sum);
double dailyAverage = dailySum / requestsInDay.Length;
double dailyPercent = dailyAverage * config.SalePercent;
lock (_lockObject)
{
calcPercent += dailyPercent;
}
}
});
double bonus = 0;
try
{
bonus = requests
.AsParallel()
.WithDegreeOfParallelism(_salaryConfiguration.MaxConcurrentThreads)
.Where(x => x.Sum > _salaryConfiguration.ExtraSaleSum)
.Sum(x => x.Sum * config.BonusForExtraSales);
}
catch (AggregateException agEx)
{
foreach (var ex in agEx.InnerExceptions)
{
_logger.LogError(ex, "Error calculating bonus in cashier payroll");
}
return 0;
}
return config.Rate + calcPercent + bonus;
}
private double CalculateSalaryForSupervisor(DateTime startDate, DateTime finishDate, SupervisorPostConfiguration config)
{
try
{
return config.Rate + config.PersonalCountTrendPremium *
_workerStorageContract.GetWorkerTrend(startDate, finishDate);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in the supervisor payroll process");
return 0;
}
}
}

View File

@@ -1,20 +1,23 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using System.Text.Json;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class SoftwareBusinessLogicContract(ISoftwareStorageContract
softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
softwareStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : ISoftwareBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISoftwareStorageContract _softwareStorageContract =
softwareStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<SoftwareDataModel> GetAllSoftwares(bool onlyActive)
{
_logger.LogInformation("GetAllSoftwares params: {onlyActive}", onlyActive);
@@ -30,9 +33,9 @@ softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
}
if (!manufacturerId.IsGuid())
{
throw new ValidationException("The value in the field manufacturerId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "ManufacturerId"));
}
_logger.LogInformation("GetAllSoftwares params: {manufacturerId}, { onlyActive} ", manufacturerId, onlyActive);
_logger.LogInformation("GetAllSoftwares params: {manufacturerId}, { onlyActive} ", manufacturerId, onlyActive);
return _softwareStorageContract.GetList(onlyActive, manufacturerId) ??
throw new NullListException();
}
@@ -45,7 +48,7 @@ softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
}
if (!softwareId.IsGuid())
{
throw new ValidationException("The value in the field softwareId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SoftwareId"));
}
return _softwareStorageContract.GetHistoryBySoftwareId(softwareId) ??
throw new NullListException();
@@ -61,17 +64,17 @@ softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
if (data.IsGuid())
{
return _softwareStorageContract.GetElementById(data) ?? throw
new ElementNotFoundException(data);
new ElementNotFoundException(data, _localizer);
}
return _softwareStorageContract.GetElementByName(data) ?? throw new
ElementNotFoundException(data);
ElementNotFoundException(data, _localizer);
}
public void InsertSoftware(SoftwareDataModel softwareDataModel)
{
_logger.LogInformation("New data: {json}",
JsonSerializer.Serialize(softwareDataModel));
ArgumentNullException.ThrowIfNull(softwareDataModel);
softwareDataModel.Validate();
softwareDataModel.Validate(_localizer);
_softwareStorageContract.AddElement(softwareDataModel);
}
public void UpdateSoftware(SoftwareDataModel softwareDataModel)
@@ -79,7 +82,7 @@ softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
_logger.LogInformation("Update data: {json}",
JsonSerializer.Serialize(softwareDataModel));
ArgumentNullException.ThrowIfNull(softwareDataModel);
softwareDataModel.Validate();
softwareDataModel.Validate(_localizer);
_softwareStorageContract.UpdElement(softwareDataModel);
}
@@ -92,7 +95,7 @@ softwareStorageContract, ILogger logger) : ISoftwareBusinessLogicContract
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_softwareStorageContract.DelElement(id);
}

View File

@@ -1,8 +1,10 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using System;
using System.Collections.Generic;
@@ -13,12 +15,12 @@ using System.Threading.Tasks;
namespace SmallSoftwareBusinessLogic.Implementations;
internal class WorkerBusinessLogicContract(IWorkerStorageContract
workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
internal class WorkerBusinessLogicContract(IWorkerStorageContract workerStorageContract, IStringLocalizer<Messages> localizer, ILogger logger) : IWorkerBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IWorkerStorageContract _workerStorageContract =
workerStorageContract;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<WorkerDataModel> GetAllWorkers(bool onlyActive = true)
{
_logger.LogInformation("GetAllWorkers params: {onlyActive}",
@@ -36,7 +38,7 @@ workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
}
if (!postId.IsGuid())
{
throw new ValidationException("The value in the field postId is not a unique identifier.");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "PostId"));
}
return _workerStorageContract.GetList(onlyActive, postId) ?? throw
new NullListException();
@@ -47,7 +49,7 @@ workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
_logger.LogInformation("GetAllWorkers params: {onlyActive}, { fromDate}, { toDate} ", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
return _workerStorageContract.GetList(onlyActive, fromBirthDate:
fromDate, toBirthDate: toDate) ?? throw new NullListException();
@@ -58,7 +60,7 @@ workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
_logger.LogInformation("GetAllWorkers params: {onlyActive}, { fromDate}, { toDate} ", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
throw new IncorrectDatesException(fromDate, toDate, _localizer);
}
return _workerStorageContract.GetList(onlyActive, fromEmploymentDate:
fromDate, toEmploymentDate: toDate) ?? throw new NullListException();
@@ -73,17 +75,17 @@ workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
if (data.IsGuid())
{
return _workerStorageContract.GetElementById(data) ?? throw
new ElementNotFoundException(data);
new ElementNotFoundException(data, _localizer);
}
return _workerStorageContract.GetElementByFIO(data) ?? throw new
ElementNotFoundException(data);
ElementNotFoundException(data, _localizer);
}
public void InsertWorker(WorkerDataModel workerDataModel)
{
_logger.LogInformation("New data: {json}",
JsonSerializer.Serialize(workerDataModel));
ArgumentNullException.ThrowIfNull(workerDataModel);
workerDataModel.Validate();
workerDataModel.Validate(_localizer);
_workerStorageContract.AddElement(workerDataModel);
}
public void UpdateWorker(WorkerDataModel workerDataModel)
@@ -91,7 +93,7 @@ workerStorageContract, ILogger logger) : IWorkerBusinessLogicContract
_logger.LogInformation("Update data: {json}",
JsonSerializer.Serialize(workerDataModel));
ArgumentNullException.ThrowIfNull(workerDataModel);
workerDataModel.Validate();
workerDataModel.Validate(_localizer);
_workerStorageContract.UpdElement(workerDataModel);
}
public void DeleteWorker(string id)
@@ -103,7 +105,7 @@ public void DeleteWorker(string id)
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
}
_workerStorageContract.DelElement(id);
}

View File

@@ -0,0 +1,9 @@
namespace SmallSoftwareBusinessLogic.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

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

@@ -0,0 +1,9 @@
namespace SmallSoftwareBusinessLogic.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

@@ -0,0 +1,76 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace SmallSoftwareBusinessLogic.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 headerStyle = _document.Styles.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@@ -0,0 +1,308 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace SmallSoftwareBusinessLogic.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.BoldTextWithBorders);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.BoldTextWithBorders);
}
_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.BoldTextWithBorders);
}
_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.SimpleTextWithBorders);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorders);
}
_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);
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill()
{
PatternType = new EnumValue<PatternValues>(PatternValues.None)
}
});
workbookStylesPart.Stylesheet.Append(fills);
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 },
DiagonalBorder = new DiagonalBorder()
});
workbookStylesPart.Stylesheet.Append(borders);
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.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorders = 1,
BoldTextWithoutBorders = 2,
BoldTextWithBorders = 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

@@ -0,0 +1,116 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace SmallSoftwareBusinessLogic.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());
var runProperties = new RunProperties();
runProperties.AppendChild(new Bold());
run.AppendChild(runProperties);
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

@@ -7,7 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.2" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,13 @@
using SmallSoftwareContracts.AdapterContracts.OperationResponses;
namespace SmallSoftwareContracts.AdapterContracts;
public interface IReportAdapter
{
Task<ReportOperationResponse> GetDataSoftwaresByHistoryAsync(CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentSoftwaresByHistoryAsync(CancellationToken ct);
Task<ReportOperationResponse> GetDataRequestByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentRequestsByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -0,0 +1,15 @@
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.ViewModels;
namespace SmallSoftwareContracts.AdapterContracts.OperationResponses;
public class ReportOperationResponse : OperationResponse
{
public static ReportOperationResponse OK(List<HistoryOfSoftwareViewModel> data) => OK<ReportOperationResponse, List<HistoryOfSoftwareViewModel>>(data);
public static ReportOperationResponse OK(List<RequestViewModel> data) => OK<ReportOperationResponse, List<RequestViewModel>>(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);
public static ReportOperationResponse OK(List<WorkerSalaryByPeriodViewModel> data) => OK<ReportOperationResponse, List<WorkerSalaryByPeriodViewModel>>(data);
}

View File

@@ -12,5 +12,5 @@ public class PostBindingModel
public string? PostId => Id;
public string? PostName { get; set; }
public string? PostType { get; set; }
public double Salary { get; set; }
public double? Salary { get; set; }
}

View File

@@ -12,4 +12,5 @@ public class WorkerBindingModel
public string? PostId { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
public string? ConfigurationJson { get; set; }
}

View File

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface IManufacturerBusinessLogicContract
internal interface IManufacturerBusinessLogicContract
{
List<ManufacturerDataModel> GetAllManufacturers();
ManufacturerDataModel GetManufacturerByData(string data);

View File

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface IPostBusinessLogicContract
internal interface IPostBusinessLogicContract
{
List<PostDataModel> GetAllPosts();
List<PostDataModel> GetAllDataOfPost(string postId);

View File

@@ -0,0 +1,13 @@
using SmallSoftwareContracts.DataModels;
namespace SmallSoftwareContracts.BusinessLogicsContracts;
internal interface IReportContract
{
Task<List<HistoryOfSoftwareDataModel>> GetDataSoftwaresByHistoryAsync(CancellationToken ct);
Task<List<RequestDataModel>> GetDataRequestByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<Stream> CreateDocumentSoftwaresByHistoryAsync(CancellationToken ct);
Task<Stream> CreateDocumentRequestsByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<List<WorkerSalaryByPeriodDataModel>> GetDataSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<Stream> CreateDocumentSalaryByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface IRequestBusinessLogicContract
internal interface IRequestBusinessLogicContract
{
List<RequestDataModel> GetAllRequestsByPeriod(DateTime fromDate, DateTime toDate);

View File

@@ -3,7 +3,7 @@ using SmallSoftwareContracts.DataModels;
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface ISalaryBusinessLogicContract
internal interface ISalaryBusinessLogicContract
{
List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate);
List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime fromDate, DateTime toDate, string workerId);

View File

@@ -2,7 +2,7 @@
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface ISoftwareBusinessLogicContract
internal interface ISoftwareBusinessLogicContract
{
List<SoftwareDataModel> GetAllSoftwares(bool onlyActive = true);
List<SoftwareDataModel> GetAllSoftwaresByManufacturer(string manufacturerId,

View File

@@ -2,7 +2,7 @@
namespace SmallSoftwareContracts.BusinessLogicsContracts;
public interface IWorkerBusinessLogicContract
internal interface IWorkerBusinessLogicContract
{
List<WorkerDataModel> GetAllWorkers(bool onlyActive = true);
List<WorkerDataModel> GetAllWorkersByPost(string postId, bool onlyActive = true);

View File

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

View File

@@ -1,10 +1,12 @@
using SmallSoftwareContracts.Exceptions;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.DataModels;
public class InstallationRequestDataModel(string softwareId, string requestId, int count, double price) : IValidation
internal class InstallationRequestDataModel(string softwareId, string requestId, int count, double price) : IValidation
{
private readonly SoftwareDataModel? _software;
@@ -19,20 +21,21 @@ public class InstallationRequestDataModel(string softwareId, string requestId, i
_software = software;
}
public InstallationRequestDataModel() : this(string.Empty, string.Empty, 0, 0) { }
public void Validate()
public void Validate(IStringLocalizer<Messages> localizer)
{
if (SoftwareId.IsEmpty())
throw new ValidationException("Field SoftwareId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SoftwareId"));
if (!SoftwareId.IsGuid())
throw new ValidationException("The value in the field SoftwareId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SoftwareId"));
if (RequestId.IsEmpty())
throw new ValidationException("Field RequestId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "RequestId"));
if (!RequestId.IsGuid())
throw new ValidationException("The value in the field RequestId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "RequestId"));
if (Count <= 0)
throw new ValidationException("Field Count is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Count"));
if (Price <= 0)
throw new ValidationException("Field Price is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price"));
}
}

View File

@@ -1,10 +1,12 @@
using SmallSoftwareContracts.Exceptions;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.DataModels;
public class ManufacturerDataModel(string id, string manufacturerName, string?
internal class ManufacturerDataModel(string id, string manufacturerName, string?
prevManufacturerName, string? prevPrevManufacturerName) : IValidation
{
public string Id { get; private set; } = id;
@@ -16,15 +18,17 @@ prevManufacturerName, string? prevPrevManufacturerName) : IValidation
public ManufacturerDataModel(string id, string manufacturerName) : this(id, manufacturerName, null, null){ }
public void Validate()
public ManufacturerDataModel() : this(string.Empty, string.Empty, null, null) { }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
if (ManufacturerName.IsEmpty())
throw new ValidationException("Field ManufacturerName is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "ManufacturerName"));
}
}

View File

@@ -1,28 +1,39 @@
using SmallSoftwareContracts.Enums;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.DataModels;
public class PostDataModel(string postId, string postName, PostType
internal class PostDataModel(string postId, string postName, PostType
postType, double salary) : IValidation
{
[AlternativeName("PostId")]
public string Id { get; private set; } = postId;
public string PostName { get; private set; } = postName;
public PostType PostType { get; private set; } = postType;
public double Salary { get; private set; } = salary;
public void Validate()
public PostDataModel() : this(string.Empty, string.Empty, PostType.None, 0) { }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
if (PostName.IsEmpty())
throw new ValidationException("Field PostName is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostName"));
if (PostType == PostType.None)
throw new ValidationException("Field PostType is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "PostType"));
if (Salary <= 0)
throw new ValidationException("Field Salary is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Salary"));
}
}

View File

@@ -1,6 +1,9 @@
using SmallSoftwareContracts.Exceptions;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using System.Text.RegularExpressions;
using System.Xml;
@@ -8,7 +11,7 @@ using System.Xml;
namespace SmallSoftwareContracts.DataModels;
public class RequestDataModel : IValidation
internal class RequestDataModel : IValidation
{
private readonly WorkerDataModel? _worker;
public string Id { get; private set; }
@@ -17,8 +20,13 @@ public class RequestDataModel : IValidation
public string Email { get; private set; }
public double Sum { get; private set; }
public bool IsCancel { get; private set; }
[AlternativeName("InstallationRequests")]
public List<InstallationRequestDataModel>? Softwares { get; private set; }
public string WorkerFIO => _worker?.FIO ?? string.Empty;
public string WorkerFIO => _worker?.FIO ?? string.Empty;
public RequestDataModel() : this(string.Empty, string.Empty, string.Empty, false,new List<InstallationRequestDataModel>(), DateTime.UtcNow) { }
public RequestDataModel(string id, string workerId, string email, bool isCancel, List<InstallationRequestDataModel> installationRequests, DateTime requestDate)
{
Id = id;
@@ -37,24 +45,27 @@ public class RequestDataModel : IValidation
_worker = worker;
}
public void Validate()
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
if (WorkerId.IsEmpty())
throw new ValidationException("Field WorkerId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "WorkerId"));
if (!WorkerId.IsGuid())
throw new ValidationException("The value in the field WorkerId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "WorkerId"));
if (Sum <= 0)
throw new ValidationException("Field Sum is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Sum"));
if ((Softwares?.Count ?? 0) == 0)
throw new ValidationException("The request must include products");
throw new ValidationException(localizer["ValidationExceptionMessageNoProductsInSale"]);
if (!Regex.IsMatch(Email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"))
{
throw new ValidationException("Invalid email format");
}
throw new ValidationException(localizer["ValidationExceptionMessageIncorrectEmail"]);
}
}

View File

@@ -1,15 +1,17 @@
using SmallSoftwareContracts.Exceptions;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.DataModels;
public class SalaryDataModel(string workerId, DateTime salaryDate, double
internal class SalaryDataModel(string workerId, DateTime salaryDate, double
workerSalary) : IValidation
{
private readonly WorkerDataModel? _worker;
public string WorkerId { get; private set; } = workerId;
public DateTime SalaryDate { get; private set; } = salaryDate;
public DateTime SalaryDate { get; private set; } = salaryDate.ToUniversalTime();
public double Salary { get; private set; } = workerSalary;
public string WorkerFIO => _worker?.FIO ?? string.Empty;
@@ -17,15 +19,17 @@ workerSalary) : IValidation
{
_worker = worker;
}
public void Validate()
public SalaryDataModel() : this(string.Empty, DateTime.Now, 0) { }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (WorkerId.IsEmpty())
throw new ValidationException("Field WorkerId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "WorkerId"));
if (!WorkerId.IsGuid())
throw new ValidationException("The value in the field WorkerId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "WorkerId"));
if (Salary <= 0)
throw new ValidationException("Field Salary is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Salary"));
}
}

View File

@@ -1,7 +1,9 @@
using SmallSoftwareContracts.Enums;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Resources;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,7 +13,7 @@ using System.Xml;
namespace SmallSoftwareContracts.DataModels;
public class SoftwareDataModel(string id, string softwareName, SoftwareType softwareType, string manufacturerId, double price, bool isDeleted) : IValidation
internal class SoftwareDataModel(string id, string softwareName, SoftwareType softwareType, string manufacturerId, double price, bool isDeleted) : IValidation
{
private readonly ManufacturerDataModel? _manufacturer;
public string Id { get; private set; } = id;
@@ -34,22 +36,22 @@ public class SoftwareDataModel(string id, string softwareName, SoftwareType soft
softwareType, manufacturerId, price, false)
{ }
public void Validate()
public SoftwareDataModel() : this(string.Empty, string.Empty, SoftwareType.None, string.Empty, 0.0, false) { }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "Id"));
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "Id"));
if (SoftwareName.IsEmpty())
throw new ValidationException("Field SoftwareName is empty");
if (SoftwareType == SoftwareType.None)
throw new ValidationException("Field SoftwareType is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SoftwareName"));
if (SoftwareType == SoftwareType.None)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SoftwareType"));
if (ManufacturerId.IsEmpty())
throw new ValidationException("Field ManufacturerId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "ManufacturerId"));
if (!ManufacturerId.IsGuid())
throw new ValidationException("The value in the field ManufacturerId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "ManufacturerId"));
if (Price <= 0)
throw new ValidationException("Field Price is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Price"));
}
}

View File

@@ -1,37 +1,36 @@
using SmallSoftwareContracts.Exceptions;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.DataModels;
public class SoftwareHistoryDataModel(string softwareId, double oldPrice) : IValidation
internal class SoftwareHistoryDataModel(string softwareId, double oldPrice) : IValidation
{
private readonly SoftwareDataModel? _software;
private SoftwareDataModel? Software;
public string SoftwareId { get; private set; } = softwareId;
public double OldPrice { get; private set; } = oldPrice;
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow.ToUniversalTime();
public string SoftwareName => _software?.SoftwareName ?? string.Empty;
public string SoftwareName => Software?.SoftwareName ?? string.Empty;
public SoftwareHistoryDataModel(string softwareId, double oldPrice, DateTime
changeDate, SoftwareDataModel software) : this(softwareId, oldPrice)
{
ChangeDate = changeDate;
_software = software;
Software = software;
}
public void Validate()
public SoftwareHistoryDataModel() : this(string.Empty, 0) { }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (SoftwareId.IsEmpty())
throw new ValidationException("Field SoftwareId is empty");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageEmptyField"], "SoftwareId"));
if (!SoftwareId.IsGuid())
throw new ValidationException("The value in the field SoftwareId is not a unique identifier");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotAId"], "SoftwareId"));
if (OldPrice <= 0)
throw new ValidationException("Field OldPrice is less than or equal to 0");
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "OldPrice"));
}
}

View File

@@ -1,50 +1,90 @@
using SmallSoftwareContracts.Exceptions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Extensions;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.DataModels;
public class WorkerDataModel(string id, string fio, string postId, DateTime
birthDate, DateTime employmentDate, bool isDeleted) : IValidation
internal class WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted, PostConfiguration configuration) : IValidation
{
private readonly PostDataModel? _post;
[AlternativeName("Post")]
public PostDataModel? _post;
public string Id { get; private set; } = id;
public string FIO { get; private set; } = fio;
public string PostId { get; private set; } = postId;
public DateTime BirthDate { get; private set; } = birthDate;
public DateTime EmploymentDate { get; private set; } = employmentDate;
public DateTime BirthDate { get; private set; } = birthDate.ToUniversalTime();
public DateTime EmploymentDate { get; private set; } = employmentDate.ToUniversalTime();
public bool IsDeleted { get; private set; } = isDeleted;
public string PostName => _post?.PostName ?? string.Empty;
[AlternativeName("ConfigurationJson")]
[AlternativeName("Configuration")]
[PostProcessing(MappingCallMethodName = "ParseJson")]
public PostConfiguration ConfigurationModel { get; private set; } = configuration;
public WorkerDataModel(string id, string fio, string postId,
DateTime birthDate, DateTime employmentDate, bool isDeleted, PostDataModel post) :
this(id, fio, postId, birthDate, employmentDate, isDeleted)
{
_post = post;
}
public WorkerDataModel(string id, string fio, string postId,
DateTime birthDate, DateTime employmentDate) : this(id, fio, postId, birthDate, employmentDate, false)
public WorkerDataModel() : this(string.Empty, string.Empty, string.Empty, DateTime.UtcNow, DateTime.UtcNow, false, (PostConfiguration)null)
{ }
public WorkerDataModel(string id, string fio, string postId, DateTime
birthDate, DateTime employmentDate, bool isDeleted, PostDataModel post) :
this(id, fio, postId, birthDate, employmentDate, isDeleted, new PostConfiguration { Rate = 10 })
{
_post = post;
}
public void Validate()
public WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate)
: this(id, fio, postId, birthDate, employmentDate, false, new PostConfiguration { Rate = 10 })
{ }
public void Validate(IStringLocalizer<Messages> localizer)
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageEmptyField, nameof(Id)]);
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageNotAId, nameof(Id)]);
if (FIO.IsEmpty())
throw new ValidationException("Field FIO is empty");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageEmptyField, nameof(FIO)]);
if (PostId.IsEmpty())
throw new ValidationException("Field PostId is empty");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageEmptyField, nameof(PostId)]);
if (!PostId.IsGuid())
throw new ValidationException("The value in the field PostId is not a unique identifier");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageNotAId, nameof(PostId)]);
if (BirthDate.Date > DateTime.Now.AddYears(-16).Date)
throw new ValidationException($"Minors cannot be hired (BirthDate = { BirthDate.ToShortDateString() })");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageMinorsBirthDate, BirthDate.ToShortDateString()]);
if (EmploymentDate.Date < BirthDate.Date)
throw new ValidationException("The date of employment cannot be less than the date of birth");
if ((EmploymentDate - BirthDate).TotalDays / 365 < 16)
throw new ValidationException($"Minors cannot be hired (EmploymentDate - { EmploymentDate.ToShortDateString() }, BirthDate - { BirthDate.ToShortDateString()})");
throw new ValidationException(localizer[Messages.ValidationExceptionMessageEmploymentDateAndBirthDate, EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString()]);
if ((EmploymentDate - BirthDate).TotalDays / 365 < 16)
throw new ValidationException(localizer[Messages.ValidationExceptionMessageMinorsEmploymentDate, EmploymentDate.ToShortDateString(), BirthDate.ToShortDateString()]);
if (ConfigurationModel is null)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageNotInitialized"], "ConfigurationModel"));
if (ConfigurationModel!.Rate <= 0)
throw new ValidationException(string.Format(localizer["ValidationExceptionMessageLessOrEqualZero"], "Rate"));
}
private PostConfiguration? ParseJson(string json)
{
var obj = JToken.Parse(json);
if (obj is not null)
{
return obj.Value<string>("Type") switch
{
nameof(CashierPostConfiguration) => JsonConvert.DeserializeObject<CashierPostConfiguration>(json)!,
nameof(SupervisorPostConfiguration) => JsonConvert.DeserializeObject<SupervisorPostConfiguration>(json)!,
_ => JsonConvert.DeserializeObject<PostConfiguration>(json)!,
};
}
return null;
}
}

View File

@@ -0,0 +1,13 @@
using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.DataModels;
public class WorkerSalaryByPeriodDataModel
{
[AlternativeName("FIO")]
public required string WorkerFIO { get; set; }
public double TotalSalary { get; set; }
public DateTime FromPeriod { get; set; }
public DateTime ToPeriod { get; set; }
}

View File

@@ -1,5 +1,7 @@
namespace SmallSoftwareContracts.Exceptions;
public class ElementDeletedException : Exception
{
public ElementDeletedException(string id) : base($"Cannot modify a deleted item(id: { id})") { }
}
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.Exceptions;
internal class ElementDeletedException(string id, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["ElementDeletedExceptionMessage"], id))
{ }

View File

@@ -1,13 +1,11 @@

using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.Exceptions;
public class ElementExistsException : Exception
internal class ElementExistsException(string paramName, string paramValue, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["ElementExistsExceptionMessage"], paramValue, paramName))
{
public string ParamName { get; private set; }
public string ParamValue { get; private set; }
public ElementExistsException(string paramName, string paramValue) :
base($"There is already an element with value{paramValue} of parameter { paramName}")
{
ParamName = paramName;
ParamValue = paramValue;
}
}
public string ParamName { get; private set; } = paramName;
public string ParamValue { get; private set; } = paramValue;
}

View File

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

View File

@@ -1,14 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.Exceptions;
public class IncorrectDatesException : Exception
{
public IncorrectDatesException(DateTime start, DateTime end) :
base($"The end date must be later than the start date..StartDate: { start: dd.MM.YYYY}.EndDate: {end:dd.MM.YYYY}") { }
}
internal class IncorrectDatesException(DateTime start, DateTime end, IStringLocalizer<Messages> localizer) :
Exception(string.Format(localizer["IncorrectDatesExceptionMessage"], start.ToShortDateString(), end.ToShortDateString()))
{ }

View File

@@ -1,8 +1,8 @@

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

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SmallSoftwareContracts.Infrastructure;
public interface IConfigurationSalary
{
double ExtraSaleSum { get; }
int MaxConcurrentThreads { get; }
}

View File

@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.Resources;
namespace SmallSoftwareContracts.Infrastructure;
public interface IValidation
internal interface IValidation
{
void Validate();
void Validate(IStringLocalizer<Messages> localizer);
}

View File

@@ -6,10 +6,13 @@ namespace SmallSoftwareContracts.Infrastructure;
public class OperationResponse
{
protected HttpStatusCode StatusCode { get; set; }
protected HttpStatusCode StatusCode { get; set; }
protected object? Result { get; set; }
public IActionResult GetResponse(HttpRequest request, HttpResponse
response)
protected string? FileName { get; set; }
public IActionResult GetResponse(HttpRequest request, HttpResponse response)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(response);
@@ -18,31 +21,46 @@ public class OperationResponse
{
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()
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
Result = data,
FileName = fileName
};
protected static TResult NoContent<TResult>() where TResult :
OperationResponse, new() => new() { StatusCode = HttpStatusCode.NoContent };
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()
where TResult : OperationResponse, new() => new()
{
StatusCode = HttpStatusCode.BadRequest,
StatusCode =
HttpStatusCode.BadRequest,
Result = errorMessage
};
protected static TResult NotFound<TResult>(string? errorMessage = null)
where TResult : OperationResponse, new() => new()
protected static TResult NotFound<TResult>(string? errorMessage = null)
where TResult : OperationResponse, new() => new()
{
StatusCode = HttpStatusCode.NotFound,
StatusCode =
HttpStatusCode.NotFound,
Result = errorMessage
};
protected static TResult InternalServerError<TResult>(string? errorMessage = null) where TResult : OperationResponse, new() => new()
protected static TResult InternalServerError<TResult>(string? errorMessage
= null) where TResult : OperationResponse, new() => new()
{
StatusCode = HttpStatusCode.InternalServerError,
StatusCode =
HttpStatusCode.InternalServerError,
Result = errorMessage
};
}
}

View File

@@ -0,0 +1,8 @@
namespace SmallSoftwareContracts.Infrastructure.PostConfigurations;
public class CashierPostConfiguration : PostConfiguration
{
public override string Type => nameof(CashierPostConfiguration);
public double SalePercent { get; set; }
public double BonusForExtraSales { get; set; }
}

View File

@@ -0,0 +1,9 @@
using System.Globalization;
namespace SmallSoftwareContracts.Infrastructure.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

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

View File

@@ -0,0 +1,7 @@
namespace SmallSoftwareContracts.Mapper;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
class AlternativeNameAttribute(string alternativeName) : Attribute
{
public string AlternativeName { get; set; } = alternativeName;
}

View File

@@ -0,0 +1,305 @@
using System.Collections;
using System.Reflection;
using Newtonsoft.Json;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
namespace SmallSoftwareContracts.Mapper;
public static class CustomMapper
{
public static To MapObject<To>(object obj, To newObject)
{
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(newObject);
var typeFrom = obj.GetType();
var typeTo = newObject.GetType();
var propertiesFrom = typeFrom.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x => x.CanRead)
.ToArray();
foreach (var property in typeTo.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x => x.CanWrite))
{
if (property.GetCustomAttribute<IgnoreMappingAttribute>() is not null)
continue;
var propertyFrom = TryGetPropertyFrom(property, propertiesFrom);
if (propertyFrom is null)
{
FindAndMapDefaultValue(property, newObject);
continue;
}
var fromValue = propertyFrom.GetValue(obj);
var postProcessingAttribute = property.GetCustomAttribute<PostProcessingAttribute>();
if (postProcessingAttribute is not null)
{
var value = PostProcessing(fromValue, postProcessingAttribute, newObject);
if (value is not null)
{
property.SetValue(newObject, value);
}
continue;
}
if (propertyFrom.PropertyType.IsGenericType &&
propertyFrom.PropertyType.GetGenericTypeDefinition() == typeof(List<>) &&
fromValue is not null)
{
var elementType = property.PropertyType.GenericTypeArguments[0];
if (elementType.IsPrimitive || elementType == typeof(string) || elementType.IsValueType)
{
var original = (IEnumerable)fromValue;
var copy = (IList)Activator.CreateInstance(property.PropertyType)!;
foreach (var item in original)
copy.Add(item);
property.SetValue(newObject, copy);
continue;
}
fromValue = MapListOfObjects(property, fromValue);
}
if (propertyFrom.PropertyType.IsEnum && property.PropertyType.IsEnum)
{
if (fromValue != null && property.PropertyType != propertyFrom.PropertyType)
{
fromValue = System.Enum.ToObject(property.PropertyType, Convert.ChangeType(fromValue, System.Enum.GetUnderlyingType(propertyFrom.PropertyType)));
}
property.SetValue(newObject, fromValue);
continue;
}
if (propertyFrom.PropertyType.IsEnum && property.PropertyType == typeof(string) && fromValue != null)
{
fromValue = fromValue.ToString();
}
else if (!propertyFrom.PropertyType.IsEnum && property.PropertyType.IsEnum && fromValue is not null)
{
if (fromValue is string stringValue)
fromValue = System.Enum.Parse(property.PropertyType, stringValue);
else
fromValue = System.Enum.ToObject(property.PropertyType, fromValue);
}
if (fromValue is not null)
{
if (propertyFrom.PropertyType.IsClass
&& property.PropertyType.IsClass
&& propertyFrom.PropertyType != typeof(string)
&& property.PropertyType != typeof(string)
&& !property.PropertyType.IsAssignableFrom(propertyFrom.PropertyType))
{
try
{
var nestedInstance = Activator.CreateInstance(property.PropertyType);
if (nestedInstance != null)
{
var nestedMapped = MapObject(fromValue, nestedInstance);
property.SetValue(newObject, nestedMapped);
continue;
}
}
catch { }
}
property.SetValue(newObject, fromValue);
}
}
var fieldsTo = typeTo.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var fieldsFrom = typeFrom.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fieldsTo)
{
if (field.Name.Contains("k__BackingField"))
continue;
if (field.GetCustomAttribute<IgnoreMappingAttribute>() is not null)
continue;
var sourceField = fieldsFrom.FirstOrDefault(f => f.Name == field.Name);
object? fromValue = null;
if (sourceField is not null)
{
fromValue = sourceField.GetValue(obj);
}
else
{
var propertyName = field.Name.TrimStart('_');
var sourceProperty = typeFrom.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (sourceProperty is not null && sourceProperty.CanRead)
{
fromValue = sourceProperty.GetValue(obj);
}
}
if (fromValue is null)
continue;
if (field.FieldType.IsClass && field.FieldType != typeof(string))
{
try
{
var nested = Activator.CreateInstance(field.FieldType)!;
var mapped = MapObject(fromValue, nested);
RemoveReadOnly(field);
field.SetValue(newObject, mapped);
continue;
}
catch (MissingMethodException)
{
Console.WriteLine($"Нет конструктора по умолчанию для {field.FieldType}");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка маппинга для {field.Name}: {ex.Message}");
}
}
RemoveReadOnly(field);
field.SetValue(newObject, fromValue);
}
var classPostProcessing = typeTo.GetCustomAttribute<PostProcessingAttribute>();
if (classPostProcessing is not null && classPostProcessing.MappingCallMethodName is not null)
{
var methodInfo = typeTo.GetMethod(classPostProcessing.MappingCallMethodName, BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo?.Invoke(newObject, []);
}
return newObject;
}
private static void RemoveReadOnly(FieldInfo field)
{
if (!field.IsInitOnly)
return;
var attr = typeof(FieldInfo).GetField("m_fieldAttributes", BindingFlags.Instance | BindingFlags.NonPublic);
if (attr != null)
{
var current = (FieldAttributes)attr.GetValue(field)!;
attr.SetValue(field, current & ~FieldAttributes.InitOnly);
}
}
public static To MapObject<To>(object obj) => MapObject(obj, Activator.CreateInstance<To>()!);
public static To? MapObjectWithNull<To>(object? obj) => obj is null ? default : MapObject(obj, Activator.CreateInstance<To>());
private static PropertyInfo? TryGetPropertyFrom(PropertyInfo propertyTo, PropertyInfo[] propertiesFrom)
{
var customAttribute = propertyTo.GetCustomAttributes<AlternativeNameAttribute>()?
.ToArray()
.FirstOrDefault(x => propertiesFrom.Any(y => y.Name == x.AlternativeName));
if (customAttribute is not null)
{
return propertiesFrom.FirstOrDefault(x => x.Name == customAttribute.AlternativeName);
}
return propertiesFrom.FirstOrDefault(x => x.Name == propertyTo.Name);
}
private static object? PostProcessing<T>(object? value, PostProcessingAttribute postProcessingAttribute, T newObject)
{
if (value is null || newObject is null) return null;
try
{
if (!string.IsNullOrEmpty(postProcessingAttribute.MappingCallMethodName))
{
var methodInfo = newObject.GetType().GetMethod(
postProcessingAttribute.MappingCallMethodName,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (methodInfo != null)
{
var parameters = methodInfo.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string))
{
if (value is string strValue)
{
return methodInfo.Invoke(newObject, [strValue]);
}
else if (value is PostConfiguration config)
{
var jsonValue = JsonConvert.SerializeObject(config);
return methodInfo.Invoke(newObject, [jsonValue]);
}
}
else if (parameters.Length == 1 && parameters[0].ParameterType == typeof(PostConfiguration))
{
return methodInfo.Invoke(newObject, [value]);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"PostProcessing error: {ex.Message}");
}
return null;
}
private static object? ToLocalTime(object? obj)
{
if (obj is DateTime date)
return date.ToLocalTime();
return obj;
}
private static object? ToUniversalTime(object? obj)
{
if (obj is DateTime date)
return date.ToUniversalTime();
return obj;
}
private static void FindAndMapDefaultValue<T>(PropertyInfo property, T newObject)
{
var defaultValueAttribute = property.GetCustomAttribute<DefaultValueAttribute>();
if (defaultValueAttribute is null)
{
return;
}
if (defaultValueAttribute.DefaultValue is not null)
{
property.SetValue(newObject, defaultValueAttribute.DefaultValue);
return;
}
var value = defaultValueAttribute.Func switch
{
DefaultValueFunc.UtcNow => DateTime.UtcNow,
_ => (object?)null,
};
if (value is not null)
{
property.SetValue(newObject, value);
}
}
private static object? MapListOfObjects(PropertyInfo propertyTo, object list)
{
var listResult = Activator.CreateInstance(propertyTo.PropertyType);
var genericType = propertyTo.PropertyType.GenericTypeArguments[0];
var addMethod = propertyTo.PropertyType.GetMethod("Add", new[] { genericType });
foreach (var elem in (IEnumerable)list)
{
var newElem = MapObject(elem, Activator.CreateInstance(genericType)!);
if (newElem is not null)
{
addMethod?.Invoke(listResult, [newElem]);
}
}
return listResult;
}
}

View File

@@ -0,0 +1,12 @@
namespace SmallSoftwareContracts.Mapper;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
class DefaultValueAttribute : Attribute
{
public object? DefaultValue { get; set; }
public DefaultValueFunc Func { get; set; } = DefaultValueFunc.None;
[Obsolete("Use Func instead")]
public string? FuncName { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace SmallSoftwareContracts.Mapper;
public enum DefaultValueFunc
{
None = 0,
UtcNow = 1
}

View File

@@ -0,0 +1,6 @@
namespace SmallSoftwareContracts.Mapper;
[AttributeUsage(AttributeTargets.Property)]
class IgnoreMappingAttribute : Attribute
{
}

View File

@@ -0,0 +1,9 @@
namespace SmallSoftwareContracts.Mapper;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Field)]
class PostProcessingAttribute : Attribute
{
public string? MappingCallMethodName { get; set; }
public PostProcessingType ActionType { get; set; } = PostProcessingType.None;
}

View File

@@ -0,0 +1,10 @@
namespace SmallSoftwareContracts.Mapper;
enum PostProcessingType
{
None = -1,
ToUniversalTime = 1,
ToLocalTime = 2
}

View File

@@ -0,0 +1,405 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace SmallSoftwareContracts.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("SmallSoftwareContracts.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 DocumentDocCaptionData {
get {
return ResourceManager.GetString("DocumentDocCaptionData", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Старая цена.
/// </summary>
internal static string DocumentDocCaptionOldPrice {
get {
return ResourceManager.GetString("DocumentDocCaptionOldPrice", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Название ПО.
/// </summary>
internal static string DocumentDocCaptionSoftware {
get {
return ResourceManager.GetString("DocumentDocCaptionSoftware", 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 DocumentExcelCaptionCount {
get {
return ResourceManager.GetString("DocumentExcelCaptionCount", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Дата.
/// </summary>
internal static string DocumentExcelCaptionDate {
get {
return ResourceManager.GetString("DocumentExcelCaptionDate", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на ПО.
/// </summary>
internal static string DocumentExcelCaptionSoftware {
get {
return ResourceManager.GetString("DocumentExcelCaptionSoftware", 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>
/// Ищет локализованную строку, похожую на 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}, {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>
/// Ищет локализованную строку, похожую на Значение в поле Email не является Email.
/// </summary>
internal static string ValidationExceptionMessageIncorrectEmail {
get {
return ResourceManager.GetString("ValidationExceptionMessageIncorrectEmail", resourceCulture);
}
}
/// <summary>
/// Ищет локализованную строку, похожую на Значение в поле ФИО не является ФИО.
/// </summary>
internal static string ValidationExceptionMessageIncorrectFIO {
get {
return ResourceManager.GetString("ValidationExceptionMessageIncorrectFIO", 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 ValidationExceptionMessageNoSoftwaresCount {
get {
return ResourceManager.GetString("ValidationExceptionMessageNoSoftwaresCount", 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

@@ -0,0 +1,234 @@
<?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="AdapterMessageElementDeletedException" xml:space="preserve">
<value>Element mit Daten: {0} </value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>Element mit Daten: {0} nicht gefunden</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>Daten sind leer</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>Ungültige Datumsangaben: {0}</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>Fehler bei der Datenverarbeitung: {0}</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>Fehler beim Zugriff auf den Datenspeicher: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>Falsche Daten wurden übergeben: {0}</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>Datum</value>
</data>
<data name="DocumentDocCaptionOldPrice" xml:space="preserve">
<value>Alter Preis</value>
</data>
<data name="DocumentDocCaptionSoftware" xml:space="preserve">
<value>Softwarename</value>
</data>
<data name="DocumentDocHeader" xml:space="preserve">
<value>Software nach Geschichte</value>
</data>
<data name="DocumentDocSubHeader" xml:space="preserve">
<value>Erstellt am {0}</value>
</data>
<data name="DocumentExcelCaptionCount" xml:space="preserve">
<value>Anzahl</value>
</data>
<data name="DocumentExcelCaptionDate" xml:space="preserve">
<value>Datum</value>
</data>
<data name="DocumentExcelCaptionSoftware" xml:space="preserve">
<value>Software</value>
</data>
<data name="DocumentExcelCaptionSum" xml:space="preserve">
<value>Summe</value>
</data>
<data name="DocumentExcelCaptionTotal" xml:space="preserve">
<value>Gesamtbetrag</value>
</data>
<data name="DocumentExcelHeader" xml:space="preserve">
<value>Anfragen im Zeitraum</value>
</data>
<data name="DocumentExcelSubHeader" xml:space="preserve">
<value>von {0} bis {1}</value>
</data>
<data name="DocumentPdfDiagramCaption" xml:space="preserve">
<value>Abrechnungen</value>
</data>
<data name="DocumentPdfHeader" xml:space="preserve">
<value>Gehaltsabrechnung</value>
</data>
<data name="DocumentPdfSubHeader" xml:space="preserve">
<value> für den Zeitraum von {0} bis {1}</value>
</data>
<data name="ElementDeletedExceptionMessage" xml:space="preserve">
<value>Ein gelöschtes Element (ID: {0}) kann nicht bearbeitet werden</value>
</data>
<data name="ElementExistsExceptionMessage" xml:space="preserve">
<value>Es existiert bereits ein Element mit Wert {0} für Parameter {1}rfhjefwbe</value>
</data>
<data name="ElementNotFoundExceptionMessage" xml:space="preserve">
<value>Element mit Wert = {0} nicht gefunden</value>
</data>
<data name="IncorrectDatesExceptionMessage" xml:space="preserve">
<value>Das Enddatum muss nach dem Startdatum liegen. Startdatum: {0}. Enddatum: {1}</value>
</data>
<data name="NotEnoughDataToProcessExceptionMessage" xml:space="preserve">
<value>Unzureichende Daten zur Verarbeitung: {0}</value>
</data>
<data name="NotFoundDataMessage" xml:space="preserve">
<value>Keine Daten gefunden</value>
</data>
<data name="ValidationExceptionMessageEmploymentDateAndBirthDate" xml:space="preserve">
<value>Das Einstellungsdatum kann nicht vor dem Geburtsdatum liegen ({0}, {1})</value>
</data>
<data name="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>Das Feld {0} ist leer</value>
</data>
<data name="ValidationExceptionMessageIncorrectEmail" xml:space="preserve">
<value>Der Wert im Feld Email ist kein vollständiger Email.</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO" xml:space="preserve">
<value>Der Wert im Feld NAME ist kein vollständiger Name.</value>
</data>
<data name="ValidationExceptionMessageLessOrEqualZero" xml:space="preserve">
<value>Der Wert im Feld {0} ist kleiner oder gleich 0</value>
</data>
<data name="ValidationExceptionMessageMinorsBirthDate" xml:space="preserve">
<value>Minderjährige können nicht eingestellt werden (Geburtsdatum = {0})</value>
</data>
<data name="ValidationExceptionMessageMinorsEmploymentDate" xml:space="preserve">
<value>Minderjährige können nicht eingestellt werden (Einstellungsdatum: {0}, Geburtsdatum: {1})</value>
</data>
<data name="ValidationExceptionMessageNoSoftwaresCount" xml:space="preserve">
<value>Es muss mindestens ein Artikel zum Verkauf stehen</value>
</data>
<data name="ValidationExceptionMessageNotAId" xml:space="preserve">
<value>Der Wert im Feld {0} ist kein eindeutiger Identifikator.</value>
</data>
<data name="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>Das Feld {0} ist nicht initialisiert</value>
</data>
</root>

View File

@@ -0,0 +1,234 @@
<?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="AdapterMessageElementDeletedException" xml:space="preserve">
<value>Element by data: {0} was deleted</value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>Not found element by data: {0}</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>Data is empty</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>Incorrect dates: {0}</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>Error processing data: {0}</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>Error while working with data storage: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>Incorrect data transmitted: {0}</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>Data</value>
</data>
<data name="DocumentDocCaptionOldPrice" xml:space="preserve">
<value>Old price</value>
</data>
<data name="DocumentDocCaptionSoftware" xml:space="preserve">
<value>Software Name</value>
</data>
<data name="DocumentDocHeader" xml:space="preserve">
<value>Software by History</value>
</data>
<data name="DocumentDocSubHeader" xml:space="preserve">
<value>Generated on date {0}</value>
</data>
<data name="DocumentExcelCaptionCount" xml:space="preserve">
<value>Count</value>
</data>
<data name="DocumentExcelCaptionDate" xml:space="preserve">
<value>Data</value>
</data>
<data name="DocumentExcelCaptionSoftware" xml:space="preserve">
<value>Software</value>
</data>
<data name="DocumentExcelCaptionSum" xml:space="preserve">
<value>Summ</value>
</data>
<data name="DocumentExcelCaptionTotal" xml:space="preserve">
<value>Overall</value>
</data>
<data name="DocumentExcelHeader" xml:space="preserve">
<value>Requests in period</value>
</data>
<data name="DocumentExcelSubHeader" xml:space="preserve">
<value>from {0} to {1}</value>
</data>
<data name="DocumentPdfDiagramCaption" xml:space="preserve">
<value>Arrivals</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="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="NotFoundDataMessage" xml:space="preserve">
<value>No data found</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="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>The value in field {0} is empty</value>
</data>
<data name="ValidationExceptionMessageIncorrectEmail" xml:space="preserve">
<value>The value in the Email field is not a Email</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO" xml:space="preserve">
<value>The value in the FULL NAME field is not a full name.</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="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="ValidationExceptionMessageNoSoftwaresCount" xml:space="preserve">
<value>There must be at least one item on request</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="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>The value in field {0} is not initialized</value>
</data>
</root>

View File

@@ -0,0 +1,234 @@
<?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="AdapterMessageElementDeletedException" xml:space="preserve">
<value>Элемент по данным: {0} был удален</value>
</data>
<data name="AdapterMessageElementNotFoundException" xml:space="preserve">
<value>Не найден элемент по данным: {0}</value>
</data>
<data name="AdapterMessageEmptyDate" xml:space="preserve">
<value>Данные пусты</value>
</data>
<data name="AdapterMessageIncorrectDatesException" xml:space="preserve">
<value>Неправильные даты: {0}</value>
</data>
<data name="AdapterMessageInvalidOperationException" xml:space="preserve">
<value>Ошибка при обработке данных: {0}</value>
</data>
<data name="AdapterMessageStorageException" xml:space="preserve">
<value>Ошибка при работе с хранилищем данных: {0}</value>
</data>
<data name="AdapterMessageValidationException" xml:space="preserve">
<value>Переданы неверные данные: {0}</value>
</data>
<data name="DocumentDocCaptionData" xml:space="preserve">
<value>Дата</value>
</data>
<data name="DocumentDocCaptionOldPrice" xml:space="preserve">
<value>Старая цена</value>
</data>
<data name="DocumentDocCaptionSoftware" 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="DocumentExcelCaptionSoftware" 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="DocumentPdfDiagramCaption" xml:space="preserve">
<value>Начисления</value>
</data>
<data name="DocumentPdfHeader" xml:space="preserve">
<value>Зарплатная ведомость</value>
</data>
<data name="DocumentPdfSubHeader" xml:space="preserve">
<value>за период с {0} по {1}</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="NotFoundDataMessage" xml:space="preserve">
<value>Не найдены данные</value>
</data>
<data name="ValidationExceptionMessageEmploymentDateAndBirthDate" xml:space="preserve">
<value>Дата трудоустройства не может быть раньше даты рождения ({0}, {1})</value>
</data>
<data name="ValidationExceptionMessageEmptyField" xml:space="preserve">
<value>Значение в поле {0} пусто</value>
</data>
<data name="ValidationExceptionMessageIncorrectEmail" xml:space="preserve">
<value>Значение в поле Email не является Email</value>
</data>
<data name="ValidationExceptionMessageIncorrectFIO" xml:space="preserve">
<value>Значение в поле ФИО не является ФИО</value>
</data>
<data name="ValidationExceptionMessageLessOrEqualZero" xml:space="preserve">
<value>Значение в поле {0} меньше или равно 0</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="ValidationExceptionMessageNoSoftwaresCount" xml:space="preserve">
<value>В запросе должно быть хотя бы одно ПО</value>
</data>
<data name="ValidationExceptionMessageNotAId" xml:space="preserve">
<value>Значение в поле {0} не является типом уникального идентификатора</value>
</data>
<data name="ValidationExceptionMessageNotInitialized" xml:space="preserve">
<value>Значение в поле {0} не проиницализировано</value>
</data>
</root>

View File

@@ -9,6 +9,28 @@
<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.Abstractions" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="SmallSoftwareDatabase" />
<InternalsVisibleTo Include="SmallSoftwareTests" />
<InternalsVisibleTo Include="SmallSoftwareBusinessLogic" />
<InternalsVisibleTo Include="SmallSoftwareWebApi" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</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>
</Project>

View File

@@ -2,7 +2,7 @@
namespace SmallSoftwareContracts.StoragesContracts;
public interface IManufacturerStorageContract
internal interface IManufacturerStorageContract
{
List<ManufacturerDataModel> GetList();
ManufacturerDataModel? GetElementById(string id);

View File

@@ -2,7 +2,7 @@
namespace SmallSoftwareContracts.StoragesContracts;
public interface IPostStorageContract
internal interface IPostStorageContract
{
List<PostDataModel> GetList();
List<PostDataModel> GetPostWithHistory(string postId);

View File

@@ -2,8 +2,10 @@
namespace SmallSoftwareContracts.StoragesContracts;
public interface IRequestStorageContract
internal interface IRequestStorageContract
{
Task<List<RequestDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct);
List<RequestDataModel> GetList(DateTime? startDate = null,
DateTime? endDate = null, string? workerId = null, string? softwareId = null);
RequestDataModel? GetElementById(string id);

View File

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

View File

@@ -7,8 +7,9 @@ using System.Threading.Tasks;
namespace SmallSoftwareContracts.StoragesContracts;
public interface ISoftwareStorageContract
internal interface ISoftwareStorageContract
{
Task<List<SoftwareHistoryDataModel>> GetListAsync(CancellationToken ct);
List<SoftwareDataModel> GetList(bool onlyActive = true, string? manufacturerId = null);
List<SoftwareHistoryDataModel> GetHistoryBySoftwareId(string softwareId);
SoftwareDataModel? GetElementById(string id);

View File

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace SmallSoftwareContracts.StoragesContracts;
public interface IWorkerStorageContract
internal interface IWorkerStorageContract
{
List<WorkerDataModel> GetList(bool onlyActive = true, string? postId =
null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime?
@@ -16,5 +16,6 @@ public interface IWorkerStorageContract
WorkerDataModel? GetElementByFIO(string fio);
void AddElement(WorkerDataModel workerDataModel);
void UpdElement(WorkerDataModel workerDataModel);
void DelElement(string id);
void DelElement(string id);
int GetWorkerTrend(DateTime fromPeriod, DateTime toPeriod);
}

View File

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

View File

@@ -1,8 +1,12 @@

using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.ViewModels;
public class PostViewModel
{
[AlternativeName("PostId")]
public required string Id { get; set; }
public required string PostName { get; set; }
public required string PostType { get; set; }

View File

@@ -1,4 +1,6 @@

using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.ViewModels;
public class RequestViewModel
@@ -6,6 +8,8 @@ public class RequestViewModel
public required string Id { get; set; }
public required string WorkerId { get; set; }
public required string WorkerFIO { get; set; }
[PostProcessing(ActionType = PostProcessingType.ToLocalTime)]
public DateTime RequestDate { get; set; }
public double Sum { get; set; }
public bool IsCancel { get; set; }

View File

@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.ViewModels;
public class SoftwareHistoryViewModel
{
[AlternativeName("SoftwareName")]
public required string SoftwareName { get; set; }
public double OldPrice { get; set; }
public DateTime ChangeDate { get; set; }

View File

@@ -0,0 +1,15 @@
using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareContracts.ViewModels;
public class WorkerSalaryByPeriodViewModel
{
public required string WorkerFIO { get; set; }
public double TotalSalary { get; set; }
[PostProcessing(ActionType = PostProcessingType.ToLocalTime)]
public DateTime FromPeriod { get; set; }
[PostProcessing(ActionType = PostProcessingType.ToLocalTime)]
public DateTime ToPeriod { get; set; }
}

View File

@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareContracts.Mapper;
using System.Text.Json;
namespace SmallSoftwareContracts.ViewModels;
public class WorkerViewModel
{
[AlternativeName("WorkerId")]
public required string Id { get; set; }
public required string FIO { get; set; }
public required string PostId { get; set; }
@@ -15,4 +15,13 @@ public class WorkerViewModel
public bool IsDeleted { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
[AlternativeName("ConfigurationModel")]
[PostProcessing(MappingCallMethodName = "ParseConfiguration")]
public required string Configuration { get; set; }
public string ParseConfiguration(PostConfiguration model) => JsonSerializer.Serialize(model, new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
});
}

View File

@@ -0,0 +1,13 @@
using SmallSoftwareContracts.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SmallSoftwareDatabase;
class DefaultConfigurationDatabase : IConfigurationDatabase
{
public string ConnectionString => "";
}

View File

@@ -1,40 +1,29 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SmallSoftwareDatabase.Implementations;
internal class ManufacturerStorageContract : IManufacturerStorageContract
internal class ManufacturerStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer) : IManufacturerStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(Manufacturer));
});
_mapper = new Mapper(config);
}
private readonly SmallSoftwareDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<ManufacturerDataModel> GetList()
{
try
{
return [.. _dbContext.Manufacturers.Select(x => _mapper.Map<ManufacturerDataModel>(x))];
return [.. _dbContext.Manufacturers.Select(x => CustomMapper.MapObject<ManufacturerDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public ManufacturerDataModel? GetElementById(string id)
@@ -42,12 +31,12 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
try
{
return
_mapper.Map<ManufacturerDataModel>(GetManufacturerById(id));
CustomMapper.MapObjectWithNull<ManufacturerDataModel>(GetManufacturerById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public ManufacturerDataModel? GetElementByName(string name)
@@ -55,12 +44,12 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
try
{
return
_mapper.Map<ManufacturerDataModel>(_dbContext.Manufacturers.FirstOrDefault(x => x.ManufacturerName == name));
CustomMapper.MapObjectWithNull<ManufacturerDataModel>(_dbContext.Manufacturers.FirstOrDefault(x => x.ManufacturerName == name));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public ManufacturerDataModel? GetElementByOldName(string name)
@@ -68,41 +57,46 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
try
{
return
_mapper.Map<ManufacturerDataModel>(_dbContext.Manufacturers.FirstOrDefault(x =>
CustomMapper.MapObjectWithNull<ManufacturerDataModel>(_dbContext.Manufacturers.FirstOrDefault(x =>
x.PrevManufacturerName == name ||
x.PrevPrevManufacturerName == name));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void AddElement(ManufacturerDataModel manufacturerDataModel)
{
try
{
_dbContext.Manufacturers.Add(_mapper.Map<Manufacturer>(manufacturerDataModel));
_dbContext.Manufacturers.Add(CustomMapper.MapObject<Manufacturer>(manufacturerDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name ==
"ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id",
manufacturerDataModel.Id);
throw new ElementExistsException("Id", manufacturerDataModel.Id, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "IX_Manufacturers_ManufacturerName" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("ManufacturerName",
manufacturerDataModel.ManufacturerName);
manufacturerDataModel.ManufacturerName, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "PK_Manufacturers" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", manufacturerDataModel.Id, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void UpdElement(ManufacturerDataModel manufacturerDataModel)
@@ -110,7 +104,7 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
try
{
var element = GetManufacturerById(manufacturerDataModel.Id) ??
throw new ElementNotFoundException(manufacturerDataModel.Id);
throw new ElementNotFoundException(manufacturerDataModel.Id, _localizer);
if (element.ManufacturerName !=
manufacturerDataModel.ManufacturerName)
{
@@ -133,12 +127,12 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("ManufacturerName",
manufacturerDataModel.ManufacturerName);
manufacturerDataModel.ManufacturerName, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void DelElement(string id)
@@ -146,7 +140,7 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
try
{
var element = GetManufacturerById(id) ?? throw new
ElementNotFoundException(id);
ElementNotFoundException(id, _localizer);
_dbContext.Manufacturers.Remove(element);
_dbContext.SaveChanges();
}
@@ -158,7 +152,7 @@ public ManufacturerStorageContract(SmallSoftwareDbContext dbContext)
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
private Manufacturer? GetManufacturerById(string id) =>

View File

@@ -1,55 +1,42 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
namespace SmallSoftwareDatabase.Implementations;
internal class PostStorageContract : IPostStorageContract
internal class PostStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer) : IPostStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
public PostStorageContract(SmallSoftwareDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<PostDataModel, Post>()
.ForMember(x => x.Id, x => x.Ignore())
.ForMember(x => x.PostId, x => x.MapFrom(src => src.Id))
.ForMember(x => x.IsActual, x => x.MapFrom(src => true))
.ForMember(x => x.ChangeDate, x => x.MapFrom(src => DateTime.UtcNow));
});
_mapper = new Mapper(config);
}
private readonly SmallSoftwareDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<PostDataModel> GetList()
{
try
{
return [.._dbContext.Posts.Select(x => _mapper.Map<PostDataModel>(x))];
return [.._dbContext.Posts.Select(x => CustomMapper.MapObject<PostDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public List<PostDataModel> GetPostWithHistory(string postId)
{
try
{
return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => _mapper.Map<PostDataModel>(x))];
return [.. _dbContext.Posts.Where(x => x.PostId == postId).Select(x => CustomMapper.MapObject<PostDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public PostDataModel? GetElementById(string id)
@@ -57,13 +44,13 @@ internal class PostStorageContract : IPostStorageContract
try
{
return
_mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostId == id &&
CustomMapper.MapObjectWithNull<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostId == id &&
x.IsActual));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public PostDataModel? GetElementByName(string name)
@@ -71,20 +58,20 @@ internal class PostStorageContract : IPostStorageContract
try
{
return
_mapper.Map<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostName ==
CustomMapper.MapObjectWithNull<PostDataModel>(_dbContext.Posts.FirstOrDefault(x => x.PostName ==
name && x.IsActual));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void AddElement(PostDataModel postDataModel)
{
try
{
_dbContext.Posts.Add(_mapper.Map<Post>(postDataModel));
_dbContext.Posts.Add(CustomMapper.MapObject<Post>(postDataModel));
_dbContext.SaveChanges();
}
catch (DbUpdateException ex) when (ex.InnerException is
@@ -92,18 +79,18 @@ internal class PostStorageContract : IPostStorageContract
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName",
postDataModel.PostName);
postDataModel.PostName, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "IX_Posts_PostId_IsActual" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostId", postDataModel.Id);
throw new ElementExistsException("PostId", postDataModel.Id, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void UpdElement(PostDataModel postDataModel)
@@ -114,15 +101,15 @@ internal class PostStorageContract : IPostStorageContract
try
{
var element = GetPostById(postDataModel.Id) ?? throw new
ElementNotFoundException(postDataModel.Id);
ElementNotFoundException(postDataModel.Id, _localizer);
if (!element.IsActual)
{
throw new
ElementDeletedException(postDataModel.Id);
ElementDeletedException(postDataModel.Id, _localizer);
}
element.IsActual = false;
_dbContext.SaveChanges();
var newElement = _mapper.Map<Post>(postDataModel);
var newElement = CustomMapper.MapObject<Post>(postDataModel);
_dbContext.Posts.Add(newElement);
_dbContext.SaveChanges();
transaction.Commit();
@@ -138,7 +125,7 @@ internal class PostStorageContract : IPostStorageContract
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("PostName",
postDataModel.PostName);
postDataModel.PostName, _localizer);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is
ElementNotFoundException)
@@ -149,7 +136,7 @@ internal class PostStorageContract : IPostStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void DelElement(string id)
@@ -157,10 +144,10 @@ internal class PostStorageContract : IPostStorageContract
try
{
var element = GetPostById(id) ?? throw new
ElementNotFoundException(id);
ElementNotFoundException(id, _localizer);
if (!element.IsActual)
{
throw new ElementDeletedException(id);
throw new ElementDeletedException(id, _localizer);
}
element.IsActual = false;
_dbContext.SaveChanges();
@@ -176,7 +163,7 @@ internal class PostStorageContract : IPostStorageContract
try
{
var element = GetPostById(id) ?? throw new
ElementNotFoundException(id);
ElementNotFoundException(id, _localizer);
element.IsActual = true;
_dbContext.SaveChanges();
}

View File

@@ -1,7 +1,10 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
@@ -9,29 +12,13 @@ namespace SmallSoftwareDatabase.Implementations;
internal class RequestStorageContract : IRequestStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
private readonly SmallSoftwareDbContext _dbContext;
private readonly IStringLocalizer<Messages> _localizer;
public RequestStorageContract(SmallSoftwareDbContext dbContext)
public RequestStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Manufacturer, ManufacturerDataModel>();
cfg.CreateMap<Software, SoftwareDataModel>();
cfg.CreateMap<Worker, WorkerDataModel>();
cfg.CreateMap<InstallationRequest, InstallationRequestDataModel>();
cfg.CreateMap<InstallationRequestDataModel, InstallationRequest>()
.ForMember(x => x.SoftwareId, x => x.MapFrom(src => src.SoftwareId));
cfg.CreateMap<Request, RequestDataModel>();
cfg.CreateMap<RequestDataModel, Request>()
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
.ForMember(x => x.InstallationRequests, x => x.MapFrom(src => src.Softwares))
.ForMember(x => x.Worker, x => x.Ignore())
.ForMember(dest => dest.RequestDate, opt => opt.MapFrom(src => src.RequestDate))
.ForMember(dest => dest.RequestDate, opt => opt.MapFrom(src => src.RequestDate));
});
_mapper = new Mapper(config);
_dbContext = dbContext;
_localizer = localizer;
}
public List<RequestDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? workerId = null, string? softwareId = null)
@@ -47,12 +34,12 @@ internal class RequestStorageContract : IRequestStorageContract
{
query = query.Where(x => x.InstallationRequests!.Any(y => y.SoftwareId == softwareId));
}
return [.. query.Select(x => _mapper.Map<RequestDataModel>(x))];
return [.. query.Select(x => CustomMapper.MapObject<RequestDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
@@ -60,12 +47,12 @@ internal class RequestStorageContract : IRequestStorageContract
{
try
{
return _mapper.Map<RequestDataModel>(GetRequestById(id));
return CustomMapper.MapObjectWithNull<RequestDataModel>(GetRequestById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
@@ -73,13 +60,13 @@ internal class RequestStorageContract : IRequestStorageContract
{
try
{
_dbContext.Requests.Add(_mapper.Map<Request>(requestDataModel));
_dbContext.Requests.Add(CustomMapper.MapObject<Request>(requestDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
@@ -87,11 +74,11 @@ internal class RequestStorageContract : IRequestStorageContract
{
try
{
var element = GetRequestById(id) ?? throw new ElementNotFoundException(id);
var element = GetRequestById(id) ?? throw new ElementNotFoundException(id, _localizer);
if (element.IsCancel)
{
throw new ElementDeletedException(id);
throw new ElementDeletedException(id, _localizer);
}
element.IsCancel = true;
@@ -105,7 +92,7 @@ internal class RequestStorageContract : IRequestStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
@@ -115,4 +102,20 @@ internal class RequestStorageContract : IRequestStorageContract
.Include(x => x.InstallationRequests)!
.ThenInclude(x => x.Software)
.FirstOrDefault(x => x.Id == id);
public async Task<List<RequestDataModel>> GetListAsync(DateTime startDate, DateTime endDate, CancellationToken ct)
{
try
{
return [.. await _dbContext.Requests
.Include(x => x.InstallationRequests)!.ThenInclude(x => x.Software)
.Where(x => x.RequestDate >= startDate && x.RequestDate < endDate).Select(x => CustomMapper.MapObject<RequestDataModel>(x)).ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
}

View File

@@ -1,28 +1,20 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
namespace SmallSoftwareDatabase.Implementations;
internal class SalaryStorageContract : ISalaryStorageContract
internal class SalaryStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer) : ISalaryStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
public SalaryStorageContract(SmallSoftwareDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Worker, WorkerDataModel>();
cfg.CreateMap<Salary, SalaryDataModel>();
cfg.CreateMap<SalaryDataModel, Salary>()
.ForMember(dest => dest.WorkerSalary, opt => opt.MapFrom(src => src.Salary));
});
_mapper = new Mapper(config);
}
private readonly SmallSoftwareDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null)
{
try
@@ -32,25 +24,38 @@ internal class SalaryStorageContract : ISalaryStorageContract
{
query = query.Where(x => x.WorkerId == workerId);
}
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
return [.. query.Select(x => CustomMapper.MapObject<SalaryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void AddElement(SalaryDataModel salaryDataModel)
{
try
{
_dbContext.Salaries.Add(_mapper.Map<Salary>(salaryDataModel));
_dbContext.Salaries.Add(CustomMapper.MapObject<Salary>(salaryDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
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.Worker).Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate).Select(x => CustomMapper.MapObject<SalaryDataModel>(x)).ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
}

View File

@@ -1,32 +1,37 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
namespace SmallSoftwareDatabase.Implementations;
internal class SoftwareStorageContract : ISoftwareStorageContract
internal class SoftwareStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer) : ISoftwareStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
public SoftwareStorageContract(SmallSoftwareDbContext dbContext)
private readonly SmallSoftwareDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public async Task<List<SoftwareHistoryDataModel>> GetListAsync(CancellationToken ct)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
try
{
cfg.CreateMap<Manufacturer, ManufacturerDataModel>();
cfg.CreateMap<Software, SoftwareDataModel>();
cfg.CreateMap<SoftwareDataModel, Software>()
.ForMember(x => x.IsDeleted, x => x.MapFrom(src => false));
cfg.CreateMap<SoftwareHistory, SoftwareHistoryDataModel>();
});
_mapper = new Mapper(config);
return [.. await _dbContext.SoftwareHistories.Include(x => x.Software).Select(x => CustomMapper.MapObject<SoftwareHistoryDataModel>(x)).ToListAsync(ct)];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex, _localizer);
}
}
public List<SoftwareDataModel> GetList(bool onlyActive = true, string?
manufacturerId = null)
public List<SoftwareDataModel> GetList(bool onlyActive = true, string? manufacturerId = null)
{
try
{
@@ -40,12 +45,12 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
query = query.Where(x => x.ManufacturerId ==
manufacturerId);
}
return [.. query.Select(x => _mapper.Map<SoftwareDataModel>(x))];
return [.. query.Select(x => CustomMapper.MapObject<SoftwareDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public List<SoftwareHistoryDataModel> GetHistoryBySoftwareId(string
@@ -55,24 +60,24 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
{
return [.. _dbContext.SoftwareHistories.Include(x => x.Software).Where(x => x.SoftwareId == softwareId)
.OrderByDescending(x => x.ChangeDate)
.Select(x => _mapper.Map<SoftwareHistoryDataModel>(x))];
.Select(x => CustomMapper.MapObject<SoftwareHistoryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public SoftwareDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<SoftwareDataModel>(GetSoftwareById(id));
return CustomMapper.MapObjectWithNull<SoftwareDataModel>(GetSoftwareById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public SoftwareDataModel? GetElementByName(string name)
@@ -80,39 +85,39 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
try
{
return
_mapper.Map<SoftwareDataModel>(_dbContext.Softwares.Include(x => x.Manufacturer).FirstOrDefault(x =>
CustomMapper.MapObjectWithNull<SoftwareDataModel>(_dbContext.Softwares.Include(x => x.Manufacturer).FirstOrDefault(x =>
x.SoftwareName == name && !x.IsDeleted));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void AddElement(SoftwareDataModel softwareDataModel)
{
try
{
_dbContext.Softwares.Add(_mapper.Map<Software>(softwareDataModel));
_dbContext.Softwares.Add(CustomMapper.MapObject<Software>(softwareDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name ==
"ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", softwareDataModel.Id);
throw new ElementExistsException("Id", softwareDataModel.Id, _localizer);
}
catch (DbUpdateException ex) when (ex.InnerException is
PostgresException { ConstraintName: "IX_Softwares_SoftwareName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("SoftwareName",
softwareDataModel.SoftwareName);
softwareDataModel.SoftwareName, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void UpdElement(SoftwareDataModel softwareDataModel)
@@ -123,7 +128,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
try
{
var element = GetSoftwareById(softwareDataModel.Id) ??
throw new ElementNotFoundException(softwareDataModel.Id);
throw new ElementNotFoundException(softwareDataModel.Id, _localizer);
if (element.Price != softwareDataModel.Price)
{
_dbContext.SoftwareHistories.Add(new
@@ -131,7 +136,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
{ SoftwareId = element.Id, OldPrice = element.Price });
_dbContext.SaveChanges();
}
_dbContext.Softwares.Update(_mapper.Map(softwareDataModel,
_dbContext.Softwares.Update(CustomMapper.MapObject(softwareDataModel,
element));
_dbContext.SaveChanges();
transaction.Commit();
@@ -147,7 +152,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("SoftwareName",
softwareDataModel.SoftwareName);
softwareDataModel.SoftwareName, _localizer);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is
ElementNotFoundException)
@@ -158,7 +163,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void DelElement(string id)
@@ -166,7 +171,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
try
{
var element = GetSoftwareById(id) ?? throw new
ElementNotFoundException(id);
ElementNotFoundException(id, _localizer);
element.IsDeleted = true;
_dbContext.SaveChanges();
}
@@ -178,7 +183,7 @@ internal class SoftwareStorageContract : ISoftwareStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
private Software? GetSoftwareById(string id) =>

View File

@@ -1,34 +1,19 @@
using AutoMapper;

using Microsoft.Extensions.Localization;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Mapper;
using SmallSoftwareContracts.Resources;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmallSoftwareDatabase.Models;
namespace SmallSoftwareDatabase.Implementations;
internal class WorkerStorageContract : IWorkerStorageContract
internal class WorkerStorageContract(SmallSoftwareDbContext dbContext, IStringLocalizer<Messages> localizer) : IWorkerStorageContract
{
private readonly SmallSoftwareDbContext _dbContext;
private readonly Mapper _mapper;
public WorkerStorageContract(SmallSoftwareDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src =>
src.PostId));
cfg.CreateMap<Worker, WorkerDataModel>();
cfg.CreateMap<WorkerDataModel, Worker>()
.ForMember(x => x.Post, x => x.Ignore());
});
_mapper = new Mapper(config);
}
private readonly SmallSoftwareDbContext _dbContext = dbContext;
private readonly IStringLocalizer<Messages> _localizer = localizer;
public List<WorkerDataModel> GetList(bool onlyActive = true, string? postId
= null, DateTime? fromBirthDate = null, DateTime? toBirthDate = null, DateTime?
fromEmploymentDate = null, DateTime? toEmploymentDate = null)
@@ -55,24 +40,24 @@ internal class WorkerStorageContract : IWorkerStorageContract
query = query.Where(x => x.EmploymentDate >=
fromEmploymentDate && x.EmploymentDate <= toEmploymentDate);
}
return [.. JoinPost(query).Select(x => _mapper.Map<WorkerDataModel>(x))];
return [.. JoinPost(query).Select(x => CustomMapper.MapObject<WorkerDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public WorkerDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<WorkerDataModel>(GetWorkerById(id));
return CustomMapper.MapObjectWithNull<WorkerDataModel>(GetWorkerById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public WorkerDataModel? GetElementByFIO(string fio)
@@ -80,30 +65,30 @@ internal class WorkerStorageContract : IWorkerStorageContract
try
{
return
_mapper.Map<WorkerDataModel>(AddPost(_dbContext.Workers.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)));
CustomMapper.MapObjectWithNull<WorkerDataModel>(AddPost(_dbContext.Workers.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void AddElement(WorkerDataModel workerDataModel)
{
try
{
_dbContext.Workers.Add(_mapper.Map<Worker>(workerDataModel));
_dbContext.Workers.Add(CustomMapper.MapObject<Worker>(workerDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("Id", workerDataModel.Id);
throw new ElementExistsException("Id", workerDataModel.Id, _localizer);
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void UpdElement(WorkerDataModel workerDataModel)
@@ -111,8 +96,8 @@ internal class WorkerStorageContract : IWorkerStorageContract
try
{
var element = GetWorkerById(workerDataModel.Id) ?? throw new
ElementNotFoundException(workerDataModel.Id);
_dbContext.Workers.Update(_mapper.Map(workerDataModel,
ElementNotFoundException(workerDataModel.Id, _localizer);
_dbContext.Workers.Update(CustomMapper.MapObject(workerDataModel,
element));
_dbContext.SaveChanges();
}
@@ -124,7 +109,7 @@ internal class WorkerStorageContract : IWorkerStorageContract
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
public void DelElement(string id)
@@ -132,29 +117,45 @@ internal class WorkerStorageContract : IWorkerStorageContract
try
{
var element = GetWorkerById(id) ?? throw new
ElementNotFoundException(id);
ElementNotFoundException(id, _localizer);
element.IsDeleted = true;
element.DateOfDelete = DateTime.UtcNow;
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
throw new StorageException(ex, _localizer);
}
}
private Worker? GetWorkerById(string id) =>
AddPost(_dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
private IQueryable<Worker> JoinPost(IQueryable<Worker> query)
=> query.GroupJoin(_dbContext.Posts.Where(x => x.IsActual), x =>
x.PostId, y => y.PostId, (x, y) => new { Worker = x, Post = y })
.SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) =>
x.Worker.AddPost(y));
private Worker? AddPost(Worker? worker)
=> worker?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId ==
worker.PostId && x.IsActual));
public int GetWorkerTrend(DateTime fromPeriod, DateTime toPeriod)
{
try
{
var countWorkersOnBegining = _dbContext.Workers.Count(x =>
x.EmploymentDate < fromPeriod && (!x.IsDeleted || x.DateOfDelete > fromPeriod));
var countWorkersOnEnding = _dbContext.Workers.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 Worker? GetWorkerById(string id) => AddPost(_dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
private IQueryable<Worker> JoinPost(IQueryable<Worker> query) => query.GroupJoin(_dbContext.Posts.Where(x => x.IsActual), x =>
x.PostId, y => y.PostId, (x, y) => new { Worker = x, Post = y }).SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) => x.Worker.AddPost(y));
private Worker? AddPost(Worker? worker) => worker?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == worker.PostId && x.IsActual));
}

View File

@@ -0,0 +1,338 @@
// <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 SmallSoftwareDatabase;
#nullable disable
namespace SmallSoftwareDatabase.Migrations
{
[DbContext(typeof(SmallSoftwareDbContext))]
[Migration("20250417140247_FirstMigration")]
partial class FirstMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.Property<string>("RequestId")
.HasColumnType("text");
b.Property<string>("SoftwareId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("RequestId", "SoftwareId");
b.HasIndex("SoftwareId");
b.ToTable("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ManufacturerName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevManufacturerName")
.HasColumnType("text");
b.Property<string>("PrevPrevManufacturerName")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ManufacturerName")
.IsUnique();
b.ToTable("Manufacturers");
});
modelBuilder.Entity("SmallSoftwareDatabase.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("SmallSoftwareDatabase.Models.Request", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("RequestDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Requests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("WorkerSalary")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("ManufacturerId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevPrevSoftwareName")
.HasColumnType("text");
b.Property<string>("PrevSoftwareName")
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.Property<string>("SoftwareName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("SoftwareType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ManufacturerId");
b.HasIndex("SoftwareName", "IsDeleted")
.IsUnique()
.HasFilter("\"IsDeleted\" = FALSE");
b.ToTable("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.Property<string>("SoftwareId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SoftwareId");
b.ToTable("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
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("Workers");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Request", "Request")
.WithMany("InstallationRequests")
.HasForeignKey("RequestId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("InstallationRequests")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Request");
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Requests")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Salaries")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Manufacturer", "Manufacturer")
.WithMany("Softwares")
.HasForeignKey("ManufacturerId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Manufacturer");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("SoftwareHistories")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Navigation("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.Navigation("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Navigation("InstallationRequests");
b.Navigation("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Navigation("Requests");
b.Navigation("Salaries");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,254 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SmallSoftwareDatabase.Migrations
{
/// <inheritdoc />
public partial class FirstMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Manufacturers",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
ManufacturerName = table.Column<string>(type: "text", nullable: false),
PrevManufacturerName = table.Column<string>(type: "text", nullable: true),
PrevPrevManufacturerName = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Manufacturers", 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: "Workers",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
FIO = 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_Workers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Softwares",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
SoftwareName = table.Column<string>(type: "text", nullable: false),
SoftwareType = table.Column<int>(type: "integer", nullable: false),
ManufacturerId = table.Column<string>(type: "text", nullable: false),
Price = table.Column<double>(type: "double precision", nullable: false),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false),
PrevSoftwareName = table.Column<string>(type: "text", nullable: true),
PrevPrevSoftwareName = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Softwares", x => x.Id);
table.ForeignKey(
name: "FK_Softwares_Manufacturers_ManufacturerId",
column: x => x.ManufacturerId,
principalTable: "Manufacturers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Requests",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
WorkerId = table.Column<string>(type: "text", nullable: false),
RequestDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
Email = table.Column<string>(type: "text", nullable: false),
Sum = table.Column<double>(type: "double precision", nullable: false),
IsCancel = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Requests", x => x.Id);
table.ForeignKey(
name: "FK_Requests_Workers_WorkerId",
column: x => x.WorkerId,
principalTable: "Workers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Salaries",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
WorkerId = table.Column<string>(type: "text", nullable: false),
WorkerSalary = table.Column<double>(type: "double precision", nullable: false),
SalaryDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Salaries", x => x.Id);
table.ForeignKey(
name: "FK_Salaries_Workers_WorkerId",
column: x => x.WorkerId,
principalTable: "Workers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SoftwareHistories",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
SoftwareId = 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_SoftwareHistories", x => x.Id);
table.ForeignKey(
name: "FK_SoftwareHistories_Softwares_SoftwareId",
column: x => x.SoftwareId,
principalTable: "Softwares",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "InstallationRequests",
columns: table => new
{
SoftwareId = table.Column<string>(type: "text", nullable: false),
RequestId = 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_InstallationRequests", x => new { x.RequestId, x.SoftwareId });
table.ForeignKey(
name: "FK_InstallationRequests_Requests_RequestId",
column: x => x.RequestId,
principalTable: "Requests",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InstallationRequests_Softwares_SoftwareId",
column: x => x.SoftwareId,
principalTable: "Softwares",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_InstallationRequests_SoftwareId",
table: "InstallationRequests",
column: "SoftwareId");
migrationBuilder.CreateIndex(
name: "IX_Manufacturers_ManufacturerName",
table: "Manufacturers",
column: "ManufacturerName",
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_Requests_WorkerId",
table: "Requests",
column: "WorkerId");
migrationBuilder.CreateIndex(
name: "IX_Salaries_WorkerId",
table: "Salaries",
column: "WorkerId");
migrationBuilder.CreateIndex(
name: "IX_SoftwareHistories_SoftwareId",
table: "SoftwareHistories",
column: "SoftwareId");
migrationBuilder.CreateIndex(
name: "IX_Softwares_ManufacturerId",
table: "Softwares",
column: "ManufacturerId");
migrationBuilder.CreateIndex(
name: "IX_Softwares_SoftwareName_IsDeleted",
table: "Softwares",
columns: new[] { "SoftwareName", "IsDeleted" },
unique: true,
filter: "\"IsDeleted\" = FALSE");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "InstallationRequests");
migrationBuilder.DropTable(
name: "Posts");
migrationBuilder.DropTable(
name: "Salaries");
migrationBuilder.DropTable(
name: "SoftwareHistories");
migrationBuilder.DropTable(
name: "Requests");
migrationBuilder.DropTable(
name: "Softwares");
migrationBuilder.DropTable(
name: "Workers");
migrationBuilder.DropTable(
name: "Manufacturers");
}
}
}

View File

@@ -0,0 +1,345 @@
// <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 SmallSoftwareDatabase;
#nullable disable
namespace SmallSoftwareDatabase.Migrations
{
[DbContext(typeof(SmallSoftwareDbContext))]
[Migration("20250417185242_ChangeFieldsInWorker")]
partial class ChangeFieldsInWorker
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.Property<string>("RequestId")
.HasColumnType("text");
b.Property<string>("SoftwareId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("RequestId", "SoftwareId");
b.HasIndex("SoftwareId");
b.ToTable("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ManufacturerName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevManufacturerName")
.HasColumnType("text");
b.Property<string>("PrevPrevManufacturerName")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ManufacturerName")
.IsUnique();
b.ToTable("Manufacturers");
});
modelBuilder.Entity("SmallSoftwareDatabase.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("SmallSoftwareDatabase.Models.Request", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("RequestDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Requests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("WorkerSalary")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("ManufacturerId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevPrevSoftwareName")
.HasColumnType("text");
b.Property<string>("PrevSoftwareName")
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.Property<string>("SoftwareName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("SoftwareType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ManufacturerId");
b.HasIndex("SoftwareName", "IsDeleted")
.IsUnique()
.HasFilter("\"IsDeleted\" = FALSE");
b.ToTable("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.Property<string>("SoftwareId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SoftwareId");
b.ToTable("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Configuration")
.IsRequired()
.HasColumnType("jsonb");
b.Property<DateTime?>("DateOfDelete")
.HasColumnType("timestamp without time zone");
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("Workers");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Request", "Request")
.WithMany("InstallationRequests")
.HasForeignKey("RequestId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("InstallationRequests")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Request");
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Requests")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Salaries")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Manufacturer", "Manufacturer")
.WithMany("Softwares")
.HasForeignKey("ManufacturerId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Manufacturer");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("SoftwareHistories")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Navigation("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.Navigation("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Navigation("InstallationRequests");
b.Navigation("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Navigation("Requests");
b.Navigation("Salaries");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SmallSoftwareDatabase.Migrations
{
/// <inheritdoc />
public partial class ChangeFieldsInWorker : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Configuration",
table: "Workers",
type: "jsonb",
nullable: false,
defaultValue: "{\"Rate\": 0, \"Type\": \"PostConfiguration\"}");
migrationBuilder.AddColumn<DateTime>(
name: "DateOfDelete",
table: "Workers",
type: "timestamp without time zone",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Configuration",
table: "Workers");
migrationBuilder.DropColumn(
name: "DateOfDelete",
table: "Workers");
}
}
}

View File

@@ -0,0 +1,342 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SmallSoftwareDatabase;
#nullable disable
namespace SmallSoftwareDatabase.Migrations
{
[DbContext(typeof(SmallSoftwareDbContext))]
partial class SmallSoftwareDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.Property<string>("RequestId")
.HasColumnType("text");
b.Property<string>("SoftwareId")
.HasColumnType("text");
b.Property<int>("Count")
.HasColumnType("integer");
b.Property<double>("Price")
.HasColumnType("double precision");
b.HasKey("RequestId", "SoftwareId");
b.HasIndex("SoftwareId");
b.ToTable("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("ManufacturerName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevManufacturerName")
.HasColumnType("text");
b.Property<string>("PrevPrevManufacturerName")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("ManufacturerName")
.IsUnique();
b.ToTable("Manufacturers");
});
modelBuilder.Entity("SmallSoftwareDatabase.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("SmallSoftwareDatabase.Models.Request", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsCancel")
.HasColumnType("boolean");
b.Property<DateTime>("RequestDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("Sum")
.HasColumnType("double precision");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Requests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("SalaryDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("WorkerId")
.IsRequired()
.HasColumnType("text");
b.Property<double>("WorkerSalary")
.HasColumnType("double precision");
b.HasKey("Id");
b.HasIndex("WorkerId");
b.ToTable("Salaries");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<bool>("IsDeleted")
.HasColumnType("boolean");
b.Property<string>("ManufacturerId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PrevPrevSoftwareName")
.HasColumnType("text");
b.Property<string>("PrevSoftwareName")
.HasColumnType("text");
b.Property<double>("Price")
.HasColumnType("double precision");
b.Property<string>("SoftwareName")
.IsRequired()
.HasColumnType("text");
b.Property<int>("SoftwareType")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("ManufacturerId");
b.HasIndex("SoftwareName", "IsDeleted")
.IsUnique()
.HasFilter("\"IsDeleted\" = FALSE");
b.ToTable("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("ChangeDate")
.HasColumnType("timestamp without time zone");
b.Property<double>("OldPrice")
.HasColumnType("double precision");
b.Property<string>("SoftwareId")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("SoftwareId");
b.ToTable("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<DateTime>("BirthDate")
.HasColumnType("timestamp without time zone");
b.Property<string>("Configuration")
.IsRequired()
.HasColumnType("jsonb");
b.Property<DateTime?>("DateOfDelete")
.HasColumnType("timestamp without time zone");
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("Workers");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.InstallationRequest", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Request", "Request")
.WithMany("InstallationRequests")
.HasForeignKey("RequestId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("InstallationRequests")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Request");
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Requests")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Salary", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Worker", "Worker")
.WithMany("Salaries")
.HasForeignKey("WorkerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Worker");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Manufacturer", "Manufacturer")
.WithMany("Softwares")
.HasForeignKey("ManufacturerId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Manufacturer");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.SoftwareHistory", b =>
{
b.HasOne("SmallSoftwareDatabase.Models.Software", "Software")
.WithMany("SoftwareHistories")
.HasForeignKey("SoftwareId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Software");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Manufacturer", b =>
{
b.Navigation("Softwares");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Request", b =>
{
b.Navigation("InstallationRequests");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Software", b =>
{
b.Navigation("InstallationRequests");
b.Navigation("SoftwareHistories");
});
modelBuilder.Entity("SmallSoftwareDatabase.Models.Worker", b =>
{
b.Navigation("Requests");
b.Navigation("Salaries");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -8,8 +8,6 @@ using System.Text;
using System.Threading.Tasks;
namespace SmallSoftwareDatabase.Models;
[AutoMap(typeof(ManufacturerDataModel), ReverseMap = true)]
internal class Manufacturer
{
public required string Id { get; set; }

View File

@@ -1,14 +1,27 @@
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Mapper;
using System.ComponentModel.DataAnnotations;
namespace SmallSoftwareDatabase.Models;
internal class Post
{
public string Id { get; set; } = Guid.NewGuid().ToString();
[Key]
public string Id { get; set; } = Guid.NewGuid().ToString();
[Required]
[AlternativeName("Id")]
public required string PostId { get; set; }
[Required]
public required string PostName { get; set; }
public PostType PostType { get; set; }
public double Salary { get; set; }
[DefaultValue(DefaultValue = true)]
public bool IsActual { get; set; }
[DefaultValue(FuncName = "UtcNow")]
public DateTime ChangeDate { get; set; }
}

View File

@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations.Schema;
using SmallSoftwareContracts.Mapper;
using System.ComponentModel.DataAnnotations.Schema;
namespace SmallSoftwareDatabase.Models;
@@ -13,5 +14,7 @@ internal class Request
public Worker? Worker { get; set; }
[ForeignKey("RequestId")]
[AlternativeName("Softwares")]
public List<InstallationRequest>? InstallationRequests { get; set; }
}

View File

@@ -1,9 +1,13 @@
namespace SmallSoftwareDatabase.Models;
using SmallSoftwareContracts.Mapper;
namespace SmallSoftwareDatabase.Models;
internal class Salary
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public required string WorkerId { get; set; }
public required string WorkerId { get; set; }
[AlternativeName("Salary")]
public double WorkerSalary { get; set; }
public DateTime SalaryDate { get; set; }
public Worker? Worker { get; set; }

View File

@@ -1,8 +1,12 @@
namespace SmallSoftwareDatabase.Models;
using System.ComponentModel.DataAnnotations;
namespace SmallSoftwareDatabase.Models;
internal class SoftwareHistory
{
[Key]
public string Id { get; set; } = Guid.NewGuid().ToString();
[Required]
public required string SoftwareId { get; set; }
public double OldPrice { get; set; }
public DateTime ChangeDate { get; set; } = DateTime.UtcNow;

View File

@@ -1,16 +1,23 @@
using AutoMapper;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareContracts.Mapper;
using System.ComponentModel.DataAnnotations.Schema;
namespace SmallSoftwareDatabase.Models;
[AutoMap(typeof(WorkerDataModel), ReverseMap = true)]
internal class Worker
{
[AlternativeName("WorkerId")]
public required string Id { get; set; }
public required string FIO { get; set; }
public required string PostId { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
public bool IsDeleted { get; set; }
[AlternativeName("ConfigurationModel")]
public required PostConfiguration Configuration { get; set; }
public DateTime? DateOfDelete { get; set; }
[NotMapped]
public Post? Post { get; set; }
[ForeignKey("WorkerId")]

View File

@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore.Design;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SmallSoftwareDatabase;
internal class SampleContextFactory : IDesignTimeDbContextFactory<SmallSoftwareDbContext>
{
public SmallSoftwareDbContext CreateDbContext(string[] args)
{
return new SmallSoftwareDbContext(new DefaultConfigurationDatabase());
}
}

View File

@@ -9,6 +9,11 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.3" />
</ItemGroup>

View File

@@ -1,5 +1,8 @@
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SmallSoftwareContracts.Infrastructure;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareDatabase.Models;
using System;
using System.Collections.Generic;
@@ -16,8 +19,6 @@ internal class SmallSoftwareDbContext : DbContext
public SmallSoftwareDbContext(IConfigurationDatabase configurationDatabase)
{
_configurationDatabase = configurationDatabase;
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
@@ -43,6 +44,11 @@ internal class SmallSoftwareDbContext : DbContext
.WithMany(e => e.Softwares)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<InstallationRequest>().HasKey(x => new { x.RequestId, x.SoftwareId });
modelBuilder.Entity<Worker>().Property(x => x.Configuration).HasColumnType("jsonb").HasConversion(
x => SerializePostConfiguration(x),
x => DeserialzePostConfiguration(x)
);
}
public DbSet<Manufacturer> Manufacturers { get; set; }
public DbSet<Post> Posts { get; set; }
@@ -52,4 +58,11 @@ internal class SmallSoftwareDbContext : DbContext
public DbSet<Request> Requests { get; set; }
public DbSet<InstallationRequest> InstallationRequests { get; set; }
public DbSet<Worker> Workers { get; set; }
private static string SerializePostConfiguration(PostConfiguration postConfiguration) => JsonConvert.SerializeObject(postConfiguration);
private static PostConfiguration DeserialzePostConfiguration(string jsonString) => JToken.Parse(jsonString).Value<string>("Type") switch
{
nameof(CashierPostConfiguration) => JsonConvert.DeserializeObject<CashierPostConfiguration>(jsonString)!,
nameof(SupervisorPostConfiguration) => JsonConvert.DeserializeObject<SupervisorPostConfiguration>(jsonString)!,
_ => JsonConvert.DeserializeObject<PostConfiguration>(jsonString)!
};
}

View File

@@ -5,6 +5,7 @@ using SmallSoftwareContracts.BusinessLogicsContracts;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
namespace SmallSoftwareTests.BusinessLogicsContractsTests;
@@ -18,7 +19,7 @@ internal class ManufacturerBusinessLogicContractTests
{
_manufacturerStorageContract = new
Mock<IManufacturerStorageContract>();
_manufacturerBusinessLogicContract = new ManufacturerBusinessLogicContract(_manufacturerStorageContract.Object, new Mock<ILogger>().Object);
_manufacturerBusinessLogicContract = new ManufacturerBusinessLogicContract(_manufacturerStorageContract.Object, StringLocalizerMockCreator.GetObject(), new Mock<ILogger>().Object);
}
[SetUp]
public void SetUp()
@@ -69,7 +70,7 @@ internal class ManufacturerBusinessLogicContractTests
{
//Arrange
_manufacturerStorageContract.Setup(x => x.GetList()).Throws(new
StorageException(new InvalidOperationException()));
StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.GetAllManufacturers(),
@@ -186,10 +187,10 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_manufacturerStorageContract.Setup(x =>
x.GetElementByName(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.GetManufacturerByData(Guid.NewGuid().ToString(
@@ -212,7 +213,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.GetElementByOldName(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.GetManufacturerByData("name"),
@@ -249,7 +250,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.AddElement(It.IsAny<ManufacturerDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.InsertManufacturer(new(Guid.NewGuid().ToString
@@ -284,7 +285,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.AddElement(It.IsAny<ManufacturerDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.InsertManufacturer(new(Guid.NewGuid().ToString
@@ -320,7 +321,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<ManufacturerDataModel>())).Throws(new
ElementNotFoundException(""));
ElementNotFoundException("", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.UpdateManufacturer(new(Guid.NewGuid().ToString
@@ -334,7 +335,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<ManufacturerDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.UpdateManufacturer(new(Guid.NewGuid().ToString
@@ -369,7 +370,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<ManufacturerDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.UpdateManufacturer(new(Guid.NewGuid().ToString
@@ -398,7 +399,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
var id = Guid.NewGuid().ToString();
_manufacturerStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id));
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.DeleteManufacturer(Guid.NewGuid().ToString()),
@@ -435,7 +436,7 @@ internal class ManufacturerBusinessLogicContractTests
//Arrange
_manufacturerStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_manufacturerBusinessLogicContract.DeleteManufacturer(Guid.NewGuid().ToString()),

View File

@@ -5,6 +5,7 @@ using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -23,7 +24,7 @@ internal class PostBusinessLogicContractTests
{
_postStorageContract = new Mock<IPostStorageContract>();
_postBusinessLogicContract = new
PostBusinessLogicContract(_postStorageContract.Object, new
PostBusinessLogicContract(_postStorageContract.Object, StringLocalizerMockCreator.GetObject(), new
Mock<ILogger>().Object);
}
[SetUp]
@@ -90,7 +91,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.GetList()).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.GetAllPosts(),
@@ -170,7 +171,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.GetPostWithHistory(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.GetAllDataOfPost(Guid.NewGuid().ToString()),
@@ -254,10 +255,10 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_postStorageContract.Setup(x =>
x.GetElementByName(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.GetPostByData(Guid.NewGuid().ToString()),
@@ -296,7 +297,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.AddElement(It.IsAny<PostDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.InsertPost(new(Guid.NewGuid().ToString(), "name",
@@ -330,7 +331,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.AddElement(It.IsAny<PostDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.InsertPost(new(Guid.NewGuid().ToString(), "name",
@@ -366,7 +367,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.UpdElement(It.IsAny<PostDataModel>())).Throws(new
ElementNotFoundException(""));
ElementNotFoundException("", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.UpdatePost(new(Guid.NewGuid().ToString(), "name",
@@ -381,7 +382,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.UpdElement(It.IsAny<PostDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.UpdatePost(new(Guid.NewGuid().ToString(), "anme",
@@ -415,7 +416,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.UpdElement(It.IsAny<PostDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.UpdatePost(new(Guid.NewGuid().ToString(), "name",
@@ -445,7 +446,7 @@ internal class PostBusinessLogicContractTests
//Arrange
var id = Guid.NewGuid().ToString();
_postStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id));
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.DeletePost(Guid.NewGuid().ToString()),
@@ -480,7 +481,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.DeletePost(Guid.NewGuid().ToString()),
@@ -509,7 +510,7 @@ internal class PostBusinessLogicContractTests
//Arrange
var id = Guid.NewGuid().ToString();
_postStorageContract.Setup(x =>
x.ResElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id));
x.ResElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.RestorePost(Guid.NewGuid().ToString()),
@@ -544,7 +545,7 @@ internal class PostBusinessLogicContractTests
//Arrange
_postStorageContract.Setup(x =>
x.ResElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_postBusinessLogicContract.RestorePost(Guid.NewGuid().ToString()),

View File

@@ -0,0 +1,503 @@
using Microsoft.Extensions.Logging;
using Moq;
using SmallSoftwareBusinessLogic.Implementations;
using SmallSoftwareBusinessLogic.OfficePackage;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
namespace SmallSoftwareTests.BusinessLogicsContractsTests;
[TestFixture]
internal class ReportContractTests
{
private ReportContract _reportContract;
private Mock<ISoftwareStorageContract> _softwareStorageContract;
private Mock<IRequestStorageContract> _requestStorageContract;
private Mock<ISalaryStorageContract> _salaryStorageContract;
private Mock<BaseWordBuilder> _baseWordBuilder;
private Mock<BaseExcelBuilder> _baseExcelBuilder;
private Mock<BasePdfBuilder> _basePdfBuilder;
[OneTimeSetUp]
public void OneTimeSetUp()
{
_softwareStorageContract = new Mock<ISoftwareStorageContract>();
_requestStorageContract = new Mock<IRequestStorageContract>();
_salaryStorageContract = new Mock<ISalaryStorageContract>();
_baseWordBuilder = new Mock<BaseWordBuilder>();
_baseExcelBuilder = new Mock<BaseExcelBuilder>();
_basePdfBuilder = new Mock<BasePdfBuilder>();
_reportContract = new ReportContract(_softwareStorageContract.Object, _requestStorageContract.Object, _salaryStorageContract.Object, _baseWordBuilder.Object, _baseExcelBuilder.Object, _basePdfBuilder.Object, StringLocalizerMockCreator.GetObject(), new Mock<ILogger>().Object);
}
[SetUp]
public void SetUp()
{
_softwareStorageContract.Reset();
_requestStorageContract.Reset();
_salaryStorageContract.Reset();
}
[Test]
public async Task GetDataSoftwaresByManufacturer_ShouldSuccess_Test()
{
//Arrange
var manufacturer1 = new ManufacturerDataModel(Guid.NewGuid().ToString(), "name1");
var manufacturer2 = new ManufacturerDataModel(Guid.NewGuid().ToString(), "name2");
var softwareId1 = Guid.NewGuid().ToString();
var softwareId2 = Guid.NewGuid().ToString();
var software1 = new SoftwareDataModel(softwareId1, "name1", SoftwareType.AudioDriver, manufacturer1.Id, 10, false);
var software2 = new SoftwareDataModel(softwareId2, "name2", SoftwareType.AudioDriver, manufacturer2.Id, 10, false);
_softwareStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(new List<SoftwareHistoryDataModel>()
{
new(softwareId1, 22, DateTime.UtcNow, software1),
new(softwareId2, 21, DateTime.UtcNow, software2),
new(softwareId1, 33, DateTime.UtcNow, software1),
new(softwareId1, 32, DateTime.UtcNow, software1),
new(softwareId2, 65, DateTime.UtcNow, software2)
}));
//Act
var data = await _reportContract.GetDataSoftwaresByHistoryAsync(CancellationToken.None);
//Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(2));
Assert.Multiple(() =>
{
Assert.That(data.First(x => x.SoftwareName == software1.SoftwareName).Histories, Has.Count.EqualTo(3));
Assert.That(data.First(x => x.SoftwareName == software2.SoftwareName).Histories, Has.Count.EqualTo(2));
});
_softwareStorageContract.Verify(x => x.GetListAsync(It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetDataSoftwaresByHistory_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
_softwareStorageContract.Setup(x =>
x.GetListAsync(It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(new List<SoftwareHistoryDataModel>()));
//Act
var data = await _reportContract.GetDataSoftwaresByHistoryAsync(CancellationToken.None);
//Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
_softwareStorageContract.Verify(x =>
x.GetListAsync(It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public void GetDataSoftwaresByHistory_WhenStorageThrowError_ShouldFail_Test()
{
//Arrange
_softwareStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>())).Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(async () => await _reportContract.GetDataSoftwaresByHistoryAsync(CancellationToken.None), Throws.TypeOf<StorageException>());
_softwareStorageContract.Verify(x => x.GetListAsync(It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task CreateDocumentSoftwaresByHistory_ShouldeSuccess_Test()
{
//Arrange
var manufacturer1 = new
ManufacturerDataModel(Guid.NewGuid().ToString(), "name1");
var manufacturer2 = new
ManufacturerDataModel(Guid.NewGuid().ToString(), "name2");
var softwareId1 = Guid.NewGuid().ToString();
var softwareId2 = Guid.NewGuid().ToString();
var software1 = new SoftwareDataModel(softwareId1, "name1", SoftwareType.AudioDriver, manufacturer1.Id, 10, false);
var software2 = new SoftwareDataModel(softwareId2, "name2", SoftwareType.AudioDriver, manufacturer2.Id, 10, false);
var histories = new List<SoftwareHistoryDataModel>()
{
new(softwareId1, 22, DateTime.UtcNow, software1),
new(softwareId1, 33, DateTime.UtcNow, software1),
new(softwareId1, 32, DateTime.UtcNow, software1),
new(softwareId2, 21, DateTime.UtcNow, software2),
new(softwareId2, 65, DateTime.UtcNow, software2)
};
_softwareStorageContract.Setup(x => x.GetListAsync(It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(histories));
_baseWordBuilder.Setup(x => x.AddHeader(It.IsAny<string>())).Returns(_baseWordBuilder.Object);
_baseWordBuilder.Setup(x => x.AddParagraph(It.IsAny<string>())).Returns(_baseWordBuilder.Object);
var countRows = 0;
string[] firstRow = [];
string[] secondRow = [];
_baseWordBuilder.Setup(x => x.AddTable(It.IsAny<int[]>(),
It.IsAny<List<string[]>>()))
.Callback((int[] widths, List<string[]> data) =>
{
countRows = data.Count;
if (data.Count > 0) firstRow = data[0];
if (data.Count > 1) secondRow = data[1];
})
.Returns(_baseWordBuilder.Object);
// Act
var data = await _reportContract.CreateDocumentSoftwaresByHistoryAsync(CancellationToken.None);
// Assert
_softwareStorageContract.Verify(x => x.GetListAsync(It.IsAny<CancellationToken>()), Times.Once);
_baseWordBuilder.Verify(x => x.AddHeader(It.IsAny<string>()), Times.Once);
_baseWordBuilder.Verify(x => x.AddParagraph(It.IsAny<string>()), Times.Once);
_baseWordBuilder.Verify(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>()), Times.Once);
_baseWordBuilder.Verify(x => x.Build(), Times.Once);
Assert.Multiple(() =>
{
Assert.That(countRows, Is.EqualTo(8));
Assert.That(firstRow, Has.Length.EqualTo(3));
Assert.That(secondRow, Has.Length.EqualTo(3));
});
}
[Test]
public async Task GetDataByRequestsByPeriod_ShouldSuccess_Test()
{
//Arrange
_requestStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<RequestDataModel>()
{
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, [new InstallationRequestDataModel("", Guid.NewGuid().ToString(), 10, 10)], DateTime.UtcNow),
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, [new InstallationRequestDataModel("", Guid.NewGuid().ToString(), 10, 10)], DateTime.UtcNow)
}));
//Act
var data = await
_reportContract.GetDataRequestByPeriodAsync(DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow, CancellationToken.None);
//Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(2));
_requestStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetDataByRequestsByPeriod_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
_requestStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new
List<RequestDataModel>()));
//Act
var data = await
_reportContract.GetDataRequestByPeriodAsync(DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow, CancellationToken.None);
//Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
_requestStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public void GetDataByRequestsByPeriod_WhenIncorrectDates_ShouldFail_Test()
{
//Arrange
var date = DateTime.UtcNow;
//Act&Assert
Assert.That(async () => await
_reportContract.GetDataRequestByPeriodAsync(date, date, CancellationToken.None),
Throws.TypeOf<IncorrectDatesException>());
Assert.That(async () => await
_reportContract.GetDataRequestByPeriodAsync(date, DateTime.UtcNow.AddDays(-1),
CancellationToken.None), Throws.TypeOf<IncorrectDatesException>());
}
[Test]
public void GetDataByRequestsByPeriod_WhenStorageThrowError_ShouldFail_Test()
{
//Arrange
_requestStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>())).Throws(new
StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(async () => await
_reportContract.GetDataRequestByPeriodAsync(DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow, CancellationToken.None), Throws.TypeOf<StorageException>());
_requestStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetDataSalaryByPeriod_ShouldSuccess_Test()
{
// Arrange
var startDate = DateTime.UtcNow.AddDays(-20);
var endDate = DateTime.UtcNow.AddDays(5);
var worker1 = new WorkerDataModel(
Guid.NewGuid().ToString(),
"fio 1",
Guid.NewGuid().ToString(),
DateTime.UtcNow.AddYears(-20),
DateTime.UtcNow.AddDays(-3));
var worker2 = new WorkerDataModel(
Guid.NewGuid().ToString(),
"fio 2",
Guid.NewGuid().ToString(),
DateTime.UtcNow.AddYears(-20),
DateTime.UtcNow.AddDays(-3));
_salaryStorageContract.Setup(x =>
x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<SalaryDataModel>()
{
new(worker1.Id, DateTime.UtcNow.AddDays(-10), 100),
new(worker1.Id, endDate, 1000),
new(worker1.Id, startDate, 1000),
new(worker2.Id, DateTime.UtcNow.AddDays(-10), 100),
new(worker2.Id, DateTime.UtcNow.AddDays(-5), 200)
});
// Act
var data = await _reportContract.GetDataSalaryByPeriodAsync(
DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow,
CancellationToken.None);
// Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(1));
var totalSalary = data.First();
Assert.Multiple(() =>
{
Assert.That(totalSalary, Is.Not.Null);
Assert.That(totalSalary.TotalSalary, Is.EqualTo(2400));
});
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetDataSalaryByPeriod_WhenNoRecords_ShouldSuccess_Test()
{
// Arrange
_salaryStorageContract.Setup(x =>
x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<SalaryDataModel>());
// Act
var data = await _reportContract.GetDataSalaryByPeriodAsync(
DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow,
CancellationToken.None);
// Assert
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
_salaryStorageContract.Verify(x =>
x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()),
Times.Once);
}
[Test]
public void GetDataSalaryByPeriod_WhenIncorrectDates_ShouldFail_Test()
{
// Arrange
var date = DateTime.UtcNow;
// Act & Assert
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(
date, date, CancellationToken.None),
Throws.TypeOf<IncorrectDatesException>());
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(
date, DateTime.UtcNow.AddDays(-1), CancellationToken.None),
Throws.TypeOf<IncorrectDatesException>());
}
[Test]
public void GetDataBySalaryByPeriod_WhenStorageThrowError_ShouldFail_Test()
{
// Arrange
_salaryStorageContract.Setup(x =>
x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ThrowsAsync(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
// Act & Assert
Assert.That(async () => await _reportContract.GetDataSalaryByPeriodAsync(
DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow,
CancellationToken.None),
Throws.TypeOf<StorageException>());
_salaryStorageContract.Verify(x =>
x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()),
Times.Once);
}
[Test]
public async Task CreateDocumentRequestsByPeriod_ShouldSuccess_Test()
{
// Arrange
var manufacturer1 = new ManufacturerDataModel(Guid.NewGuid().ToString(), "name1");
var software1 = new SoftwareDataModel(Guid.NewGuid().ToString(), "name1", SoftwareType.Windows, manufacturer1.Id, 10, false);
var software2 = new SoftwareDataModel(Guid.NewGuid().ToString(), "name2", SoftwareType.Windows, manufacturer1.Id, 10, false);
_requestStorageContract.Setup(x => x.GetListAsync(
It.IsAny<DateTime>(),
It.IsAny<DateTime>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<RequestDataModel>()
{
new(Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
"test@mail.ru",
false,
new List<InstallationRequestDataModel>() {
new("", software1.Id, 10, 10, software1),
new("", software2.Id, 10, 10, software2)
}, DateTime.UtcNow.AddDays(-1)),
new(Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
"qwerty@gmail.ru",
false,
new List<InstallationRequestDataModel>()
{
new("", software2.Id, 10, 10, software2)
}, DateTime.UtcNow.AddDays(-1))
});
_baseExcelBuilder.Setup(x => x.AddHeader(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>()))
.Returns(_baseExcelBuilder.Object);
_baseExcelBuilder.Setup(x => x.AddParagraph(It.IsAny<string>(), It.IsAny<int>()))
.Returns(_baseExcelBuilder.Object);
var countRows = 0;
string[] headerRow = Array.Empty<string>();
string[] firstDataRow = Array.Empty<string>();
string[] firstSoftwareRow = Array.Empty<string>();
_baseExcelBuilder.Setup(x => x.AddTable(It.IsAny<int[]>(), It.IsAny<List<string[]>>()))
.Callback((int[] widths, List<string[]> data) =>
{
countRows = data.Count;
headerRow = data[0];
firstDataRow = data[1];
firstSoftwareRow = data[2];
})
.Returns(_baseExcelBuilder.Object);
// Act
var result = await _reportContract.CreateDocumentRequestsByPeriodAsync(
DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow,
CancellationToken.None);
// Assert
Assert.Multiple(() =>
{
Assert.That(countRows, Is.EqualTo(7));
Assert.That(headerRow, Is.Not.Empty);
Assert.That(firstDataRow, Is.Not.Empty);
Assert.That(firstSoftwareRow, Is.Not.Empty);
});
Assert.Multiple(() =>
{
Assert.That(headerRow[0], Is.EqualTo("Дата"));
Assert.That(headerRow[1], Is.EqualTo("Email"));
Assert.That(headerRow[2], Is.EqualTo("Сумма"));
Assert.That(headerRow[3], Is.EqualTo("ПО"));
Assert.That(headerRow[4], Is.EqualTo("Количество"));
Assert.That(firstDataRow[0], Is.EqualTo(DateTime.UtcNow.ToString("dd.MM.yyyy")));
Assert.That(firstDataRow[1], Is.EqualTo("test@mail.ru"));
Assert.That(firstDataRow[2], Is.EqualTo(200.ToString("N2")));
Assert.That(firstDataRow[3], Is.Empty);
Assert.That(firstDataRow[4], Is.Empty);
Assert.That(firstSoftwareRow[0], Is.Empty);
Assert.That(firstSoftwareRow[1], Is.Empty);
Assert.That(firstSoftwareRow[2], Is.Empty);
Assert.That(firstSoftwareRow[3], Is.EqualTo(software1.SoftwareName));
Assert.That(firstSoftwareRow[4], Is.EqualTo(10.ToString("N2")));
});
_requestStorageContract.Verify(x => x.GetListAsync(
It.IsAny<DateTime>(),
It.IsAny<DateTime>(),
It.IsAny<CancellationToken>()), Times.Once);
_baseExcelBuilder.Verify(x => x.AddHeader(
It.IsAny<string>(),
It.IsAny<int>(),
It.IsAny<int>()), Times.Once);
_baseExcelBuilder.Verify(x => x.AddParagraph(
It.IsAny<string>(),
It.IsAny<int>()), Times.Once);
_baseExcelBuilder.Verify(x => x.AddTable(
It.IsAny<int[]>(),
It.IsAny<List<string[]>>()), Times.Once);
_baseExcelBuilder.Verify(x => x.Build(), Times.Once);
}
[Test]
public async Task CreateDocumentSalaryByPeriod_ShouldeSuccess_Test()
{
//Arrange
var startDate = DateTime.UtcNow.AddDays(-20);
var endDate = DateTime.UtcNow.AddDays(5);
var worker1 = new WorkerDataModel(Guid.NewGuid().ToString(), "fio 1", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3));
var worker2 = new WorkerDataModel(Guid.NewGuid().ToString(), "fio 2", Guid.NewGuid().ToString(), DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddDays(-3));
_salaryStorageContract.Setup(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<SalaryDataModel>()
{
new(worker1.Id, DateTime.UtcNow.AddDays(-10), 100, worker1),
new(worker1.Id, endDate, 1000, worker1),
new(worker1.Id, startDate, 1000, worker1),
new(worker2.Id, DateTime.UtcNow.AddDays(-10), 100, worker2),
new(worker2.Id, DateTime.UtcNow.AddDays(-5), 200, worker2)
}));
_basePdfBuilder.Setup(x => x.AddHeader(It.IsAny<string>())).Returns(_basePdfBuilder.Object);
_basePdfBuilder.Setup(x => x.AddParagraph(It.IsAny<string>())).Returns(_basePdfBuilder.Object);
var countRows = 0;
(string, double) firstRow = default;
(string, double) secondRow = default;
_basePdfBuilder.Setup(x => x.AddPieChart(It.IsAny<string>(), It.IsAny<List<(string, double)>>())).Callback((string header, List<(string, double)> data) =>
{
countRows = data.Count;
firstRow = data[0];
secondRow = data[1];
}).Returns(_basePdfBuilder.Object);
//Act
var data = await _reportContract.CreateDocumentSalaryByPeriodAsync(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, CancellationToken.None);
//Assert
Assert.Multiple(() =>
{
Assert.That(countRows, Is.EqualTo(2));
Assert.That(firstRow, Is.Not.EqualTo(default));
Assert.That(secondRow, Is.Not.EqualTo(default));
});
Assert.Multiple(() =>
{
Assert.That(firstRow.Item1, Is.EqualTo(worker1.FIO));
Assert.That(firstRow.Item2, Is.EqualTo(2100));
Assert.That(secondRow.Item1, Is.EqualTo(worker2.FIO));
Assert.That(secondRow.Item2, Is.EqualTo(300));
});
_salaryStorageContract.Verify(x => x.GetListAsync(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()), Times.Once);
_basePdfBuilder.Verify(x => x.AddHeader(It.IsAny<string>()), Times.Once);
_basePdfBuilder.Verify(x => x.AddParagraph(It.IsAny<string>()), Times.Once);
_basePdfBuilder.Verify(x => x.AddPieChart(It.IsAny<string>(), It.IsAny<List<(string, double)>>()), Times.Once);
_basePdfBuilder.Verify(x => x.Build(), Times.Once);
}
}

View File

@@ -4,6 +4,7 @@ using SmallSoftwareBusinessLogic.Implementations;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
namespace SmallSoftwareTests.BusinessLogicsContractsTests;
@@ -19,7 +20,7 @@ internal class RequestBusinessLogicContractTests
{
_requestStorageContract = new Mock<IRequestStorageContract>();
_requestBusinessLogicContract = new
RequestBusinessLogicContract(_requestStorageContract.Object, new
RequestBusinessLogicContract(_requestStorageContract.Object, StringLocalizerMockCreator.GetObject(), new
Mock<ILogger>().Object);
}
[SetUp]
@@ -96,7 +97,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<string>(), It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.GetAllRequestsByPeriod(DateTime.UtcNow,
@@ -211,7 +212,7 @@ internal class RequestBusinessLogicContractTests
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<string>(),
It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.GetAllRequestsByWorkerByPeriod(Guid.NewGuid().ToString(),
@@ -328,7 +329,7 @@ internal class RequestBusinessLogicContractTests
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<string>(),
It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.GetAllRequestsBySoftwareByPeriod(Guid.NewGuid().ToString()
@@ -391,7 +392,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
_requestStorageContract.Setup(x =>
x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.GetRequestByData(Guid.NewGuid().ToString()),
@@ -431,7 +432,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
_requestStorageContract.Setup(x =>
x.AddElement(It.IsAny<RequestDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false,
@@ -461,7 +462,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
_requestStorageContract.Setup(x =>
x.AddElement(It.IsAny<RequestDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)], DateTime.UtcNow)), Throws.TypeOf<StorageException>());
@@ -489,7 +490,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
var id = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id));
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.CancelRequest(Guid.NewGuid().ToString()),
@@ -524,7 +525,7 @@ internal class RequestBusinessLogicContractTests
//Arrange
_requestStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_requestBusinessLogicContract.CancelRequest(Guid.NewGuid().ToString()),

View File

@@ -4,7 +4,10 @@ using SmallSoftwareBusinessLogic.Implementations;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareDatabase.Implementations;
using SmallSoftwareTests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -20,7 +23,8 @@ internal class SalaryBusinessLogicContractTests
private Mock<ISalaryStorageContract> _salaryStorageContract;
private Mock<IRequestStorageContract> _requestStorageContract;
private Mock<IPostStorageContract> _postStorageContract;
private Mock<IWorkerStorageContract> _workerStorageContract;
private Mock<IWorkerStorageContract> _workerStorageContract;
private readonly ConfigurationSalaryTest _salaryConfigurationTest = new();
[OneTimeSetUp]
public void OneTimeSetUp()
{
@@ -28,10 +32,8 @@ internal class SalaryBusinessLogicContractTests
_requestStorageContract = new Mock<IRequestStorageContract>();
_postStorageContract = new Mock<IPostStorageContract>();
_workerStorageContract = new Mock<IWorkerStorageContract>();
_salaryBusinessLogicContract = new
SalaryBusinessLogicContract(_salaryStorageContract.Object,
_requestStorageContract.Object, _postStorageContract.Object,
_workerStorageContract.Object, new Mock<ILogger>().Object);
_salaryBusinessLogicContract = new SalaryBusinessLogicContract(_salaryStorageContract.Object, _requestStorageContract.Object,
_postStorageContract.Object, _workerStorageContract.Object, StringLocalizerMockCreator.GetObject(), new Mock<ILogger>().Object, _salaryConfigurationTest);
}
[SetUp]
public void SetUp()
@@ -113,7 +115,7 @@ internal class SalaryBusinessLogicContractTests
//Arrange
_salaryStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.GetAllSalariesByPeriod(DateTime.UtcNow,
@@ -222,7 +224,7 @@ internal class SalaryBusinessLogicContractTests
//Arrange
_salaryStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.GetAllSalariesByPeriodByWorker(DateTime.UtcNow,
@@ -233,198 +235,347 @@ internal class SalaryBusinessLogicContractTests
}
[Test]
public void CalculateSalaryByMounth_WithSeveralWorkers_Test()
public void CalculateSalaryByMonth_CalculateSalary_Test()
{
//Arrange
var worker1Id = Guid.NewGuid().ToString();
var worker2Id = Guid.NewGuid().ToString();
var worker3Id = Guid.NewGuid().ToString();
var list = new List<WorkerDataModel>() {
new(worker1Id, "Test", Guid.NewGuid().ToString(),
DateTime.UtcNow, DateTime.UtcNow, false),
new(worker2Id, "Test", Guid.NewGuid().ToString(),
DateTime.UtcNow, DateTime.UtcNow, false),
new(worker3Id, "Test", Guid.NewGuid().ToString(),
DateTime.UtcNow, DateTime.UtcNow, false)
};
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
worker1Id, Guid.NewGuid().ToString(), false, [], DateTime.UtcNow),
new RequestDataModel(Guid.NewGuid().ToString(), worker1Id, Guid.NewGuid().ToString(),
false, [], DateTime.UtcNow),
new RequestDataModel(Guid.NewGuid().ToString(), worker2Id, Guid.NewGuid().ToString(),
false, [], DateTime.UtcNow),
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
false, [], DateTime.UtcNow),
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
false, [], DateTime.UtcNow)]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, 2000));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns(list);
//Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
//Assert
_salaryStorageContract.Verify(x =>
x.AddElement(It.IsAny<SalaryDataModel>()), Times.Exactly(list.Count));
}
[Test]
public void CalculateSalaryByMounth_WithoitRequestsByWorker_Test()
{
//Arrange
var postSalary = 2000.0;
// Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, postSalary));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test",
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
var sum = 0.0;
var expectedSum = postSalary;
_salaryStorageContract.Setup(x =>
x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
sum = x.Salary;
});
//Act
var postId = Guid.NewGuid().ToString();
var rate = 1000.0;
// Настраиваем моки
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "TestPost", PostType.CashierConsultant, rate));
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(),
It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "emmmail@mail.ru", false,
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)], DateTime.UtcNow)]);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = rate })]);
double actualSum = 0;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>())).Callback((SalaryDataModel x) => actualSum = x.Salary);
// Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
//Assert
// Assert
Assert.That(actualSum, Is.EqualTo(rate));
}
[Test]
public void CalculateSalaryByMonth_WithSeveralWorkers_Test()
{
// Arrange
var postId = Guid.NewGuid().ToString();
var rate = 1000.0;
// Настраиваем мок для PostStorage
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, rate));
var workers = new List<WorkerDataModel>
{
new(Guid.NewGuid().ToString(), "Test1", postId, DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1), false, new PostConfiguration { Rate = rate }),
new(Guid.NewGuid().ToString(), "Test2", postId, DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1), false, new PostConfiguration { Rate = rate }),
new(Guid.NewGuid().ToString(), "Test3", postId, DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1), false, new PostConfiguration { Rate = rate })
};
// Настраиваем мок для WorkerStorage
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns(workers);
// Настраиваем мок для RequestStorage
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(workers.Select(w =>
new RequestDataModel(Guid.NewGuid().ToString(), w.Id, "email@mail.ru",false, [], DateTime.UtcNow)).ToList());
// Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
// Assert
_salaryStorageContract.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Exactly(workers.Count));
}
[Test]
public void CalculateSalaryByMonth_WithoutSalesByWorker_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
var rate = 2000.0;
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, rate));
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>())).Returns([]);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = rate })]);
double sum = 0;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) => sum = x.Salary);
// Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
// Assert
Assert.That(sum, Is.EqualTo(rate));
}
[Test]
public void CalculateSalaryByMonth_RequestStorageReturnNull_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, 1000));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = 1000 })]);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void CalculateSalaryByMonth_PostStorageReturnNull_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
// Настраиваем моки
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "email@mail.ru", false, [], DateTime.UtcNow)]);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = 1000 })]);
// PostStorage возвращает null
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns((PostDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void CalculateSalaryByMonth_WorkerStorageReturnNull_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
// Настраиваем моки
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "email@mail.ru", false, [], DateTime.UtcNow)]);
// WorkerStorage возвращает null
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns((List<WorkerDataModel>)null);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, 1000));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void CalculateSalaryByMonth_RequestStorageThrowException_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
// RequestStorage выбрасывает исключение
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = 1000 })]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, 1000));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
}
[Test]
public void CalculateSalaryByMonth_PostStorageThrowException_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
// Настраиваем моки
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "email@mail.ru", false, [], DateTime.UtcNow)]);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, new PostConfiguration { Rate = 1000 })]);
// PostStorage выбрасывает исключение
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
}
[Test]
public void CalculateSalaryByMonth_WorkerStorageThrowException_ThrowException_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
// Настраиваем моки
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "email@mail.ru", false, [], DateTime.UtcNow)]);
// WorkerStorage выбрасывает исключение
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Throws(new StorageException(new InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(postId, "TestPost", PostType.SoftInstaller, 1000));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
}
[Test]
public void CalculateSalaryByMonth_WithCashierPostConfiguration_CalculateSalary_Test()
{
// Arrange
var workerId = Guid.NewGuid().ToString();
var postId = Guid.NewGuid().ToString();
var config = new CashierPostConfiguration
{
Rate = 2000,
SalePercent = 0.1,
BonusForExtraSales = 0.5
};
var sales = new List<RequestDataModel>()
{
new(Guid.NewGuid().ToString(), workerId, "eemail@maiil.ru", false,
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)], DateTime.UtcNow),
new(Guid.NewGuid().ToString(), workerId, "eeemail@maiiil.ru", false,
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)], DateTime.UtcNow),
new(Guid.NewGuid().ToString(), workerId, "eeeemail@mail.ru", false,
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5000, 12)], DateTime.UtcNow)
};
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "CashierConsultant", PostType.CashierConsultant, config.Rate));
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(sales);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, config)]);
double sum = 0;
var expectedSum = config.Rate + (config.SalePercent * sales.Average(x => x.Sum)) +
(sales.Where(x => x.Sum > _salaryConfigurationTest.ExtraSaleSum).Sum(x => x.Sum) * config.BonusForExtraSales);
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) => sum = x.Salary);
// Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
// Assert
Assert.That(sum, Is.EqualTo(expectedSum));
}
[Test]
public void
CalculateSalaryByMounth_RequestStorageReturnNull_ThrowException_Test()
public void CalculateSalaryByMonth_WithSupervisorPostConfiguration_CalculateSalary_Test()
{
//Arrange
// Arrange
var workerId = Guid.NewGuid().ToString();
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, 2000));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test",
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void
CalculateSalaryByMounth_PostStorageReturnNull_ThrowException_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), false, [], DateTime.UtcNow)]);
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test",
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void
CalculateSalaryByMounth_WorkerStorageReturnNull_ThrowException_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
workerId, Guid.NewGuid().ToString(), false, [], DateTime.UtcNow)]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, 2000));
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<NullListException>());
}
[Test]
public void
CalculateSalaryByMounth_RequestStorageThrowException_ThrowException_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Throws(new StorageException(new
InvalidOperationException()));
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, 2000));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test",
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
}
[Test]
public void
CalculateSalaryByMounth_PostStorageThrowException_ThrowException_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
workerId, Guid.NewGuid().ToString(), false, [], DateTime.UtcNow)]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Throws(new StorageException(new
InvalidOperationException()));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test",
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
}
[Test]
public void
CalculateSalaryByMounth_WorkerStorageThrowException_ThrowException_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), false, [], DateTime.UtcNow)]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
PostType.SoftInstaller, 2000));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Throws(new StorageException(new
InvalidOperationException()));
//Act&Assert
Assert.That(() =>
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow),
Throws.TypeOf<StorageException>());
var postId = Guid.NewGuid().ToString();
var rate = 2000.0;
var trend = 3;
var bonus = 100;
// Конфигурация для супервайзера
var supervisorConfig = new SupervisorPostConfiguration()
{
Rate = rate,
PersonalCountTrendPremium = bonus
};
// Настраиваем моки
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, "email@mail.ru", false,
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)], DateTime.UtcNow)]);
_postStorageContract.Setup(x => x.GetElementById(postId))
.Returns(new PostDataModel(postId, "Supervisor", PostType.Supervisor, supervisorConfig.Rate));
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
.Returns([new WorkerDataModel(workerId, "Test", postId,
DateTime.UtcNow.AddYears(-20), DateTime.UtcNow.AddYears(-1),
false, supervisorConfig)]);
_workerStorageContract.Setup(x => x.GetWorkerTrend(It.IsAny<DateTime>(), It.IsAny<DateTime>()))
.Returns(trend);
double actualSum = 0;
var expectedSum = rate + (trend * bonus);
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) => actualSum = x.Salary);
// Act
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
// Assert
Assert.That(actualSum, Is.EqualTo(expectedSum));
}
}

View File

@@ -5,6 +5,7 @@ using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -24,7 +25,7 @@ internal class SoftwareBusinessLogicContractTests
{
_softwareStorageContract = new Mock<ISoftwareStorageContract>();
_softwareBusinessLogicContract = new
SoftwareBusinessLogicContract(_softwareStorageContract.Object, new
SoftwareBusinessLogicContract(_softwareStorageContract.Object, StringLocalizerMockCreator.GetObject(), new
Mock<ILogger>().Object);
}
[SetUp]
@@ -98,7 +99,7 @@ internal class SoftwareBusinessLogicContractTests
//Arrange
_softwareStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.GetAllSoftwares(It.IsAny<bool>()),
@@ -206,7 +207,7 @@ internal class SoftwareBusinessLogicContractTests
//Arrange
_softwareStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.GetAllSoftwaresByManufacturer(Guid.NewGuid().ToString(), It.IsAny<bool>()), Throws.TypeOf<StorageException>());
@@ -293,7 +294,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.GetHistoryBySoftwareId(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.GetSoftwareHistoryBySoftware(Guid.NewGuid().ToString(
@@ -376,10 +377,10 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_softwareStorageContract.Setup(x =>
x.GetElementByName(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.GetSoftwareByData(Guid.NewGuid().ToString()),
@@ -421,7 +422,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.AddElement(It.IsAny<SoftwareDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.InsertSoftware(new(Guid.NewGuid().ToString(),
@@ -455,7 +456,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.AddElement(It.IsAny<SoftwareDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.InsertSoftware(new(Guid.NewGuid().ToString(),
@@ -493,7 +494,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.UpdElement(It.IsAny<SoftwareDataModel>())).Throws(new
ElementNotFoundException(""));
ElementNotFoundException("", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.UpdateSoftware(new(Guid.NewGuid().ToString(),
@@ -509,7 +510,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.UpdElement(It.IsAny<SoftwareDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.UpdateSoftware(new(Guid.NewGuid().ToString(),
@@ -543,7 +544,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.UpdElement(It.IsAny<SoftwareDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException() , StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.UpdateSoftware(new(Guid.NewGuid().ToString(),
@@ -573,7 +574,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
var id = Guid.NewGuid().ToString();
_softwareStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id));
x.DelElement(It.IsAny<string>())).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.DeleteSoftware(Guid.NewGuid().ToString()),
@@ -608,7 +609,7 @@ new(Guid.NewGuid().ToString(), 10),
//Arrange
_softwareStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_softwareBusinessLogicContract.DeleteSoftware(Guid.NewGuid().ToString()),

View File

@@ -3,7 +3,9 @@ using Moq;
using SmallSoftwareBusinessLogic.Implementations;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using SmallSoftwareContracts.StoragesContracts;
using SmallSoftwareTests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -22,7 +24,7 @@ internal class WorkerBusinessLogicContractTests
{
_workerStorageContract = new Mock<IWorkerStorageContract>();
_workerBusinessLogicContract = new
WorkerBusinessLogicContract(_workerStorageContract.Object, new
WorkerBusinessLogicContract(_workerStorageContract.Object, StringLocalizerMockCreator.GetObject(), new
Mock<ILogger>().Object);
}
[SetUp]
@@ -36,15 +38,9 @@ internal class WorkerBusinessLogicContractTests
//Arrange
var listOriginal = new List<WorkerDataModel>()
{
new(Guid.NewGuid().ToString(), "fio 1",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 2",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
true),
new(Guid.NewGuid().ToString(), "fio 3",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 1", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 2", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, true, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 3", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
};
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
@@ -106,7 +102,7 @@ internal class WorkerBusinessLogicContractTests
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.GetAllWorkers(It.IsAny<bool>()),
@@ -120,17 +116,11 @@ internal class WorkerBusinessLogicContractTests
//Arrange
var postId = Guid.NewGuid().ToString();
var listOriginal = new List<WorkerDataModel>()
{
new(Guid.NewGuid().ToString(), "fio 1",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 2",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
true),
new(Guid.NewGuid().ToString(), "fio 3",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
};
{
new(Guid.NewGuid().ToString(), "fio 1", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 2", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, true, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 3", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
};
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns(listOriginal);
@@ -221,7 +211,7 @@ false),
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.GetAllWorkersByPost(Guid.NewGuid().ToString(),
@@ -237,15 +227,9 @@ false),
var date = DateTime.UtcNow;
var listOriginal = new List<WorkerDataModel>()
{
new(Guid.NewGuid().ToString(), "fio 1",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 2",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
true),
new(Guid.NewGuid().ToString(), "fio 3",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 1", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 2", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, true, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 3", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
};
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
@@ -331,7 +315,7 @@ false),
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.GetAllWorkersByBirthDate(DateTime.UtcNow,
@@ -347,17 +331,11 @@ false),
//Arrange
var date = DateTime.UtcNow;
var listOriginal = new List<WorkerDataModel>()
{
new(Guid.NewGuid().ToString(), "fio 1",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
new(Guid.NewGuid().ToString(), "fio 2",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
true),
new(Guid.NewGuid().ToString(), "fio 3",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false),
};
{
new(Guid.NewGuid().ToString(), "fio 1", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 2", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, true, new PostConfiguration() { Rate = 10 }),
new(Guid.NewGuid().ToString(), "fio 3", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 }),
};
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns(listOriginal);
@@ -446,7 +424,7 @@ false),
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.GetAllWorkersByEmploymentDate(DateTime.UtcNow,
@@ -463,7 +441,7 @@ false),
var id = Guid.NewGuid().ToString();
var record = new WorkerDataModel(id, "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false);
false, new PostConfiguration() { Rate = 10 });
_workerStorageContract.Setup(x =>
x.GetElementById(id)).Returns(record);
//Act
@@ -481,7 +459,7 @@ false),
var fio = "fio";
var record = new WorkerDataModel(Guid.NewGuid().ToString(), fio,
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false);
false, new PostConfiguration() { Rate = 10 });
_workerStorageContract.Setup(x =>
x.GetElementByFIO(fio)).Returns(record);
//Act
@@ -536,10 +514,10 @@ public void GetWorkerByData_StorageThrowError_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
_workerStorageContract.Setup(x =>
x.GetElementByFIO(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.GetWorkerByData(Guid.NewGuid().ToString()),
@@ -559,7 +537,7 @@ public void InsertWorker_CorrectRecord_Test()
var flag = false;
var record = new WorkerDataModel(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false);
false, new PostConfiguration() { Rate = 10 });
_workerStorageContract.Setup(x =>
x.AddElement(It.IsAny<WorkerDataModel>()))
.Callback((WorkerDataModel x) =>
@@ -582,12 +560,12 @@ public void InsertWorker_RecordWithExistsData_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.AddElement(It.IsAny<WorkerDataModel>())).Throws(new
ElementExistsException("Data", "Data"));
ElementExistsException("Data", "Data", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.InsertWorker(new(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false)), Throws.TypeOf<ElementExistsException>());
false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<ElementExistsException>());
_workerStorageContract.Verify(x =>
x.AddElement(It.IsAny<WorkerDataModel>()), Times.Once);
}
@@ -606,7 +584,7 @@ public void InsertWorker_InvalidRecord_ThrowException_Test()
//Act&Assert
Assert.That(() => _workerBusinessLogicContract.InsertWorker(new
WorkerDataModel("id", "fio", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-
16).AddDays(-1), DateTime.Now, false)), Throws.TypeOf<ValidationException>());
16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<ValidationException>());
_workerStorageContract.Verify(x =>
x.AddElement(It.IsAny<WorkerDataModel>()), Times.Never);
}
@@ -616,12 +594,12 @@ public void InsertWorker_StorageThrowError_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.AddElement(It.IsAny<WorkerDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.InsertWorker(new(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false)), Throws.TypeOf<StorageException>());
false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<StorageException>());
_workerStorageContract.Verify(x =>
x.AddElement(It.IsAny<WorkerDataModel>()), Times.Once);
}
@@ -632,7 +610,7 @@ public void UpdateWorker_CorrectRecord_Test()
var flag = false;
var record = new WorkerDataModel(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false);
false, new PostConfiguration() { Rate = 10 });
_workerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<WorkerDataModel>()))
.Callback((WorkerDataModel x) =>
@@ -655,12 +633,12 @@ public void UpdateWorker_RecordWithIncorrectData_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<WorkerDataModel>())).Throws(new
ElementNotFoundException(""));
ElementNotFoundException("", StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.UpdateWorker(new(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false)), Throws.TypeOf<ElementNotFoundException>());
false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<ElementNotFoundException>());
_workerStorageContract.Verify(x =>
x.UpdElement(It.IsAny<WorkerDataModel>()), Times.Once);
}
@@ -679,7 +657,7 @@ public void UpdateWorker_InvalidRecord_ThrowException_Test()
//Act&Assert
Assert.That(() => _workerBusinessLogicContract.UpdateWorker(new
WorkerDataModel("id", "fio", Guid.NewGuid().ToString(), DateTime.Now.AddYears(-
16).AddDays(-1), DateTime.Now, false)), Throws.TypeOf<ValidationException>());
16).AddDays(-1), DateTime.Now, false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<ValidationException>());
_workerStorageContract.Verify(x =>
x.UpdElement(It.IsAny<WorkerDataModel>()), Times.Never);
}
@@ -689,12 +667,12 @@ public void UpdateWorker_StorageThrowError_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.UpdElement(It.IsAny<WorkerDataModel>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.UpdateWorker(new(Guid.NewGuid().ToString(), "fio",
Guid.NewGuid().ToString(), DateTime.Now.AddYears(-16).AddDays(-1), DateTime.Now,
false)), Throws.TypeOf<StorageException>());
false, new PostConfiguration() { Rate = 10 })), Throws.TypeOf<StorageException>());
_workerStorageContract.Verify(x =>
x.UpdElement(It.IsAny<WorkerDataModel>()), Times.Once);
}
@@ -719,7 +697,7 @@ public void DeleteWorker_RecordWithIncorrectId_ThrowException_Test()
//Arrange
var id = Guid.NewGuid().ToString();
_workerStorageContract.Setup(x => x.DelElement(It.Is((string x) => x
!= id))).Throws(new ElementNotFoundException(id));
!= id))).Throws(new ElementNotFoundException(id, StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.DeleteWorker(Guid.NewGuid().ToString()),
@@ -754,7 +732,7 @@ public void DeleteWorker_StorageThrowError_ThrowException_Test()
//Arrange
_workerStorageContract.Setup(x =>
x.DelElement(It.IsAny<string>())).Throws(new StorageException(new
InvalidOperationException()));
InvalidOperationException(), StringLocalizerMockCreator.GetObject()));
//Act&Assert
Assert.That(() =>
_workerBusinessLogicContract.DeleteWorker(Guid.NewGuid().ToString()),

View File

@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using SmallSoftwareTests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -18,11 +19,11 @@ internal class InstallationRequestDataModelTests
{
var installationRequest = CreateDataModel(null, Guid.NewGuid().ToString(),
10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
installationRequest = CreateDataModel(string.Empty,
Guid.NewGuid().ToString(), 10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -30,7 +31,7 @@ internal class InstallationRequestDataModelTests
{
var installationRequest = CreateDataModel("softwareId",
Guid.NewGuid().ToString(), 10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -38,11 +39,11 @@ internal class InstallationRequestDataModelTests
{
var installationRequest = CreateDataModel(Guid.NewGuid().ToString(), null,
10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
installationRequest = CreateDataModel(string.Empty,
Guid.NewGuid().ToString(), 10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -50,7 +51,7 @@ internal class InstallationRequestDataModelTests
{
var installationRequest = CreateDataModel(Guid.NewGuid().ToString(),
"requestId", 10, 10);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -58,11 +59,11 @@ internal class InstallationRequestDataModelTests
{
var installationRequest = CreateDataModel(Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(), 0, 0);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
installationRequest = CreateDataModel(Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(), -10, -20);
Assert.That(() => installationRequest.Validate(),
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -73,7 +74,7 @@ internal class InstallationRequestDataModelTests
var count = 10;
var price = 10;
var installationRequest = CreateDataModel(softwareId, requestId, count, price);
Assert.That(() => installationRequest.Validate(), Throws.Nothing);
Assert.That(() => installationRequest.Validate(StringLocalizerMockCreator.GetObject()), Throws.Nothing);
Assert.Multiple(() =>
{
Assert.That(installationRequest.SoftwareId, Is.EqualTo(softwareId));

View File

@@ -1,10 +1,6 @@
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmallSoftwareTests.Infrastructure;
namespace SmallSoftwareTests.DataModelsTests;
@@ -15,28 +11,28 @@ internal class ManufacturerDataModelTests
public void IdIsNullEmptyTest()
{
var manufacturer = CreateDataModel(null, "name");
Assert.That(() => manufacturer.Validate(),
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
manufacturer = CreateDataModel(string.Empty, "name");
Assert.That(() => manufacturer.Validate(),
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
public void IdIsNotGuidTest()
{
var manufacturer = CreateDataModel("id", "name");
Assert.That(() => manufacturer.Validate(),
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
public void ManufacturerNameIsNullOrEmptyTest()
{
var manufacturer = CreateDataModel(Guid.NewGuid().ToString(), null);
Assert.That(() => manufacturer.Validate(),
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
manufacturer = CreateDataModel(Guid.NewGuid().ToString(),
string.Empty);
Assert.That(() => manufacturer.Validate(),
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()),
Throws.TypeOf<ValidationException>());
}
[Test]
@@ -48,7 +44,7 @@ internal class ManufacturerDataModelTests
var prevPrevManufacturerName = "prevPrevManufacturerName";
var manufacturer = CreateDataModel(manufacturerId, manufacturerName,
prevManufacturerName, prevPrevManufacturerName);
Assert.That(() => manufacturer.Validate(), Throws.Nothing);
Assert.That(() => manufacturer.Validate(StringLocalizerMockCreator.GetObject()), Throws.Nothing);
Assert.Multiple(() =>
{
Assert.That(manufacturer.Id, Is.EqualTo(manufacturerId));

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