Реализация Salary

This commit is contained in:
2025-04-24 09:18:01 +04:00
parent bb6387e6eb
commit dca7a5752d
12 changed files with 607 additions and 178 deletions

View File

@@ -0,0 +1,13 @@
using TheBlacksmithVakulaContract.AdapterContracts.OperationResponses;
namespace TheBlacksmithVakulaContract.AdapterContracts
{
public interface ISalaryAdapter
{
SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetListByPeriodByBlacksmith(DateTime fromDate, DateTime toDate, string blacksmithId);
SalaryOperationResponse CalculateSalary(DateTime date);
}
}

View File

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

View File

@@ -6,12 +6,21 @@ namespace TheBlacksmithVakulaContract.DataModels
{
public class SalaryDataModel(string blacksmithId, DateTime salaryDate, double blacksmithSalary) : IValidation
{
private readonly BlacksmithDataModel? _blacksmith;
public string BlacksmithId { get; private set; } = blacksmithId;
public DateTime SalaryDate { get; private set; } = salaryDate;
public double Salary { get; private set; } = blacksmithSalary;
public string BlacksmithFIO => _blacksmith?.FIO ?? string.Empty;
public SalaryDataModel(string blacksmithId, DateTime salaryDate, double blacksmithSalary, BlacksmithDataModel blacksmith) : this(blacksmithId, salaryDate, blacksmithSalary)
{
_blacksmith = blacksmith;
}
public void Validate()
{
if (BlacksmithId.IsEmpty())

View File

@@ -0,0 +1,13 @@
namespace TheBlacksmithVakulaContract.ViewModels
{
public class SalaryViewModel
{
public required string BlacksmithId { get; set; }
public required string BlacksmithFIO { get; set; }
public DateTime SalaryDate { get; set; }
public double Salary { get; set; }
}
}

View File

@@ -1,54 +1,59 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using TheBlacksmithVakulaContract.DataModels;
using TheBlacksmithVakulaContract.Exceptions;
using TheBlacksmithVakulaContract.StoragesContracts;
using TheBlacksmithVakulaDatabase.Models;
namespace TheBlacksmithVakulaDatabase.Implementations
namespace TheBlacksmithVakulaDatabase.Implementations;
internal class SalaryStorageContract : ISalaryStorageContract
{
internal class SalaryStorageContract : ISalaryStorageContract
private readonly TheBlacksmithVakulaDbContext _dbContext;
private readonly Mapper _mapper;
public SalaryStorageContract(TheBlacksmithVakulaDbContext dbContext)
{
private readonly TheBlacksmithVakulaDbContext _dbContext;
private readonly Mapper _mapper;
public SalaryStorageContract(TheBlacksmithVakulaDbContext dbContext)
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(Salary));
cfg.CreateMap<Blacksmith, BlacksmithDataModel>();
cfg.CreateMap<Salary, SalaryDataModel>();
cfg.CreateMap<SalaryDataModel, Salary>()
.ForMember(dest => dest.BlacksmithSalary, opt => opt.MapFrom(src => src.Salary));
});
_mapper = new Mapper(config);
}
});
_mapper = new Mapper(config);
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? blacksmithId = null)
{
try
{
var query = _dbContext.Salaries.Include(x => x.Blacksmith).Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate);
if (blacksmithId is not null)
{
query = query.Where(x => x.BlacksmithId == blacksmithId);
}
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
}
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? blacksmithId = null)
catch (Exception ex)
{
try
{
var query = _dbContext.Salaries.Where(x => x.SalaryDate >= startDate && x.SalaryDate <= endDate);
if (blacksmithId is not null) query = query.Where(x => x.BlacksmithId == blacksmithId);
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void AddElement(SalaryDataModel salaryDataModel)
public void AddElement(SalaryDataModel salaryDataModel)
{
try
{
try
{
_dbContext.Salaries.Add(_mapper.Map<Salary>(salaryDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
_dbContext.Salaries.Add(_mapper.Map<Salary>(salaryDataModel));
_dbContext.SaveChanges();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
}

View File

@@ -4,9 +4,16 @@ using TheBlacksmithVakulaDatabase.Models;
namespace TheBlacksmithVakulaDatabase
{
internal class TheBlacksmithVakulaDbContext(IConfigurationDatabase configurationDatabase) : DbContext
internal class TheBlacksmithVakulaDbContext : DbContext
{
private readonly IConfigurationDatabase? _configurationDatabase = configurationDatabase;
private readonly IConfigurationDatabase? _configurationDatabase;
public TheBlacksmithVakulaDbContext(IConfigurationDatabase configurationDatabase)
{
_configurationDatabase = configurationDatabase;
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{

View File

@@ -23,7 +23,7 @@ namespace TheBlacksmithVakulaTests.Infrastructure
return billet;
}
public static Rank InsertRankToDatabaseAndReturn(this TheBlacksmithVakulaDbContext dbContext, string? id = null, string rankName = "test", RankType rankType = RankType.Expert, double salary = 10, bool isActual = true, DateTime? changeDate = null)
public static Rank InsertRankToDatabaseAndReturn(this TheBlacksmithVakulaDbContext dbContext, string? id = null, string rankName = "test", RankType rankType = RankType.Expert, bool isActual = true, DateTime? changeDate = null)
{
var rank = new Rank() { Id = Guid.NewGuid().ToString(), RankId = id ?? Guid.NewGuid().ToString(), RankName = rankName, RankType = rankType, IsActual = isActual, ChangeDate = changeDate ?? DateTime.UtcNow };
dbContext.Ranks.Add(rank);
@@ -49,7 +49,7 @@ namespace TheBlacksmithVakulaTests.Infrastructure
public static Salary InsertSalaryToDatabaseAndReturn(this TheBlacksmithVakulaDbContext dbContext, string blacksmithId, double blacksmithSalary = 1, DateTime? salaryDate = null)
{
var salary = new Salary() { BlacksmithId = blacksmithId, BlacksmithSalary = blacksmithSalary, SalaryDate = salaryDate ?? DateTime.UtcNow };
var salary = new Salary() { Id = Guid.NewGuid().ToString(), BlacksmithId = blacksmithId, BlacksmithSalary = blacksmithSalary, SalaryDate = salaryDate ?? DateTime.UtcNow };
dbContext.Salaries.Add(salary);
dbContext.SaveChanges();
return salary;

View File

@@ -1,157 +1,130 @@
using Microsoft.EntityFrameworkCore;
using TheBlacksmithVakulaContract.DataModels;
using TheBlacksmithVakulaContract.DataModels;
using TheBlacksmithVakulaDatabase.Implementations;
using TheBlacksmithVakulaDatabase.Models;
using TheBlacksmithVakulaTests.Infrastructure;
namespace TheBlacksmithVakulaTests.StrorageContractTests
namespace TheBlacksmithVakulaTests.StrorageContractTests;
[TestFixture]
internal class SalaryStorageContractTests : BaseStorageContractTest
{
[TestFixture]
internal class SalaryStorageContractTests : BaseStorageContractTest
private SalaryStorageContract _salaryStorageContract;
private Blacksmith _blacksmith;
[SetUp]
public void SetUp()
{
private SalaryStorageContract _salaryStorageContract;
private Blacksmith _blacksmith;
_salaryStorageContract = new SalaryStorageContract(TheBlacksmithVakulaDbContext);
_blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn();
}
[SetUp]
public void SetUp()
{
_salaryStorageContract = new SalaryStorageContract(TheBlacksmithVakulaDbContext);
_blacksmith = InsertBlacksmithToDatabaseAndReturn();
}
[TearDown]
public void TearDown()
{
TheBlacksmithVakulaDbContext.RemoveSalariesFromDatabase();
TheBlacksmithVakulaDbContext.RemoveBlacksmithsFromDatabase();
}
[TearDown]
public void TearDown()
{
TheBlacksmithVakulaDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Salaries\"CASCADE; ");
TheBlacksmithVakulaDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Blacksmiths\"CASCADE; ");
}
[Test]
public void Try_GetList_WhenHaveRecords_Test()
{
var salary = TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, blacksmithSalary: 100);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10));
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.Single(x => x.Salary == salary.BlacksmithSalary), salary);
}
[Test]
public void Try_GetList_WhenHaveRecords_Test()
{
var salary = InsertSalaryToDatabaseAndReturn(_blacksmith.Id, blacksmithSalary: 100);
InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10));
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(), salary);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10));
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
[Test]
public void Try_GetList_OnlyInDatePeriod_Test()
{
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1));
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
{
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10));
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetList_OnlyInDatePeriod_Test()
{
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1));
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(2));
}
});
}
[Test]
public void Try_GetList_ByBlacksmith_Test()
[Test]
public void Try_GetList_ByBlacksmith_Test()
{
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id);
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _blacksmith.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
{
var blacksmith = InsertBlacksmithToDatabaseAndReturn("name 2");
InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
InsertSalaryToDatabaseAndReturn(_blacksmith.Id);
InsertSalaryToDatabaseAndReturn(blacksmith.Id);
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _blacksmith.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(list, Has.Count.EqualTo(2));
Assert.That(list.All(x => x.BlacksmithId == _blacksmith.Id));
});
}
Assert.That(list, Has.Count.EqualTo(2));
Assert.That(list.All(x => x.BlacksmithId == _blacksmith.Id));
});
}
[Test]
public void Try_GetList_ByBlacksmithOnlyInDatePeriod_Test()
[Test]
public void Try_GetList_ByBlacksmithOnlyInDatePeriod_Test()
{
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _blacksmith.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
{
var blacksmith = InsertBlacksmithToDatabaseAndReturn("name 2");
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
InsertSalaryToDatabaseAndReturn(_blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
var list = _salaryStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _blacksmith.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(list, Has.Count.EqualTo(2));
Assert.That(list.All(x => x.BlacksmithId == _blacksmith.Id));
});
}
Assert.That(list, Has.Count.EqualTo(2));
Assert.That(list.All(x => x.BlacksmithId == _blacksmith.Id));
});
}
[Test]
public void Try_AddElement_Test()
[Test]
public void Try_AddElement_Test()
{
var salary = CreateModel(_blacksmith.Id);
_salaryStorageContract.AddElement(salary);
AssertElement(TheBlacksmithVakulaDbContext.GetSalariesFromDatabaseByBlacksmithId(_blacksmith.Id).First(), salary);
}
private static void AssertElement(SalaryDataModel? actual, Salary expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
var salary = CreateModel(_blacksmith.Id);
_salaryStorageContract.AddElement(salary);
AssertElement(GetSalaryFromDatabaseByBlacksmithId(_blacksmith.Id), salary);
}
Assert.That(actual.BlacksmithId, Is.EqualTo(expected.BlacksmithId));
Assert.That(actual.Salary, Is.EqualTo(expected.BlacksmithSalary));
});
}
private Blacksmith InsertBlacksmithToDatabaseAndReturn(string blacksmithFIO = "fio")
private static SalaryDataModel CreateModel(string blacksmithId, double blacksmithSalary = 1, DateTime? salaryDate = null)
=> new(blacksmithId, salaryDate ?? DateTime.UtcNow, blacksmithSalary);
private static void AssertElement(Salary? actual, SalaryDataModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
var blacksmith = new Blacksmith()
{
Id = Guid.NewGuid().ToString(),
RankId = Guid.NewGuid().ToString(),
FIO = blacksmithFIO,
IsDeleted = false
};
TheBlacksmithVakulaDbContext.Blacksmiths.Add(blacksmith);
TheBlacksmithVakulaDbContext.SaveChanges();
return blacksmith;
}
private Salary InsertSalaryToDatabaseAndReturn(string blacksmithId, double blacksmithSalary = 1, DateTime? salaryDate = null)
{
var salary = new Salary()
{
BlacksmithId = blacksmithId,
BlacksmithSalary = blacksmithSalary,
SalaryDate = salaryDate ?? DateTime.UtcNow
};
TheBlacksmithVakulaDbContext.Salaries.Add(salary);
TheBlacksmithVakulaDbContext.SaveChanges();
return salary;
}
private static void AssertElement(SalaryDataModel? actual, Salary expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.BlacksmithId, Is.EqualTo(expected.BlacksmithId));
Assert.That(actual.Salary, Is.EqualTo(expected.BlacksmithSalary));
});
}
private static SalaryDataModel CreateModel(string blacksmithId, double blacksmithSalary = 1, DateTime? salaryDate = null)
=> new(blacksmithId, salaryDate ?? DateTime.UtcNow, blacksmithSalary);
private Salary? GetSalaryFromDatabaseByBlacksmithId(string id)
=> TheBlacksmithVakulaDbContext.Salaries.FirstOrDefault(x => x.BlacksmithId == id);
private static void AssertElement(Salary? actual, SalaryDataModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.BlacksmithId, Is.EqualTo(expected.BlacksmithId));
Assert.That(actual.BlacksmithSalary, Is.EqualTo(expected.Salary));
});
}
Assert.That(actual.BlacksmithId, Is.EqualTo(expected.BlacksmithId));
Assert.That(actual.BlacksmithSalary, Is.EqualTo(expected.Salary));
});
}
}

View File

@@ -0,0 +1,240 @@
using System.Net;
using TheBlacksmithVakulaContract.ViewModels;
using TheBlacksmithVakulaDatabase.Models;
using TheBlacksmithVakulaTests.Infrastructure;
namespace TheBlacksmithVakulaTests.WebApiControllersTests
{
[TestFixture]
internal class SalaryControllerTests : BaseWebApiControllerTest
{
[TearDown]
public void TearDown()
{
TheBlacksmithVakulaDbContext.RemoveRanksFromDatabase();
TheBlacksmithVakulaDbContext.RemoveOrdersFromDatabase();
TheBlacksmithVakulaDbContext.RemoveProductsFromDatabase();
TheBlacksmithVakulaDbContext.RemoveBilletsFromDatabase();
TheBlacksmithVakulaDbContext.RemoveSalariesFromDatabase();
TheBlacksmithVakulaDbContext.RemoveBlacksmithsFromDatabase();
}
[Test]
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name");
var salary = TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, blacksmithSalary: 100);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id);
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
});
AssertElement(data.First(x => x.Salary == salary.BlacksmithSalary), salary);
}
[Test]
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
});
}
[Test]
public async Task GetList_OnlyInDatePeriod_ShouldSuccess_Test()
{
//Arrange
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name");
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
});
}
[Test]
public async Task GetList_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getblacksmithrecords?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByBlacksmith_ShouldSuccess_Test()
{
//Arrange
var blacksmith1 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 1");
var blacksmith2 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id);
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith2.Id);
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getblacksmithrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&id={blacksmith1.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => x.BlacksmithId == blacksmith1.Id));
});
}
[Test]
public async Task GetList_ByBlacksmith_OnlyInDatePeriod_ShouldSuccess_Test()
{
//Arrange
var blacksmith1 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 1");
var blacksmith2 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith2.Id, salaryDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith2.Id, salaryDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
TheBlacksmithVakulaDbContext.InsertSalaryToDatabaseAndReturn(blacksmith1.Id, salaryDate: DateTime.UtcNow.AddDays(-2));
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getblacksmithrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&id={blacksmith1.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SalaryViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => x.BlacksmithId == blacksmith1.Id));
});
}
[Test]
public async Task GetList_ByBlacksmith_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 1");
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getblacksmithrecords?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&id={blacksmith.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByBlacksmith_WhenIdIsNotGuid_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/salaries/getblacksmithrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&id=id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Calculate_ShouldSuccess_Test()
{
//Arrange
var blacksmith = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name");
var billet = TheBlacksmithVakulaDbContext.InsertBilletToDatabaseAndReturn();
var product = TheBlacksmithVakulaDbContext.InsertProductToDatabaseAndReturn(billet.Id, price: 100);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith.Id, null, sum: 2000, products: [(product.Id, 10)]);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith.Id, null, sum: 2000, products: [(product.Id, 10)]);
//Act
var response = await HttpClient.PostAsync($"/api/salaries/calculate?date={DateTime.UtcNow:MM/dd/yyyy}", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
var salary = TheBlacksmithVakulaDbContext.GetSalariesFromDatabaseByBlacksmithId(blacksmith.Id);
Assert.Multiple(() =>
{
Assert.That(salary, Has.Length.EqualTo(1));
Assert.That(salary.First().BlacksmithSalary, Is.EqualTo(2000));
Assert.That(salary.First().SalaryDate.Month, Is.EqualTo(DateTime.UtcNow.Month));
});
}
[Test]
public async Task Calculate_WithSeveralBlacksmiths_ShouldSuccess_Test()
{
//Arrange
var blacksmith1 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 1");
var blacksmith2 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
var blacksmith3 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 3");
var billet = TheBlacksmithVakulaDbContext.InsertBilletToDatabaseAndReturn();
var product = TheBlacksmithVakulaDbContext.InsertProductToDatabaseAndReturn(billet.Id, price: 100);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith1.Id, null, sum: 2000, products: [(product.Id, 10)]);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith1.Id, null, sum: 2000, products: [(product.Id, 10)]);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith2.Id, null, sum: 2000, products: [(product.Id, 10)]);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith3.Id, null, sum: 2000, products: [(product.Id, 10)]);
//Act
var response = await HttpClient.PostAsync($"/api/salaries/calculate?date={DateTime.UtcNow:MM/dd/yyyy}", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
var salary = TheBlacksmithVakulaDbContext.Salaries.ToArray();
Assert.That(salary, Has.Length.EqualTo(3));
}
[Test]
public async Task Calculate_WithoutBlacksmiths_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/salaries/calculate?date={DateTime.UtcNow:MM/dd/yyyy}", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
var salary = TheBlacksmithVakulaDbContext.Salaries.ToArray();
Assert.That(salary, Has.Length.EqualTo(0));
}
[Test]
public async Task Calculate_WithoutOrdersByBlacksmith_ShouldSuccess_Test()
{
//Arrange
var blacksmith1 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 1");
var blacksmith2 = TheBlacksmithVakulaDbContext.InsertBlacksmithToDatabaseAndReturn(fio: "name 2");
var billet = TheBlacksmithVakulaDbContext.InsertBilletToDatabaseAndReturn();
var product = TheBlacksmithVakulaDbContext.InsertProductToDatabaseAndReturn(billet.Id, price: 100);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith1.Id, null, orderDate: DateTime.UtcNow.AddMonths(-1), sum: 2000, products: [(product.Id, 10)]);
TheBlacksmithVakulaDbContext.InsertOrderToDatabaseAndReturn(blacksmith2.Id, null, sum: 2000, products: [(product.Id, 10)]);
//Act
var response = await HttpClient.PostAsync($"/api/salaries/calculate?date={DateTime.UtcNow:MM/dd/yyyy}", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
var salary1 = TheBlacksmithVakulaDbContext.GetSalariesFromDatabaseByBlacksmithId(blacksmith1.Id).First().BlacksmithSalary;
var salary2 = TheBlacksmithVakulaDbContext.GetSalariesFromDatabaseByBlacksmithId(blacksmith2.Id).First().BlacksmithSalary;
Assert.That(salary1, Is.Not.EqualTo(salary2));
}
private static void AssertElement(SalaryViewModel? actual, Salary expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.BlacksmithFIO, Is.EqualTo(expected.Blacksmith!.FIO));
Assert.That(actual.Salary, Is.EqualTo(expected.BlacksmithSalary));
});
}
}
}

View File

@@ -0,0 +1,120 @@
using AutoMapper;
using TheBlacksmithVakulaContract.AdapterContracts;
using TheBlacksmithVakulaContract.AdapterContracts.OperationResponses;
using TheBlacksmithVakulaContract.BusinessLogicsContracts;
using TheBlacksmithVakulaContract.DataModels;
using TheBlacksmithVakulaContract.Exceptions;
using TheBlacksmithVakulaContract.ViewModels;
namespace TheBlacksmithVakulaWebApi.Adapters
{
public class SalaryAdapter : ISalaryAdapter
{
private readonly ISalaryBusinessLogicContract _salaryBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public SalaryAdapter(ISalaryBusinessLogicContract salaryBusinessLogicContract, ILogger<SalaryAdapter> logger)
{
_salaryBusinessLogicContract = salaryBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SalaryDataModel, SalaryViewModel>();
});
_mapper = new Mapper(config);
}
public SalaryOperationResponse GetListByPeriod(DateTime fromDate, DateTime toDate)
{
try
{
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriod(fromDate, toDate).Select(x => _mapper.Map<SalaryViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SalaryOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SalaryOperationResponse.InternalServerError(ex.Message);
}
}
public SalaryOperationResponse GetListByPeriodByBlacksmith(DateTime fromDate, DateTime toDate, string blacksmithId)
{
try
{
return SalaryOperationResponse.OK([.. _salaryBusinessLogicContract.GetAllSalariesByPeriodByBlacksmith(fromDate, toDate, blacksmithId).Select(x => _mapper.Map<SalaryViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SalaryOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SalaryOperationResponse.InternalServerError(ex.Message);
}
}
public SalaryOperationResponse CalculateSalary(DateTime date)
{
try
{
_salaryBusinessLogicContract.CalculateSalaryByMounth(date);
return SalaryOperationResponse.NoContent();
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SalaryOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SalaryOperationResponse.InternalServerError(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using TheBlacksmithVakulaContract.AdapterContracts;
namespace TheBlacksmithVakulaWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class SalariesController(ISalaryAdapter adapter) : ControllerBase
{
private readonly ISalaryAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(DateTime fromDate, DateTime toDate)
{
return _adapter.GetListByPeriod(fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetBlacksmithRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetListByPeriodByBlacksmith(fromDate, toDate, id).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Calculate(DateTime date)
{
return _adapter.CalculateSalary(date).GetResponse(Request, Response);
}
}

View File

@@ -68,13 +68,12 @@ builder.Services.AddTransient<IRankAdapter, RankAdapter>();
builder.Services.AddTransient<IProductAdapter, ProductAdapter>();
builder.Services.AddTransient<IOrderAdapter, OrderAdapter>();
builder.Services.AddTransient<IBlacksmithAdapter, BlacksmithAdapter>();
builder.Services.AddTransient<ISalaryAdapter, SalaryAdapter>();
builder.Services.AddOpenApi();
var app = builder.Build();
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{