Сделал 5 лабораторную
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TwoFromTheCasketContracts.BusinessLogicsContracts;
|
||||
using TwoFromTheCasketContracts.DataModels;
|
||||
using TwoFromTheCasketContracts.Exceptions;
|
||||
using TwoFromTheCasketContracts.Infastructure;
|
||||
using TwoFromTheCasketContracts.Infastructure.SalaryConfiguration;
|
||||
using TwoFromTheCasketContracts.StorageContracts;
|
||||
|
||||
namespace TwoFromTheCasketBusinessLogic.Implementation;
|
||||
|
||||
internal class SalaryBusinessLogicContract(ISalaryStorageContract _salaryStorageContract, IWorkerStorageContract _workerStorageContract,
|
||||
IComplitedWorkStorageContract _сomplitedWorkStorageContract, ISpecializationStorageContract _specializationStorageContract, ILogger _logger) : ISalaryBusinessLogicContract
|
||||
IComplitedWorkStorageContract _сomplitedWorkStorageContract, ISpecializationStorageContract _specializationStorageContract, ILogger _logger, IConfigurationSalary configuration) : ISalaryBusinessLogicContract
|
||||
{
|
||||
private ISalaryStorageContract salaryStorageContract = _salaryStorageContract;
|
||||
private IWorkerStorageContract workerStorageContract = _workerStorageContract;
|
||||
private IComplitedWorkStorageContract сomplitedWorkStorageContract = _сomplitedWorkStorageContract;
|
||||
private ISpecializationStorageContract specializationStorageContract = _specializationStorageContract;
|
||||
private IConfigurationSalary configurationSalary = configuration;
|
||||
private ILogger logger = _logger;
|
||||
|
||||
public List<SalaryDataModel> GetSalariesByWorkerByPeriod(string workerId, DateTime fromDate, DateTime toDate)
|
||||
@@ -47,56 +51,118 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract _salaryStorage
|
||||
|
||||
public void CalculateSalaryByMonth(DateTime date)
|
||||
{
|
||||
_logger.LogInformation("Calculating salary for month: {Date}", date);
|
||||
logger.LogInformation("Calculating salary for month: {Date}", date);
|
||||
|
||||
var startDate = new DateTime(date.Year, date.Month, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
var finishDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month), 23, 59, 59, DateTimeKind.Utc);
|
||||
var finishDate = new DateTime(
|
||||
date.Year,
|
||||
date.Month,
|
||||
DateTime.DaysInMonth(date.Year, date.Month),
|
||||
23, 59, 59,
|
||||
DateTimeKind.Utc);
|
||||
|
||||
var workers = _workerStorageContract.GetList() ?? throw new StorageException(new InvalidOperationException("Failed to retrieve workerStorageContract from storage."));
|
||||
var workers = workerStorageContract.GetList()
|
||||
?? throw new StorageException(new InvalidOperationException("Failed to load workers"));
|
||||
|
||||
foreach (var worker in workers)
|
||||
{
|
||||
var completedWorks = сomplitedWorkStorageContract.GetList(startDate, finishDate, WorkerId: worker.Id);
|
||||
var completed = сomplitedWorkStorageContract
|
||||
.GetList(startDate, finishDate, worker.Id)
|
||||
?? throw new StorageException(new InvalidOperationException("Failed to load completed works"));
|
||||
|
||||
if (completedWorks == null)
|
||||
throw new StorageException(new InvalidOperationException("Failed to retrieve completed works from storage."));
|
||||
|
||||
var totalHours = completedWorks
|
||||
var totalUnits = completed
|
||||
.SelectMany(cw => cw.Workers)
|
||||
.Where(wcw => wcw.WorkerId == worker.Id)
|
||||
.Sum(wcw => wcw.NumberOfWorkingHours);
|
||||
|
||||
var specialization = _specializationStorageContract.GetElementById(worker.SpecializationId)
|
||||
var specialization = specializationStorageContract
|
||||
.GetElementById(worker.SpecializationId)
|
||||
?? throw new NullListException();
|
||||
|
||||
var salary = specialization.Salary * totalHours;
|
||||
var cfg = worker.ConfigurationModel;
|
||||
double salaryToPay;
|
||||
|
||||
_logger.LogDebug("Calculated salary for worker {WorkerId}: {Salary}", worker.Id, salary);
|
||||
switch (cfg)
|
||||
{
|
||||
case OvertimeSalaryConfiguration otCfg:
|
||||
salaryToPay = CalculateOvertimeParallel(otCfg, totalUnits);
|
||||
break;
|
||||
|
||||
_salaryStorageContract.AddElement(new SalaryDataModel(Guid.NewGuid().ToString(), worker.Id, salary));
|
||||
case PieceworkSalaryConfiguration pwCfg:
|
||||
salaryToPay = CalculatePieceworkParallel(pwCfg, completed, worker.Id);
|
||||
break;
|
||||
|
||||
default:
|
||||
salaryToPay = cfg.Rate * totalUnits;
|
||||
break;
|
||||
}
|
||||
|
||||
logger.LogDebug("Worker {WorkerId} totalUnits={Units} salary={Salary}", worker.Id, totalUnits, salaryToPay);
|
||||
|
||||
salaryStorageContract.AddElement(
|
||||
new SalaryDataModel(Guid.NewGuid().ToString(), worker.Id, salaryToPay)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertSalary(SalaryDataModel model)
|
||||
private double CalculateOvertimeParallel(OvertimeSalaryConfiguration cfg, double hours)
|
||||
{
|
||||
if (model == null)
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
const double standardHours = 160;
|
||||
|
||||
logger.LogInformation("Inserting salary: {SalaryId}", model.Id);
|
||||
var t1 = Task.Run(() => Math.Min(hours, standardHours) * cfg.Rate);
|
||||
var t2 = Task.Run(() => Math.Max(0, hours - standardHours) * cfg.Rate * cfg.OvertimeMultiplier);
|
||||
|
||||
if (!Guid.TryParse(model.Id, out _))
|
||||
throw new ValidationException("Salary ID is not a valid GUID.");
|
||||
|
||||
if (!Guid.TryParse(model.WorkerId, out _))
|
||||
throw new ValidationException("Worker ID is not a valid GUID.");
|
||||
|
||||
var worker = workerStorageContract.GetElementById(model.WorkerId)
|
||||
?? throw new ElementNotFoundException(model.WorkerId);
|
||||
|
||||
salaryStorageContract.AddElement(model);
|
||||
|
||||
logger.LogDebug("Salary inserted for worker {WorkerId}", model.WorkerId);
|
||||
Task.WaitAll(t1, t2);
|
||||
return t1.Result + t2.Result;
|
||||
}
|
||||
|
||||
private double CalculatePieceworkParallel(
|
||||
PieceworkSalaryConfiguration cfg,
|
||||
List<ComplitedWorkDataModel> completed,
|
||||
string workerId)
|
||||
{
|
||||
var units = completed
|
||||
.SelectMany(cw => cw.Workers)
|
||||
.Where(wcw => wcw.WorkerId == workerId)
|
||||
.Select(wcw => wcw.NumberOfWorkingHours)
|
||||
.ToList();
|
||||
|
||||
if (units.Count == 0)
|
||||
return 0;
|
||||
|
||||
var maxThreads = configurationSalary.MaxParallelThreads;
|
||||
var semaphore = new SemaphoreSlim(maxThreads);
|
||||
|
||||
var chunkSize = (int)Math.Ceiling(units.Count / (double)maxThreads);
|
||||
var tasks = new List<Task<double>>();
|
||||
|
||||
for (int i = 0; i < units.Count; i += chunkSize)
|
||||
{
|
||||
var chunk = units.Skip(i).Take(chunkSize).ToList();
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
semaphore.Wait();
|
||||
try
|
||||
{
|
||||
return chunk.Sum(u => u * cfg.UnitRate);
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
semaphore.Dispose();
|
||||
|
||||
var basePay = tasks.Sum(t => t.Result);
|
||||
|
||||
var totalUnits = units.Sum();
|
||||
var bonusUnits = Math.Max(0, totalUnits - configurationSalary.BonusThreshold);
|
||||
var bonusPay = bonusUnits * cfg.BonusPerUnit;
|
||||
|
||||
return basePay + bonusPay;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,5 +6,4 @@ public interface ISalaryBusinessLogicContract
|
||||
List<SalaryDataModel> GetSalariesByWorkerByPeriod(string workerId, DateTime fromDate, DateTime toDate);
|
||||
|
||||
void CalculateSalaryByMonth(DateTime date);
|
||||
public void InsertSalary(SalaryDataModel model);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace TwoFromTheCasketContracts.Infastructure;
|
||||
|
||||
public interface IConfigurationSalary
|
||||
{
|
||||
int MaxParallelThreads { get; }
|
||||
|
||||
double BonusThreshold { get; }
|
||||
}
|
||||
@@ -6,7 +6,5 @@ public class PieceworkSalaryConfiguration : SalaryConfiguration
|
||||
|
||||
public double UnitRate { get; set; }
|
||||
|
||||
public double BonusThreshold { get; set; }
|
||||
|
||||
public double BonusPerUnit { get; set; }
|
||||
}
|
||||
|
||||
@@ -38,36 +38,38 @@ public class ComplitedWorkStorageContract : IComplitedWorkStorageContract
|
||||
try
|
||||
{
|
||||
var query = _dbContext.ComplitedWorks
|
||||
.Include(x => x.Work)
|
||||
.Include(x => x.Room)
|
||||
.Include(x => x.WorkersComplitedWorks)
|
||||
.Include(cw => cw.WorkersComplitedWorks)
|
||||
.Where(cw => cw.Date >= startTime && cw.Date <= endTime)
|
||||
.AsQueryable();
|
||||
|
||||
if (startTime.HasValue)
|
||||
query = query.Where(x => x.Date >= startTime.Value);
|
||||
|
||||
if (endTime.HasValue)
|
||||
query = query.Where(x => x.Date <= endTime.Value);
|
||||
|
||||
if (!string.IsNullOrEmpty(RoomId))
|
||||
query = query.Where(x => x.RoomId == RoomId);
|
||||
if (!string.IsNullOrEmpty(WorkerId))
|
||||
query = query.Where(cw =>
|
||||
cw.WorkersComplitedWorks.Any(wcw => wcw.WorkerId == WorkerId));
|
||||
|
||||
if (!string.IsNullOrEmpty(WorkId))
|
||||
query = query.Where(x => x.WorkId == WorkId);
|
||||
query = query.Where(cw => cw.WorkId == WorkId);
|
||||
|
||||
if (!string.IsNullOrEmpty(WorkerId))
|
||||
query = query.Where(x => x.WorkersComplitedWorks.Any(wcw => wcw.WorkerId == WorkerId));
|
||||
if (!string.IsNullOrEmpty(RoomId))
|
||||
query = query.Where(cw => cw.RoomId == RoomId);
|
||||
|
||||
var result = query
|
||||
.Select(x => _mapper.Map<ComplitedWorkDataModel>(x))
|
||||
return query
|
||||
.Select(cw => new ComplitedWorkDataModel(
|
||||
cw.Id,
|
||||
cw.WorkId,
|
||||
cw.RoomId,
|
||||
cw.WorkersComplitedWorks
|
||||
.Select(wcw => new WorkerComplitedWorkDataModel(
|
||||
wcw.WorkerId,
|
||||
wcw.ComplitedWorkId,
|
||||
wcw.NumberOfWorkingHours))
|
||||
.ToList()
|
||||
))
|
||||
.ToList();
|
||||
|
||||
return result ?? new List<ComplitedWorkDataModel>();
|
||||
}
|
||||
catch (Exception e)
|
||||
catch
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw new StorageException(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,11 @@ using TwoFromTheCasketBusinessLogic.Implementation;
|
||||
using TwoFromTheCasketContracts.BusinessLogicsContracts;
|
||||
using TwoFromTheCasketContracts.DataModels;
|
||||
using TwoFromTheCasketContracts.Exceptions;
|
||||
using TwoFromTheCasketContracts.Infastructure;
|
||||
using TwoFromTheCasketContracts.Infastructure.SalaryConfiguration;
|
||||
using TwoFromTheCasketContracts.StorageContracts;
|
||||
using TwoFromTheCasketTests.Infrastructure;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
|
||||
namespace TwoFromTheCasketTests.BusinessLogicsContractsTests;
|
||||
@@ -20,6 +24,7 @@ public class SalaryBusinessLogicContractTests
|
||||
private Mock<IWorkerStorageContract> _workerStorageMock;
|
||||
private Mock<IComplitedWorkStorageContract> _complitedWorkStorageMock;
|
||||
private Mock<ISpecializationStorageContract> _specializationStorageMock;
|
||||
private readonly ConfigurationSalaryTest _configurationSalary = new();
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetUp()
|
||||
@@ -29,16 +34,18 @@ public class SalaryBusinessLogicContractTests
|
||||
_complitedWorkStorageMock = new Mock<IComplitedWorkStorageContract>();
|
||||
_specializationStorageMock = new Mock<ISpecializationStorageContract>();
|
||||
|
||||
|
||||
_salaryBusinessLogicContract = new SalaryBusinessLogicContract(
|
||||
_salaryStorageMock.Object,
|
||||
_workerStorageMock.Object,
|
||||
_complitedWorkStorageMock.Object,
|
||||
_specializationStorageMock.Object,
|
||||
new Mock<ILogger>().Object);
|
||||
new Mock<ILogger>().Object,
|
||||
_configurationSalary);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_salaryStorageMock.Reset();
|
||||
_workerStorageMock.Reset();
|
||||
@@ -49,276 +56,416 @@ public class SalaryBusinessLogicContractTests
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_ReturnListOfRecords_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
//var listOriginal = new List<SalaryDataModel>
|
||||
//{
|
||||
// new(Guid.NewGuid().ToString(), workerId, 5000),
|
||||
// new(Guid.NewGuid().ToString(), workerId, 6000),
|
||||
// new(Guid.NewGuid().ToString(), workerId, 7000)
|
||||
//};
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
var listOriginal = new List<SalaryDataModel>
|
||||
{
|
||||
new(Guid.NewGuid().ToString(), workerId, 5000),
|
||||
new(Guid.NewGuid().ToString(), workerId, 6000),
|
||||
new(Guid.NewGuid().ToString(), workerId, 7000)
|
||||
};
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns(listOriginal);
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns(listOriginal);
|
||||
|
||||
//var list = _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate);
|
||||
var list = _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate);
|
||||
|
||||
//Assert.Multiple(() =>
|
||||
//{
|
||||
// Assert.That(list, Is.Not.Null);
|
||||
// Assert.That(list, Is.EquivalentTo(listOriginal));
|
||||
//});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.EquivalentTo(listOriginal));
|
||||
});
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_ReturnEmptyList_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns(new List<SalaryDataModel>());
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns(new List<SalaryDataModel>());
|
||||
|
||||
//var list = _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate);
|
||||
var list = _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate);
|
||||
|
||||
//Assert.Multiple(() =>
|
||||
//{
|
||||
// Assert.That(list, Is.Not.Null);
|
||||
// Assert.That(list, Has.Count.EqualTo(0));
|
||||
//});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(0));
|
||||
});
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_IncorrectDates_ThrowException_Test()
|
||||
{
|
||||
//var date = DateTime.UtcNow;
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
var date = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, date, date), Throws.TypeOf<IncorrectDatesException>());
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, date, date.AddSeconds(-1)), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, date, date), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, date, date.AddSeconds(-1)), Throws.TypeOf<IncorrectDatesException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_WorkerIdIsNullOrEmpty_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(null, fromDate, toDate), Throws.TypeOf<ArgumentNullException>());
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(string.Empty, fromDate, toDate), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(null, fromDate, toDate), Throws.TypeOf<ArgumentNullException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(string.Empty, fromDate, toDate), Throws.TypeOf<ArgumentNullException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_WorkerIdIsNotGuid_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var workerId = "invalid-guid";
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var workerId = "invalid-guid";
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<ValidationException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<ValidationException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_ReturnNull_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns((List<SalaryDataModel>)null);
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Returns((List<SalaryDataModel>)null);
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<NullListException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<NullListException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByWorkerByPeriod_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Throws(new StorageException(new InvalidOperationException()));
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, workerId)).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByWorkerByPeriod(workerId, fromDate, toDate), Throws.TypeOf<StorageException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, workerId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByPeriod_ReturnListOfRecords_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
//var listOriginal = new List<SalaryDataModel>
|
||||
//{
|
||||
// new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5000),
|
||||
// new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 6000),
|
||||
// new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 7000)
|
||||
//};
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
var listOriginal = new List<SalaryDataModel>
|
||||
{
|
||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5000),
|
||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 6000),
|
||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 7000)
|
||||
};
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns(listOriginal);
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns(listOriginal);
|
||||
|
||||
//var list = _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate);
|
||||
var list = _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate);
|
||||
|
||||
//Assert.Multiple(() =>
|
||||
//{
|
||||
// Assert.That(list, Is.Not.Null);
|
||||
// Assert.That(list, Is.EquivalentTo(listOriginal));
|
||||
//});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Is.EquivalentTo(listOriginal));
|
||||
});
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByPeriod_ReturnEmptyList_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns(new List<SalaryDataModel>());
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns(new List<SalaryDataModel>());
|
||||
|
||||
//var list = _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate);
|
||||
var list = _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate);
|
||||
|
||||
//Assert.Multiple(() =>
|
||||
//{
|
||||
// Assert.That(list, Is.Not.Null);
|
||||
// Assert.That(list, Has.Count.EqualTo(0));
|
||||
//});
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(list, Is.Not.Null);
|
||||
Assert.That(list, Has.Count.EqualTo(0));
|
||||
});
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByPeriod_IncorrectDates_ThrowException_Test()
|
||||
{
|
||||
//var date = DateTime.UtcNow;
|
||||
var date = DateTime.UtcNow;
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(date, date), Throws.TypeOf<IncorrectDatesException>());
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(date, date.AddSeconds(-1)), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(date, date), Throws.TypeOf<IncorrectDatesException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(date, date.AddSeconds(-1)), Throws.TypeOf<IncorrectDatesException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
_salaryStorageMock.Verify(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByPeriod_ReturnNull_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns((List<SalaryDataModel>)null);
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Returns((List<SalaryDataModel>)null);
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate), Throws.TypeOf<NullListException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate), Throws.TypeOf<NullListException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSalariesByPeriod_StorageThrowError_ThrowException_Test()
|
||||
{
|
||||
//var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
//var toDate = DateTime.UtcNow;
|
||||
var fromDate = DateTime.UtcNow.AddMonths(-1);
|
||||
var toDate = DateTime.UtcNow;
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Throws(new StorageException(new InvalidOperationException()));
|
||||
_salaryStorageMock.Setup(x => x.GetList(fromDate, toDate, null)).Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.GetSalariesByPeriod(fromDate, toDate), Throws.TypeOf<StorageException>());
|
||||
|
||||
//_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
_salaryStorageMock.Verify(x => x.GetList(fromDate, toDate, null), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMounth_CalculateSalary_Test()
|
||||
public void CalculateSalaryByMonth_CalculateSalary_Test()
|
||||
{
|
||||
//var workerId = Guid.NewGuid().ToString();
|
||||
//var workId = Guid.NewGuid().ToString();
|
||||
//var roomId = Guid.NewGuid().ToString();
|
||||
//var numberOfWorkingHours = 10.0;
|
||||
//var specializationSalary = 2000.0;
|
||||
//var expectedSalary = (specializationSalary * numberOfWorkingHours);
|
||||
var date = DateTime.UtcNow;
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
var workId = Guid.NewGuid().ToString();
|
||||
var roomId = Guid.NewGuid().ToString();
|
||||
var hours = 10.0;
|
||||
var specSalary = 2000.0;
|
||||
var expected = specSalary * hours;
|
||||
|
||||
//_complitedWorkStorageMock.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string?>(), It.IsAny<string?>(), It.IsAny<string?>()))
|
||||
// .Returns([
|
||||
// new ComplitedWorkDataModel(
|
||||
// Guid.NewGuid().ToString(),
|
||||
// workId,
|
||||
// roomId,
|
||||
// [new WorkerComplitedWorkDataModel(workerId, workId, numberOfWorkingHours)])
|
||||
// ]);
|
||||
var wm = new WorkerDataModel(
|
||||
workerId,
|
||||
"Test Worker",
|
||||
Guid.NewGuid().ToString(),
|
||||
"+7-777-777-77-77",
|
||||
DateTime.UtcNow.AddYears(-30),
|
||||
new SalaryConfiguration { Rate = specSalary }
|
||||
);
|
||||
_workerStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>()))
|
||||
.Returns(new List<WorkerDataModel> { wm });
|
||||
|
||||
//_specializationStorageMock.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
// .Returns(new SpecializationDataModel(Guid.NewGuid().ToString(), "Specialist", specializationSalary, true, DateTime.UtcNow));
|
||||
var cw = new ComplitedWorkDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
workId,
|
||||
roomId,
|
||||
new List<WorkerComplitedWorkDataModel>
|
||||
{
|
||||
new WorkerComplitedWorkDataModel(workerId, workId, hours)
|
||||
}
|
||||
);
|
||||
_complitedWorkStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<DateTime>(),
|
||||
It.IsAny<DateTime>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<string?>()))
|
||||
.Returns(new List<ComplitedWorkDataModel> { cw });
|
||||
|
||||
//_workerStorageMock.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 Worker", Guid.NewGuid().ToString(), "+7-777-777-77-77", DateTime.UtcNow.AddYears(-30))]);
|
||||
_specializationStorageMock
|
||||
.Setup(x => x.GetElementById(wm.SpecializationId))
|
||||
.Returns(new SpecializationDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Specialist",
|
||||
specSalary,
|
||||
true,
|
||||
DateTime.UtcNow));
|
||||
|
||||
//var calculatedSalary = 0.0;
|
||||
double recorded = 0;
|
||||
_salaryStorageMock
|
||||
.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
|
||||
.Callback<SalaryDataModel>(s => recorded = s.Sum);
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
|
||||
// .Callback((SalaryDataModel x) => { calculatedSalary = x.Sum; });
|
||||
_salaryBusinessLogicContract.CalculateSalaryByMonth(date);
|
||||
|
||||
//_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
||||
|
||||
//Assert.That(calculatedSalary, Is.EqualTo(expectedSalary));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMounth_WithSeveralWorkers_Test()
|
||||
{
|
||||
//var workerIds = new List<string> { Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };
|
||||
//var numberOfWorkingHours = new List<double> { 5.0, 8.0, 12.0 };
|
||||
//var specializationSalary = 2000.0;
|
||||
//var expectedSalaries = workerIds.Select((id, index) => (specializationSalary * numberOfWorkingHours[index])).ToList();
|
||||
|
||||
//var workers = workerIds.Select((id, index) => new WorkerDataModel(id, $"Worker {index + 1}", Guid.NewGuid().ToString(), "+7-777-777-77-77", DateTime.UtcNow.AddYears(-30))).ToList();
|
||||
|
||||
//_complitedWorkStorageMock.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
// .Returns(workerIds.Select((id, index) =>
|
||||
// new ComplitedWorkDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(),
|
||||
// [new WorkerComplitedWorkDataModel(id, Guid.NewGuid().ToString(), numberOfWorkingHours[index])])
|
||||
// ).ToList());
|
||||
|
||||
//_specializationStorageMock.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
// .Returns(new SpecializationDataModel(Guid.NewGuid().ToString(), "Specialist", specializationSalary, true, DateTime.UtcNow));
|
||||
|
||||
//_workerStorageMock.Setup(x => x.GetList(It.IsAny<bool>(), It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
|
||||
// .Returns(workers);
|
||||
|
||||
//var calculatedSalaries = new List<double>();
|
||||
|
||||
//_salaryStorageMock.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
|
||||
// .Callback((SalaryDataModel x) => { calculatedSalaries.Add(x.Sum); });
|
||||
|
||||
//_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
||||
|
||||
//Assert.That(calculatedSalaries, Is.EquivalentTo(expectedSalaries));
|
||||
Assert.That(recorded, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMounth_WorkerStorageReturnNull_ThrowException_Test()
|
||||
{
|
||||
//_workerStorageMock.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()));
|
||||
_workerStorageMock.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()));
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMounth_ComplitedWorkStorageReturnNull_ThrowException_Test()
|
||||
{
|
||||
//_complitedWorkStorageMock.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
// .Throws(new StorageException(new InvalidOperationException()));
|
||||
_complitedWorkStorageMock.Setup(x => x.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Throws(new StorageException(new InvalidOperationException()));
|
||||
|
||||
//Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
|
||||
Assert.That(() => _salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow), Throws.TypeOf<StorageException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMonth_OvertimeParallel_StandardAndOvertime_Test()
|
||||
{
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
var hoursWorked = 200.0;
|
||||
var rate = 100.0;
|
||||
var multiplier = 2.0;
|
||||
var overtimeCfg = new OvertimeSalaryConfiguration
|
||||
{
|
||||
Rate = rate,
|
||||
OvertimeMultiplier = multiplier
|
||||
};
|
||||
|
||||
_workerStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>()))
|
||||
.Returns(new List<WorkerDataModel>
|
||||
{
|
||||
new WorkerDataModel(
|
||||
workerId,
|
||||
"Overworker",
|
||||
Guid.NewGuid().ToString(),
|
||||
"+70000000002",
|
||||
DateTime.UtcNow.AddYears(-30),
|
||||
overtimeCfg
|
||||
)
|
||||
});
|
||||
|
||||
var cw = new ComplitedWorkDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"WK",
|
||||
"RM",
|
||||
new List<WorkerComplitedWorkDataModel>
|
||||
{
|
||||
new WorkerComplitedWorkDataModel(workerId, "WK", hoursWorked)
|
||||
}
|
||||
);
|
||||
_complitedWorkStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<DateTime>(),
|
||||
It.IsAny<DateTime>(),
|
||||
workerId,
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<string?>()))
|
||||
.Returns(new List<ComplitedWorkDataModel> { cw });
|
||||
|
||||
_specializationStorageMock
|
||||
.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
.Returns(new SpecializationDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Spec",
|
||||
0,
|
||||
true,
|
||||
DateTime.UtcNow));
|
||||
|
||||
double recorded = 0;
|
||||
_salaryStorageMock
|
||||
.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
|
||||
.Callback<SalaryDataModel>(s => recorded = s.Sum);
|
||||
|
||||
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
||||
|
||||
var expected = 160 * rate + (hoursWorked - 160) * rate * multiplier;
|
||||
Assert.That(recorded, Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CalculateSalaryByMonth_PieceworkParallel_ChunkingAndBonus_Test()
|
||||
{
|
||||
var workerId = Guid.NewGuid().ToString();
|
||||
var units = new List<double> { 5, 7, 4 };
|
||||
|
||||
var unitRate = 100.0;
|
||||
var bonusPerUnit = 10.0;
|
||||
var pieceCfg = new PieceworkSalaryConfiguration
|
||||
{
|
||||
Rate = unitRate,
|
||||
UnitRate = unitRate,
|
||||
BonusPerUnit = bonusPerUnit
|
||||
};
|
||||
|
||||
_workerStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>(),
|
||||
It.IsAny<DateTime?>()))
|
||||
.Returns(new List<WorkerDataModel>
|
||||
{
|
||||
new WorkerDataModel(
|
||||
workerId,
|
||||
"Pieceworker",
|
||||
Guid.NewGuid().ToString(),
|
||||
"+70000000003",
|
||||
DateTime.UtcNow.AddYears(-30),
|
||||
pieceCfg
|
||||
)
|
||||
});
|
||||
|
||||
var cw = new ComplitedWorkDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"W1",
|
||||
"R1",
|
||||
units.Select(u => new WorkerComplitedWorkDataModel(workerId, "W1", u)).ToList()
|
||||
);
|
||||
_complitedWorkStorageMock
|
||||
.Setup(x => x.GetList(
|
||||
It.IsAny<DateTime>(),
|
||||
It.IsAny<DateTime>(),
|
||||
workerId,
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<string?>()))
|
||||
.Returns(new List<ComplitedWorkDataModel> { cw });
|
||||
|
||||
_specializationStorageMock
|
||||
.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||
.Returns(new SpecializationDataModel(
|
||||
Guid.NewGuid().ToString(),
|
||||
"Spec",
|
||||
0,
|
||||
true,
|
||||
DateTime.UtcNow));
|
||||
|
||||
double recorded = 0;
|
||||
_salaryStorageMock
|
||||
.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
|
||||
.Callback<SalaryDataModel>(s => recorded = s.Sum);
|
||||
|
||||
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
||||
|
||||
Assert.That(recorded, Is.EqualTo(1600 + 60));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using TwoFromTheCasketContracts.Infastructure;
|
||||
|
||||
namespace TwoFromTheCasketTests.Infrastructure;
|
||||
|
||||
class ConfigurationSalaryTest : IConfigurationSalary
|
||||
{
|
||||
public int MaxParallelThreads => 4;
|
||||
public double BonusThreshold => 10;
|
||||
}
|
||||
@@ -16,9 +16,10 @@ public static class TwoFromTheCasketDbContextExtensions
|
||||
SalaryConfiguration? configuration = null,
|
||||
string? phone = null,
|
||||
DateTime? birthday = null,
|
||||
DateTime? validFrom = null)
|
||||
DateTime? validFrom = null,
|
||||
SalaryConfiguration? _configuration = null)
|
||||
{
|
||||
var config = configuration ?? new SalaryConfiguration { Rate = 0 };
|
||||
var config = _configuration ?? new SalaryConfiguration { Rate = 1 };
|
||||
|
||||
var worker = new Worker
|
||||
{
|
||||
@@ -125,15 +126,21 @@ public static class TwoFromTheCasketDbContextExtensions
|
||||
return work;
|
||||
}
|
||||
|
||||
public static ComplitedWork InsertComplitedWorkToDatabaseAndReturn(this TwoFromTheCasketDbContext db,
|
||||
string? id = null, string roomId = "room1", string workId = "work1", DateTime? date = null, WorkerComplitedWork? workerComplitedWork = null)
|
||||
public static ComplitedWork InsertComplitedWorkToDatabaseAndReturn(
|
||||
this TwoFromTheCasketDbContext db,
|
||||
string? id = null,
|
||||
string roomId = "room1",
|
||||
string workId = "work1",
|
||||
DateTime? date = null,
|
||||
WorkerComplitedWork? workerComplitedWork = null)
|
||||
{
|
||||
var complited = new ComplitedWork
|
||||
{
|
||||
Id = id ?? Guid.NewGuid().ToString(),
|
||||
RoomId = roomId,
|
||||
WorkId = workId,
|
||||
Date = date ?? DateTime.UtcNow
|
||||
Date = date ?? DateTime.UtcNow,
|
||||
WorkersComplitedWorks = new List<WorkerComplitedWork>()
|
||||
};
|
||||
|
||||
if (workerComplitedWork != null)
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace TwoFromTheCasketTests.StorageContracts
|
||||
public void Try_AddElement_WithPieceworkSalaryConfiguration_Test()
|
||||
{
|
||||
var spec = InsertSpecializationToDatabase(Guid.NewGuid().ToString());
|
||||
var conf = new PieceworkSalaryConfiguration { Rate = 50, UnitRate = 5, BonusThreshold = 100, BonusPerUnit = 2 };
|
||||
var conf = new PieceworkSalaryConfiguration { Rate = 50, UnitRate = 5, BonusPerUnit = 2 };
|
||||
var worker = CreateWorkerDataModel(Guid.NewGuid().ToString(), conf);
|
||||
|
||||
_workerStorageContract.AddElement(worker);
|
||||
@@ -233,7 +233,6 @@ namespace TwoFromTheCasketTests.StorageContracts
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(pw.UnitRate, Is.EqualTo(5));
|
||||
Assert.That(pw.BonusThreshold, Is.EqualTo(100));
|
||||
Assert.That(pw.BonusPerUnit, Is.EqualTo(2));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using TwoFromTheCasketContracts.BindingModels;
|
||||
using TwoFromTheCasketContracts.Infastructure.SalaryConfiguration;
|
||||
using TwoFromTheCasketContracts.ViewModels;
|
||||
using TwoFromTheCasketDatabase.Models;
|
||||
using TwoFromTheCasketTests.Infrastructure;
|
||||
@@ -36,8 +37,10 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
var roomId = Guid.NewGuid().ToString();
|
||||
var complitedId = Guid.NewGuid().ToString();
|
||||
|
||||
var work = TwoFromTheCasketDb.InsertWorkToDatabaseAndReturn(id: workId, date: dateValid);
|
||||
var room = TwoFromTheCasketDb.InsertRoomToDatabaseAndReturn(id: roomId);
|
||||
var work = TwoFromTheCasketDb
|
||||
.InsertWorkToDatabaseAndReturn(id: workId, date: dateValid);
|
||||
var room = TwoFromTheCasketDb
|
||||
.InsertRoomToDatabaseAndReturn(id: roomId);
|
||||
|
||||
var complited = TwoFromTheCasketDb.InsertComplitedWorkToDatabaseAndReturn(
|
||||
id: complitedId,
|
||||
@@ -57,11 +60,79 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
|
||||
var salary = TwoFromTheCasketDb.Salaries.FirstOrDefault(x => x.WorkerId == _worker.Id);
|
||||
var salary = TwoFromTheCasketDb
|
||||
.Salaries
|
||||
.FirstOrDefault(x => x.WorkerId == _worker.Id);
|
||||
Assert.That(salary, Is.Not.Null);
|
||||
Assert.That(salary.Sum, Is.GreaterThan(0));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task Try_Calculate_WithOvertimeConfiguration_Test()
|
||||
{
|
||||
var date = DateTime.UtcNow;
|
||||
var overtime = new OvertimeSalaryConfiguration
|
||||
{
|
||||
Rate = 100,
|
||||
OvertimeMultiplier = 1.75
|
||||
};
|
||||
|
||||
var w = TwoFromTheCasketDb.Workers.First(x => x.Id == _worker.Id);
|
||||
w.Configuration = overtime;
|
||||
TwoFromTheCasketDb.SaveChanges();
|
||||
|
||||
var work = TwoFromTheCasketDb.InsertWorkToDatabaseAndReturn(date: date);
|
||||
var room = TwoFromTheCasketDb.InsertRoomToDatabaseAndReturn();
|
||||
var compl = TwoFromTheCasketDb.InsertComplitedWorkToDatabaseAndReturn(
|
||||
date: date, roomId: room.Id, workId: work.Id);
|
||||
TwoFromTheCasketDb.InsertWorkerComplitedWorkToDatabaseAndReturn(
|
||||
complitedWorkId: compl.Id,
|
||||
workerId: _worker.Id,
|
||||
numberOfWorkingHour: 10
|
||||
);
|
||||
|
||||
var resp = await HttpClient.GetAsync($"/api/Salary/Calculate/{date:O}");
|
||||
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
|
||||
var sal = TwoFromTheCasketDb.Salaries.First(x => x.WorkerId == _worker.Id);
|
||||
Assert.That(sal.Sum, Is.EqualTo(10 * 100 * 1.75));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task Try_Calculate_WithPieceworkConfiguration_Test()
|
||||
{
|
||||
var date = DateTime.UtcNow;
|
||||
var piece = new PieceworkSalaryConfiguration
|
||||
{
|
||||
Rate = 1,
|
||||
UnitRate = 50,
|
||||
BonusPerUnit = 10
|
||||
};
|
||||
|
||||
var w = TwoFromTheCasketDb.Workers.First(x => x.Id == _worker.Id);
|
||||
w.Configuration = piece;
|
||||
TwoFromTheCasketDb.SaveChanges();
|
||||
|
||||
var work = TwoFromTheCasketDb.InsertWorkToDatabaseAndReturn(date: date);
|
||||
var room = TwoFromTheCasketDb.InsertRoomToDatabaseAndReturn();
|
||||
var compl = TwoFromTheCasketDb.InsertComplitedWorkToDatabaseAndReturn(
|
||||
date: date, roomId: room.Id, workId: work.Id);
|
||||
TwoFromTheCasketDb.InsertWorkerComplitedWorkToDatabaseAndReturn(
|
||||
complitedWorkId: compl.Id,
|
||||
workerId: _worker.Id,
|
||||
numberOfWorkingHour: 8
|
||||
);
|
||||
|
||||
var resp = await HttpClient.GetAsync($"/api/Salary/Calculate/{date:O}");
|
||||
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
|
||||
|
||||
var sal = TwoFromTheCasketDb.Salaries.First(x => x.WorkerId == _worker.Id);
|
||||
Assert.That(sal.Sum, Is.EqualTo(430));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task Try_Calculate_WhenNoCompletedWork_Test()
|
||||
{
|
||||
|
||||
@@ -278,7 +278,6 @@ public class WorkerControllerTest : BaseWebApiControllerTest
|
||||
{
|
||||
Rate = 80,
|
||||
UnitRate = 7,
|
||||
BonusThreshold = 50,
|
||||
BonusPerUnit = 1.5
|
||||
};
|
||||
var json = JsonConvert.SerializeObject(piecework);
|
||||
@@ -311,7 +310,6 @@ public class WorkerControllerTest : BaseWebApiControllerTest
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(pw.UnitRate, Is.EqualTo(7));
|
||||
Assert.That(pw.BonusThreshold, Is.EqualTo(50));
|
||||
Assert.That(pw.BonusPerUnit, Is.EqualTo(1.5));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Configuration;
|
||||
using TwoFromTheCasketContracts.Infastructure;
|
||||
|
||||
namespace TwoFromTheCasketWebApi.Infrastructure;
|
||||
|
||||
public class ConfigurationSalary(IConfiguration configuration) : IConfigurationSalary
|
||||
{
|
||||
private readonly Lazy<SalarySettings> _SalarySettings = new(() =>
|
||||
{
|
||||
return configuration.GetValue<SalarySettings>("SalarySettings") ?? throw new InvalidDataException(nameof(SalarySettings));
|
||||
});
|
||||
|
||||
public int MaxParallelThreads => _SalarySettings.Value.MaxParallelThreads;
|
||||
|
||||
public double BonusThreshold => _SalarySettings.Value.BonusThreshold;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TwoFromTheCasketWebApi.Infrastructure;
|
||||
public class SalarySettings
|
||||
{
|
||||
public int MaxParallelThreads { get; set; }
|
||||
public double BonusThreshold { get; set; }
|
||||
}
|
||||
@@ -55,6 +55,7 @@ public class Program
|
||||
builder.Services.AddOpenApi();
|
||||
|
||||
builder.Services.AddSingleton<IConfigurationDatabase, ConfigurationDatabase>();
|
||||
builder.Services.AddSingleton<IConfigurationSalary, ConfigurationSalary>();
|
||||
|
||||
builder.Services.AddTransient<TwoFromTheCasketDbContext>();
|
||||
|
||||
|
||||
@@ -24,5 +24,9 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"AllowedHosts": "*",
|
||||
"SalarySettings": {
|
||||
"MaxParallelThreads": 4,
|
||||
"BonusThreshold": 10
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user