готовая усложненная

This commit is contained in:
2025-04-20 17:33:35 +04:00
parent 3875eaa4e4
commit 20fd6e399e
10 changed files with 174 additions and 33 deletions

View File

@@ -122,4 +122,35 @@ public class SaleBusinessLogicContract(ISaleStorageContract saleStorageContract,
}
_saleStorageContract.DelElement(id);
}
//третье требование
public double CalculateSaleRevenue(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("CalculateSaleRevenue params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
var sales = GetAllSalesByPeriod(fromDate, toDate);
if (sales == null || !sales.Any())
{
return 0;
}
double totalRevenue = 0;
object lockObj = new object();
Parallel.ForEach(sales, sale =>
{
if (sale.IsCancel)
return;
lock (lockObj)
{
totalRevenue += sale.Sum;
}
});
_logger.LogInformation("Total revenue calculated: {totalRevenue}", totalRevenue);
return totalRevenue;
}
}

View File

@@ -23,8 +23,6 @@ public class SuppliesBusinessLogicContract(ISuppliesStorageContract suppliesStor
{
_logger.LogInformation("GetAllComponents");
return _suppliesStorageContract.GetList() ?? throw new NullListException();
return [];
}
public SuppliesDataModel GetComponentByData(string data)
@@ -39,8 +37,6 @@ public class SuppliesBusinessLogicContract(ISuppliesStorageContract suppliesStor
throw new ElementNotFoundException(data);
}
return _suppliesStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
return new("", TourType.None, DateTime.UtcNow, 0, []);
}
public void InsertComponent(SuppliesDataModel suppliesDataModel)
@@ -58,4 +54,24 @@ public class SuppliesBusinessLogicContract(ISuppliesStorageContract suppliesStor
suppliesDataModel.Validate();
_suppliesStorageContract.UpdElement(suppliesDataModel);
}
//первое требование
public int CalculateTourSupplies(DateTime? startDate, DateTime? endDate)
{
var supplies = _suppliesStorageContract.GetList(startDate, endDate);
if (supplies == null || supplies.Count == 0)
{
return 0;
}
int count = 0;
var lockObject = new object();
Parallel.ForEach(supplies, supply =>
{
int supplyCount = supply.Tours.Sum(component => component.Count);
lock (lockObject)
{
count += supplyCount;
}
});
return count;
}
}

View File

@@ -22,4 +22,6 @@ public interface ISaleBusinessLogicContract
void InsertSale(SaleDataModel saleDataModel);
void CancelSale(string id);
public double CalculateSaleRevenue(DateTime fromDate, DateTime toDate);
}

View File

@@ -13,4 +13,5 @@ public interface ISuppliesBusinessLogicContract
SuppliesDataModel GetComponentByData(string data);
void InsertComponent(SuppliesDataModel componentDataModel);
void UpdateComponent(SuppliesDataModel componentDataModel);
int CalculateTourSupplies(DateTime? startDate, DateTime? endDate);
}

View File

@@ -9,7 +9,7 @@ namespace MagicCarpetContracts.StoragesContracts;
public interface ISuppliesStorageContract
{
List<SuppliesDataModel> GetList(DateTime? startDate = null);
List<SuppliesDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null);
SuppliesDataModel GetElementById(string id);
void AddElement(SuppliesDataModel suppliesDataModel);
void UpdElement(SuppliesDataModel suppliesDataModel);

View File

@@ -3,6 +3,7 @@ using MagicCarpetContracts.DataModels;
using MagicCarpetContracts.Exceptions;
using MagicCarpetContracts.StoragesContracts;
using MagicCarpetDatabase.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -106,30 +107,37 @@ public class AgencyStorageContract : IAgencyStorageContract
throw new StorageException(ex);
}
}
//второе требование
public bool CheckComponents(SaleDataModel saleDataModel)
{
using (var transaction = _dbContext.Database.BeginTransaction())
{
foreach (SaleTourDataModel sale_tour in saleDataModel.Tours)
{
var tour = _dbContext.Tours.FirstOrDefault(x => x.Id == sale_tour.TourId);
var agency = _dbContext.Agencies.FirstOrDefault(x => x.TourType == tour.TourType && x.Count >= sale_tour.Count);
var componentTasks = saleDataModel.Tours
.AsParallel()
.Select(async saleComponent =>
{
var component = await _dbContext.Tours.FirstOrDefaultAsync(x => x.Id == saleComponent.TourId);
var agency = await _dbContext.Agencies.FirstOrDefaultAsync(x => x.TourType == component.TourType && x.Count >= saleComponent.Count);
if (agency == null)
{
transaction.Rollback();
return false;
}
if (agency.Count - saleComponent.Count == 0)
{
DelElement(agency.Id);
}
else
{
agency.Count -= saleComponent.Count;
_dbContext.Agencies.Update(agency);
}
if (agency == null)
{
transaction.Rollback();
return false;
}
if (agency.Count - sale_tour.Count == 0)
{
DelElement(agency.Id);
}
else
{
agency.Count -= sale_tour.Count;
}
}
return true;
})
.ToList();
Task.WaitAll(componentTasks.ToArray());
transaction.Commit();
_dbContext.SaveChanges();
return true;

View File

@@ -36,11 +36,16 @@ public class SuppliesStorageContract : ISuppliesStorageContract
_mapper = new Mapper(config);
}
public List<SuppliesDataModel> GetList(DateTime? startDate = null)
public List<SuppliesDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null)
{
try
{
return [.. _dbContext.Supplieses.Select(x => _mapper.Map<SuppliesDataModel>(x))];
var query = _dbContext.Supplieses.AsQueryable();
if (startDate is not null && endDate is not null)
{
query = query.Where(x => x.ProductuionDate >= startDate && x.ProductuionDate < endDate);
}
return [.. query.Select(x => _mapper.Map<SuppliesDataModel>(x))];
}
catch (Exception ex)
{

View File

@@ -523,4 +523,37 @@ internal class SaleBusinessLogicContractTests
Assert.That(() => _saleBusinessLogicContract.CancelSale(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
_saleStorageContract.Verify(x => x.DelElement(It.IsAny<string>()), Times.Once);
}
[Test]
public void CalculateSaleRevenue_ReturnsCorrectSum_Test()
{
// Arrange
var fromDate = DateTime.Now.AddDays(-10);
var toDate = DateTime.Now;
var listOriginal = new List<SaleDataModel>()
{
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), null, DiscountType.None, false,
[new SaleTourDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 1.2)]),
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), null, DiscountType.None, false, []),
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), null, DiscountType.None, false, []),
};
_saleStorageContract.Setup(x => x.GetList(fromDate, toDate, It.IsAny<string>(), It.IsAny<string>(),It.IsAny<string>())).Returns(listOriginal);
// Act
var result = _saleBusinessLogicContract.CalculateSaleRevenue(fromDate, toDate);
// Assert
Assert.That(result, Is.EqualTo(6.0));
}
[Test]
public void CalculateSaleRevenue_NoSales_ReturnsZero()
{
// Arrange
var fromDate = DateTime.Now.AddDays(-10);
var toDate = DateTime.Now;
_saleStorageContract.Setup(x => x.GetList(fromDate, toDate, null, null, null)).Returns([]);
// Act
double revenue = _saleBusinessLogicContract.CalculateSaleRevenue(fromDate, toDate);
// Assert
Assert.That(revenue, Is.EqualTo(0));
}
}

View File

@@ -42,7 +42,7 @@ internal class SuppliesBusinessLogicContractTests
new(Guid.NewGuid().ToString(), TourType.Beach, DateTime.Now, 1, []),
new(Guid.NewGuid().ToString(), TourType.Beach, DateTime.Now, 1, []),
};
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>())).Returns(listOriginal);
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns(listOriginal);
// Act
var list = _suppliesBusinessLogicContract.GetAllComponents();
// Assert
@@ -54,33 +54,33 @@ internal class SuppliesBusinessLogicContractTests
public void GetAllSupplies_ReturnEmptyList_Test()
{
// Arrange
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>())).Returns([]);
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns([]);
// Act
var list = _suppliesBusinessLogicContract.GetAllComponents();
// Assert
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(0));
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>()), Times.Once);
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>()), Times.Once);
}
[Test]
public void GetAllSupplies_ReturnNull_ThrowException_Test()
{
// Arrange
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>())).Returns((List<SuppliesDataModel>)null);
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns((List<SuppliesDataModel>)null);
// Act & Assert
Assert.That(() => _suppliesBusinessLogicContract.GetAllComponents(), Throws.TypeOf<NullListException>());
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>()), Times.Once);
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>()), Times.Once);
}
[Test]
public void GetAllSupplies_StorageThrowError_ThrowException_Test()
{
// Arrange
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>())).Throws(new StorageException(new InvalidOperationException()));
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new InvalidOperationException()));
// Act & Assert
Assert.That(() => _suppliesBusinessLogicContract.GetAllComponents(), Throws.TypeOf<StorageException>());
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>()), Times.Once);
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>()), Times.Once);
}
[Test]
@@ -239,4 +239,48 @@ internal class SuppliesBusinessLogicContractTests
[new TourSuppliesDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5)])), Throws.TypeOf<StorageException>());
_suppliesStorageContract.Verify(x => x.UpdElement(It.IsAny<SuppliesDataModel>()), Times.Once);
}
[Test]
public void CalculateTour_ReturnInt_Test()
{
// Arrange
string id = Guid.NewGuid().ToString();
var listOriginal = new List<SuppliesDataModel>()
{
new(id, TourType.Beach, DateTime.UtcNow, 1, new List<TourSuppliesDataModel> { new TourSuppliesDataModel(id, Guid.NewGuid().ToString(), 5), new TourSuppliesDataModel(id, Guid.NewGuid().ToString(), 6) })
};
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns(listOriginal);
// Act
var count = _suppliesBusinessLogicContract.CalculateTourSupplies(DateTime.UtcNow.AddDays(-5), DateTime.UtcNow.AddDays(5));
// Assert
Assert.That(count, Is.EqualTo(11));
}
[Test]
public void CalculateTour_ReturnIntZero_Test()
{
// Arrange
string id1 = Guid.NewGuid().ToString();
string id2 = Guid.NewGuid().ToString();
string id3 = Guid.NewGuid().ToString();
var listOriginal = new List<SuppliesDataModel>()
{
new(id1, TourType.Beach, DateTime.UtcNow, 1, [])
};
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Returns(listOriginal);
// Act
var count = _suppliesBusinessLogicContract.CalculateTourSupplies(DateTime.UtcNow.AddDays(-5), DateTime.UtcNow.AddDays(5));
// Assert
Assert.That(count, Is.EqualTo(0));
}
[Test]
public void CalculateTour_StorageThrowError_ThrowException_Test()
{
// Arrange
_suppliesStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>())).Throws(new StorageException(new InvalidOperationException()));
// Act & Assert
Assert.That(() => _suppliesBusinessLogicContract.CalculateTourSupplies(DateTime.UtcNow.AddDays(-5), DateTime.UtcNow.AddDays(5)), Throws.TypeOf<StorageException>());
_suppliesStorageContract.Verify(x => x.GetList(It.IsAny<DateTime?>(), It.IsAny<DateTime?>()), Times.Once);
}
}

View File

@@ -6,6 +6,7 @@ using MagicCarpetDatabase.Implementations;
using MagicCarpetDatabase.Models;
using MagicCarpetTests.Infrastructure;
using MagicCarpetTests.StoragesContracts;
using MagicCarpetTests.StoragesContractsTests;
using System;
using System.Collections.Generic;
using System.Linq;