Расчет зарплаты

This commit is contained in:
2025-03-27 20:32:15 +04:00
parent 51ec839e90
commit 1807aabf23
13 changed files with 319 additions and 103 deletions

View File

@@ -2,19 +2,22 @@
using CatHasPawsContratcs.DataModels;
using CatHasPawsContratcs.Exceptions;
using CatHasPawsContratcs.Extensions;
using CatHasPawsContratcs.Infrastructure;
using CatHasPawsContratcs.Infrastructure.PostConfigurations;
using CatHasPawsContratcs.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace CatHasPawsBusinessLogic.Implementations;
internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract,
ISaleStorageContract saleStorageContract, IPostStorageContract postStorageContract, IWorkerStorageContract workerStorageContract, ILogger logger) : ISalaryBusinessLogicContract
internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageContract, ISaleStorageContract saleStorageContract, IPostStorageContract postStorageContract, IWorkerStorageContract workerStorageContract, ILogger logger, IConfigurationSalary сonfiguration) : ISalaryBusinessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISalaryStorageContract _salaryStorageContract = salaryStorageContract;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
private readonly IPostStorageContract _postStorageContract = postStorageContract;
private readonly IWorkerStorageContract _workerStorageContract = workerStorageContract;
private readonly IConfigurationSalary _salaryConfiguration = сonfiguration;
private readonly Lock _lockObject = new();
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate)
{
@@ -52,13 +55,67 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract salaryStorageC
var workers = _workerStorageContract.GetList() ?? throw new NullListException();
foreach (var worker in workers)
{
var sales = _saleStorageContract.GetList(startDate, finishDate, workerId: worker.Id)?.Sum(x => x.Sum) ??
throw new NullListException();
var post = _postStorageContract.GetElementById(worker.PostId) ??
throw new NullListException();
var salary = post.ConfigurationModel.Rate + sales * 0.1;
var sales = _saleStorageContract.GetList(startDate, finishDate, workerId: worker.Id) ?? throw new NullListException();
var post = _postStorageContract.GetElementById(worker.PostId) ?? throw new NullListException();
var salary = post.ConfigurationModel switch
{
null => 0,
CashierPostConfiguration cpc => CalculateSalaryForCashier(sales, 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<SaleDataModel> sales, DateTime startDate, DateTime finishDate, CashierPostConfiguration config)
{
var tasks = new List<Task>();
var calcPercent = 0.0;
for (var date = startDate; date < finishDate; date = date.AddDays(1))
{
tasks.Add(Task.Factory.StartNew((object? obj) =>
{
var dateInTask = (DateTime)obj!;
var salesInDay = sales.Where(x => x.SaleDate >= dateInTask && x.SaleDate <= dateInTask.AddDays(1)).ToArray();
if (salesInDay.Length > 0)
{
lock (_lockObject)
{
calcPercent += (salesInDay.Sum(x => x.Sum) / salesInDay.Length) * config.SalePercent;
}
}
}, date));
}
var calcBonusTask = Task.Run(() =>
{
return sales.Where(x => x.Sum > _salaryConfiguration.ExtraSaleSum).Sum(x => x.Sum) * config.BonusForExtraSales;
});
try
{
Task.WaitAll([Task.WhenAll(tasks), calcBonusTask]);
}
catch (AggregateException agEx)
{
foreach (var ex in agEx.InnerExceptions)
{
_logger.LogError(ex, "Error in the cashier payroll process");
}
return 0;
}
return config.Rate + calcPercent + calcBonusTask.Result;
}
private double 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

@@ -0,0 +1,6 @@
namespace CatHasPawsContratcs.Infrastructure;
public interface IConfigurationSalary
{
double ExtraSaleSum { get; }
}

View File

@@ -15,4 +15,6 @@ public interface IWorkerStorageContract
void UpdElement(WorkerDataModel workerDataModel);
void DelElement(string id);
int GetWorkerTrend(DateTime fromPeriod, DateTime toPeriod);
}

View File

@@ -125,6 +125,7 @@ internal class WorkerStorageContract : IWorkerStorageContract
{
var element = GetWorkerById(id) ?? throw new ElementNotFoundException(id);
element.IsDeleted = true;
element.DateOfDelete = DateTime.UtcNow;
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
@@ -139,6 +140,21 @@ internal class WorkerStorageContract : IWorkerStorageContract
}
}
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);
}
}
private Worker? GetWorkerById(string id) => AddPost(_dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
private IQueryable<Worker> JoinPost(IQueryable<Worker> query)

View File

@@ -16,6 +16,8 @@ internal class Worker
public bool IsDeleted { get; set; }
public DateTime? DateOfDelete { get; set; }
[NotMapped]
public Post? Post { get; set; }

View File

@@ -2,7 +2,9 @@
using CatHasPawsContratcs.DataModels;
using CatHasPawsContratcs.Enums;
using CatHasPawsContratcs.Exceptions;
using CatHasPawsContratcs.Infrastructure.PostConfigurations;
using CatHasPawsContratcs.StoragesContracts;
using CatHasPawsTests.Infrastructure;
using Microsoft.Extensions.Logging;
using Moq;
@@ -16,6 +18,7 @@ internal class SalaryBusinessLogicContractTests
private Mock<ISaleStorageContract> _saleStorageContract;
private Mock<IPostStorageContract> _postStorageContract;
private Mock<IWorkerStorageContract> _workerStorageContract;
private readonly ConfigurationSalaryTest _salaryConfigurationTest = new();
[OneTimeSetUp]
public void OneTimeSetUp()
@@ -25,7 +28,7 @@ internal class SalaryBusinessLogicContractTests
_postStorageContract = new Mock<IPostStorageContract>();
_workerStorageContract = new Mock<IWorkerStorageContract>();
_salaryBusinessLogicContract = new SalaryBusinessLogicContract(_salaryStorageContract.Object,
_saleStorageContract.Object, _postStorageContract.Object, _workerStorageContract.Object, new Mock<ILogger>().Object);
_saleStorageContract.Object, _postStorageContract.Object, _workerStorageContract.Object, new Mock<ILogger>().Object, _salaryConfigurationTest);
}
[SetUp]
@@ -185,92 +188,89 @@ internal class SalaryBusinessLogicContractTests
public void CalculateSalaryByMounth_CalculateSalary_Test()
{
//Arrange
//var workerId = Guid.NewGuid().ToString();
//var saleSum = 1.2 * 5;
//var postSalary = 2000.0;
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
// .Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)])]);
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 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 + saleSum * 0.1;
//_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
// .Callback((SalaryDataModel x) =>
// {
// sum = x.Salary;
// });
////Act
//_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
////Assert
//Assert.That(sum, Is.EqualTo(expectedSum));
var workerId = Guid.NewGuid().ToString();
var rate = 2000.0;
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)])]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 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", Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
var sum = 0.0;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
sum = x.Salary;
});
//Act
_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
//Assert
Assert.That(sum, Is.EqualTo(rate));
}
[Test]
public void CalculateSalaryByMounth_WithSeveralWorkers_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)
//};
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
// .Returns([new SaleDataModel(Guid.NewGuid().ToString(), worker1Id, null, DiscountType.None, false, []),
// new SaleDataModel(Guid.NewGuid().ToString(), worker1Id, null, DiscountType.None, false, []),
// new SaleDataModel(Guid.NewGuid().ToString(), worker2Id, null, DiscountType.None, false, []),
// new SaleDataModel(Guid.NewGuid().ToString(), worker3Id, null, DiscountType.None, false, []),
// new SaleDataModel(Guid.NewGuid().ToString(), worker3Id, null, DiscountType.None, false, [])]);
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 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.CalculateSalaryByMounth(DateTime.UtcNow);
////Assert
//_salaryStorageContract.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Exactly(list.Count));
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)
};
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new SaleDataModel(Guid.NewGuid().ToString(), worker1Id, null, DiscountType.None, false, []),
new SaleDataModel(Guid.NewGuid().ToString(), worker1Id, null, DiscountType.None, false, []),
new SaleDataModel(Guid.NewGuid().ToString(), worker2Id, null, DiscountType.None, false, []),
new SaleDataModel(Guid.NewGuid().ToString(), worker3Id, null, DiscountType.None, false, []),
new SaleDataModel(Guid.NewGuid().ToString(), worker3Id, null, DiscountType.None, false, [])]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 100 }));
_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.CalculateSalaryByMounth(DateTime.UtcNow);
//Assert
_salaryStorageContract.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Exactly(list.Count));
}
[Test]
public void CalculateSalaryByMounth_WithoutSalesByWorker_Test()
{
//Arrange
//var postSalary = 2000.0;
//var workerId = Guid.NewGuid().ToString();
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
// .Returns([]);
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 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
//_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
////Assert
//Assert.That(sum, Is.EqualTo(expectedSum));
var rate = 2000.0;
var workerId = Guid.NewGuid().ToString();
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 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", Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
var sum = 0.0;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
sum = x.Salary;
});
//Act
_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
//Assert
Assert.That(sum, Is.EqualTo(rate));
}
[Test]
public void CalculateSalaryByMounth_SaleStorageReturnNull_ThrowException_Test()
{
//Arrange
//var workerId = Guid.NewGuid().ToString();
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<NullListException>());
var workerId = Guid.NewGuid().ToString();
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 100 }));
_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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<NullListException>());
}
[Test]
@@ -290,28 +290,28 @@ internal class SalaryBusinessLogicContractTests
public void CalculateSalaryByMounth_WorkerStorageReturnNull_ThrowException_Test()
{
//Arrange
//var workerId = Guid.NewGuid().ToString();
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
// .Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [])]);
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 2000));
////Act&Assert
//Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<NullListException>());
var workerId = Guid.NewGuid().ToString();
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [])]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 100 }));
//Act&Assert
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<NullListException>());
}
[Test]
public void CalculateSalaryByMounth_SaleStorageThrowException_ThrowException_Test()
{
//Arrange
//var workerId = Guid.NewGuid().ToString();
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), 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.Assistant, 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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
var workerId = Guid.NewGuid().ToString();
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), 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.Assistant, new PostConfiguration() { Rate = 100 }));
_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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
}
[Test]
@@ -333,14 +333,77 @@ internal class SalaryBusinessLogicContractTests
public void CalculateSalaryByMounth_WorkerStorageThrowException_ThrowException_Test()
{
//Arrange
//var workerId = Guid.NewGuid().ToString();
//_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
// .Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [])]);
//_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
// .Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, 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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
var workerId = Guid.NewGuid().ToString();
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [])]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new PostConfiguration() { Rate = 100 }));
_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.CalculateSalaryByMounth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
}
[Test]
public void CalculateSalaryByMountht_WithCashierPostConfiguration_CalculateSalary_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
var rate = 2000.0;
var percent = 0.1;
var bonus = 0.5;
var sales = new List<SaleDataModel>()
{
new(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)]),
new(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)]),
new(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5000, 12)])
};
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(sales);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new CashierPostConfiguration() { Rate = rate, SalePercent = percent, BonusForExtraSales = bonus }));
_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 = rate + percent * (sales.Sum(x => x.Sum) / sales.Count) + sales.Where(x => x.Sum > _salaryConfigurationTest.ExtraSaleSum).Sum(x => x.Sum) * bonus;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
sum = x.Salary;
});
//Act
_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
//Assert
Assert.That(sum, Is.EqualTo(expectedSum));
}
[Test]
public void CalculateSalaryByMountht_WithSupervisorPostConfiguration_CalculateSalary_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
var rate = 2000.0;
var trend = 3;
var bonus = 100;
_saleStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns([new SaleDataModel(Guid.NewGuid().ToString(), workerId, null, DiscountType.None, false, [new SaleProductDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)])]);
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name", PostType.Assistant, new SupervisorPostConfiguration() { Rate = rate, PersonalCountTrendPremium = bonus }));
_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)]);
_workerStorageContract.Setup(x => x.GetWorkerTrend(It.IsAny<DateTime>(), It.IsAny<DateTime>()))
.Returns(trend);
var sum = 0.0;
var expectedSum = rate + trend * bonus;
_salaryStorageContract.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
sum = x.Salary;
});
//Act
_salaryBusinessLogicContract.CalculateSalaryByMounth(DateTime.UtcNow);
//Assert
Assert.That(sum, Is.EqualTo(expectedSum));
}
}

View File

@@ -71,9 +71,9 @@ internal static class CatHasPawsDbContextExtensions
return sale;
}
public static Worker InsertWorkerToDatabaseAndReturn(this CatHasPawsDbContext dbContext, string? id = null, string fio = "test", string? postId = null, DateTime? birthDate = null, DateTime? employmentDate = null, bool isDeleted = false)
public static Worker InsertWorkerToDatabaseAndReturn(this CatHasPawsDbContext dbContext, string? id = null, string fio = "test", string? postId = null, DateTime? birthDate = null, DateTime? employmentDate = null, bool isDeleted = false, DateTime? dateDelete = null)
{
var worker = new Worker() { Id = id ?? Guid.NewGuid().ToString(), FIO = fio, PostId = postId ?? Guid.NewGuid().ToString(), BirthDate = birthDate ?? DateTime.UtcNow.AddYears(-20), EmploymentDate = employmentDate ?? DateTime.UtcNow, IsDeleted = isDeleted };
var worker = new Worker() { Id = id ?? Guid.NewGuid().ToString(), FIO = fio, PostId = postId ?? Guid.NewGuid().ToString(), BirthDate = birthDate ?? DateTime.UtcNow.AddYears(-20), EmploymentDate = employmentDate ?? DateTime.UtcNow, IsDeleted = isDeleted, DateOfDelete = dateDelete };
dbContext.Workers.Add(worker);
dbContext.SaveChanges();
return worker;

View File

@@ -0,0 +1,8 @@
using CatHasPawsContratcs.Infrastructure;
namespace CatHasPawsTests.Infrastructure;
class ConfigurationSalaryTest : IConfigurationSalary
{
public double ExtraSaleSum => 10;
}

View File

@@ -182,6 +182,43 @@ internal class WorkerStorageContractTests : BaseStorageContractTest
Assert.That(() => _workerStorageContract.DelElement(worker.Id), Throws.TypeOf<ElementNotFoundException>());
}
[Test]
public void Try_GetWorkerTrend_WhenNoNewAndDeletedWorkers_Test()
{
var startDate = DateTime.UtcNow.AddDays(-5);
var endDate = DateTime.UtcNow.AddDays(-3);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10), isDeleted: true, dateDelete: DateTime.UtcNow.AddDays(-9));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10), isDeleted: true, dateDelete: DateTime.UtcNow.AddDays(-1));
var count = _workerStorageContract.GetWorkerTrend(startDate, endDate);
Assert.That(count, Is.EqualTo(0));
}
[Test]
public void Try_GetWorkerTrend_WhenHaveNewAndNoDeletedWorkers_Test()
{
var startDate = DateTime.UtcNow.AddDays(-5);
var endDate = DateTime.UtcNow.AddDays(-3);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-4));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-1));
var count = _workerStorageContract.GetWorkerTrend(startDate, endDate);
Assert.That(count, Is.EqualTo(1));
}
[Test]
public void Try_GetWorkerTrend_WhenNoNewAndHaveDeletedWorkers_Test()
{
var startDate = DateTime.UtcNow.AddDays(-5);
var endDate = DateTime.UtcNow.AddDays(-3);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10), isDeleted: true, dateDelete: DateTime.UtcNow.AddDays(-9));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10), isDeleted: true, dateDelete: DateTime.UtcNow.AddDays(-4));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(employmentDate: DateTime.UtcNow.AddDays(-10), isDeleted: true, dateDelete: DateTime.UtcNow.AddDays(-1));
var count = _workerStorageContract.GetWorkerTrend(startDate, endDate);
Assert.That(count, Is.EqualTo(-1));
}
private static void AssertElement(WorkerDataModel? actual, Worker expected)
{
Assert.That(actual, Is.Not.Null);
@@ -210,6 +247,7 @@ internal class WorkerStorageContractTests : BaseStorageContractTest
Assert.That(actual.BirthDate, Is.EqualTo(expected.BirthDate));
Assert.That(actual.EmploymentDate, Is.EqualTo(expected.EmploymentDate));
Assert.That(actual.IsDeleted, Is.EqualTo(expected.IsDeleted));
Assert.That(actual.DateOfDelete.HasValue, Is.EqualTo(expected.IsDeleted));
});
}
}

View File

@@ -0,0 +1,14 @@
using CatHasPawsContratcs.Infrastructure;
namespace CatHasPawsWebApi.Infrastructure;
public class ConfigurationSalary(IConfiguration configuration) : IConfigurationSalary
{
private readonly Lazy<SalarySettings> _salarySettings = new(() =>
{
return configuration.GetValue<SalarySettings>("SalarySettings") ?? throw new InvalidDataException(nameof(SalarySettings));
});
public double ExtraSaleSum => _salarySettings.Value.ExtraSaleSum;
}

View File

@@ -0,0 +1,6 @@
namespace CatHasPawsWebApi.Infrastructure;
public class SalarySettings
{
public double ExtraSaleSum { get; set; }
}

View File

@@ -49,6 +49,7 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
});
builder.Services.AddSingleton<IConfigurationDatabase, ConfigurationDatabase>();
builder.Services.AddSingleton<IConfigurationSalary, ConfigurationSalary>();
builder.Services.AddTransient<IBuyerBusinessLogicContract, BuyerBusinessLogicContract>();
builder.Services.AddTransient<IManufacturerBusinessLogicContract, ManufacturerBusinessLogicContract>();

View File

@@ -24,5 +24,8 @@
"AllowedHosts": "*",
"DataBaseSettings": {
"ConnectionString": "Host=127.0.0.1;Port=5432;Database=CatHasPaws;Username=postgres;Password=postgres;"
},
"SalarySettings": {
"ExtraSaleSum": 1000
}
}