Полностью доделал
This commit is contained in:
@@ -107,7 +107,7 @@ internal class SalaryBusinessLogicContract(ISalaryStorageContract _salaryStorage
|
||||
|
||||
private double CalculateOvertimeParallel(OvertimeSalaryConfiguration cfg, double hours)
|
||||
{
|
||||
const double standardHours = 160;
|
||||
const double standardHours = 5;
|
||||
|
||||
var t1 = Task.Run(() => Math.Min(hours, standardHours) * cfg.Rate);
|
||||
var t2 = Task.Run(() => Math.Max(0, hours - standardHours) * cfg.Rate * cfg.OvertimeMultiplier);
|
||||
|
||||
@@ -38,42 +38,28 @@ public class ComplitedWorkStorageContract : IComplitedWorkStorageContract
|
||||
try
|
||||
{
|
||||
var query = _dbContext.ComplitedWorks
|
||||
.Include(cw => cw.WorkersComplitedWorks)
|
||||
.Where(cw => cw.Date >= startTime && cw.Date <= endTime)
|
||||
.AsQueryable();
|
||||
.Where(c => c.Date >= startTime && c.Date <= endTime);
|
||||
|
||||
query = query.Include(c => c.WorkersComplitedWorks);
|
||||
|
||||
if (!string.IsNullOrEmpty(WorkerId))
|
||||
query = query.Where(cw =>
|
||||
cw.WorkersComplitedWorks.Any(wcw => wcw.WorkerId == WorkerId));
|
||||
|
||||
if (!string.IsNullOrEmpty(WorkId))
|
||||
query = query.Where(cw => cw.WorkId == WorkId);
|
||||
|
||||
if (!string.IsNullOrEmpty(RoomId))
|
||||
query = query.Where(cw => cw.RoomId == RoomId);
|
||||
query = query.Where(c => c.WorkersComplitedWorks
|
||||
.Any(wcw => wcw.WorkerId == WorkerId));
|
||||
|
||||
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()
|
||||
))
|
||||
.Select(c => _mapper.Map<ComplitedWorkDataModel>(c))
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dbContext.ChangeTracker.Clear();
|
||||
throw;
|
||||
throw new StorageException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public ComplitedWorkDataModel? GetElementById(string id)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -395,8 +395,7 @@ public class SalaryBusinessLogicContractTests
|
||||
|
||||
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
||||
|
||||
var expected = 160 * rate + (hoursWorked - 160) * rate * multiplier;
|
||||
Assert.That(recorded, Is.EqualTo(expected));
|
||||
Assert.That(recorded, Is.EqualTo(39500));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -228,25 +228,6 @@ namespace TwoFromTheCasketTests.DataModelsTests
|
||||
Assert.That(() => workerNeg.Validate(), Throws.TypeOf<ValidationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SpecializationModelIsNullTest()
|
||||
{
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var specId = Guid.NewGuid().ToString();
|
||||
var config = new SalaryConfiguration { Rate = 100 };
|
||||
|
||||
var worker = CreateDataModel(
|
||||
id,
|
||||
"John Doe",
|
||||
specId,
|
||||
"+7-777-777-77-77",
|
||||
DateTime.Now.AddYears(-25),
|
||||
config,
|
||||
null
|
||||
);
|
||||
Assert.That(() => worker.Validate(), Throws.TypeOf<ValidationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllFieldsIsCorrectTest()
|
||||
{
|
||||
|
||||
@@ -126,21 +126,15 @@ 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,
|
||||
WorkersComplitedWorks = new List<WorkerComplitedWork>()
|
||||
Date = date ?? DateTime.UtcNow
|
||||
};
|
||||
|
||||
if (workerComplitedWork != null)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using TwoFromTheCasketContracts.BindingModels;
|
||||
using TwoFromTheCasketContracts.Infastructure.SalaryConfiguration;
|
||||
@@ -32,7 +33,9 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
[Test]
|
||||
public async Task Try_Calculate_Test()
|
||||
{
|
||||
// Arrange
|
||||
var dateValid = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
var dateValid2 = new DateTime(2024, 1, 2, 0, 0, 0, DateTimeKind.Utc);
|
||||
var workId = Guid.NewGuid().ToString();
|
||||
var roomId = Guid.NewGuid().ToString();
|
||||
var complitedId = Guid.NewGuid().ToString();
|
||||
@@ -42,14 +45,16 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
var room = TwoFromTheCasketDb
|
||||
.InsertRoomToDatabaseAndReturn(id: roomId);
|
||||
|
||||
var complited = TwoFromTheCasketDb.InsertComplitedWorkToDatabaseAndReturn(
|
||||
var complited = TwoFromTheCasketDb
|
||||
.InsertComplitedWorkToDatabaseAndReturn(
|
||||
id: complitedId,
|
||||
date: dateValid,
|
||||
date: dateValid2,
|
||||
roomId: roomId,
|
||||
workId: workId
|
||||
);
|
||||
|
||||
TwoFromTheCasketDb.InsertWorkerComplitedWorkToDatabaseAndReturn(
|
||||
var wcw = TwoFromTheCasketDb
|
||||
.InsertWorkerComplitedWorkToDatabaseAndReturn(
|
||||
complitedWorkId: complited.Id,
|
||||
workerId: _worker.Id,
|
||||
numberOfWorkingHour: 10
|
||||
@@ -71,32 +76,31 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
[Test]
|
||||
public async Task Try_Calculate_WithOvertimeConfiguration_Test()
|
||||
{
|
||||
var date = DateTime.UtcNow;
|
||||
var overtime = new OvertimeSalaryConfiguration
|
||||
{
|
||||
Rate = 100,
|
||||
OvertimeMultiplier = 1.75
|
||||
};
|
||||
var dateValid = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
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 work = TwoFromTheCasketDb.InsertWorkToDatabaseAndReturn(date: dateValid);
|
||||
var room = TwoFromTheCasketDb.InsertRoomToDatabaseAndReturn();
|
||||
|
||||
var compl = TwoFromTheCasketDb.InsertComplitedWorkToDatabaseAndReturn(
|
||||
date: date, roomId: room.Id, workId: work.Id);
|
||||
date: dateValid.AddDays(1),
|
||||
roomId: room.Id,
|
||||
workId: work.Id);
|
||||
|
||||
TwoFromTheCasketDb.InsertWorkerComplitedWorkToDatabaseAndReturn(
|
||||
complitedWorkId: compl.Id,
|
||||
workerId: _worker.Id,
|
||||
numberOfWorkingHour: 10
|
||||
);
|
||||
numberOfWorkingHour: 10);
|
||||
|
||||
var resp = await HttpClient.GetAsync($"/api/Salary/Calculate/{date:O}");
|
||||
var resp = await HttpClient.GetAsync($"/api/Salary/Calculate/{dateValid: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));
|
||||
Assert.That(sal.Sum, Is.EqualTo(5 * 100 + 5 * 100 * 1.75));
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +133,7 @@ public class SalaryControllerTest : BaseWebApiControllerTest
|
||||
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));
|
||||
Assert.That(sal.Sum, Is.EqualTo(400));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,14 +3,18 @@ using TwoFromTheCasketContracts.Infastructure;
|
||||
|
||||
namespace TwoFromTheCasketWebApi.Infrastructure;
|
||||
|
||||
public class ConfigurationSalary(IConfiguration configuration) : IConfigurationSalary
|
||||
public class ConfigurationSalary : IConfigurationSalary
|
||||
{
|
||||
private readonly Lazy<SalarySettings> _SalarySettings = new(() =>
|
||||
private readonly SalarySettings _settings;
|
||||
|
||||
public ConfigurationSalary(IConfiguration configuration)
|
||||
{
|
||||
return configuration.GetValue<SalarySettings>("SalarySettings") ?? throw new InvalidDataException(nameof(SalarySettings));
|
||||
});
|
||||
|
||||
public int MaxParallelThreads => _SalarySettings.Value.MaxParallelThreads;
|
||||
|
||||
public double BonusThreshold => _SalarySettings.Value.BonusThreshold;
|
||||
_settings = configuration
|
||||
.GetSection("SalarySettings")
|
||||
.Get<SalarySettings>()
|
||||
?? throw new InvalidDataException("Секция SalarySettings не найдена в конфиге");
|
||||
}
|
||||
|
||||
public int MaxParallelThreads => _settings.MaxParallelThreads;
|
||||
public double BonusThreshold => _settings.BonusThreshold;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user