5 Commits
lab_1 ... lab_6

Author SHA1 Message Date
d6ea911ce0 Лабораторная 6 2025-05-27 16:02:38 +04:00
fc9e753b85 Лабораторная 5 2025-05-27 15:36:28 +04:00
83c3fdcb32 4 лабораторная 2025-05-27 13:50:04 +04:00
bbccb79ebb lab_3 2025-03-19 11:24:57 +04:00
1b4f72f67f lab 2 work 2025-03-18 20:05:36 +04:00
193 changed files with 16694 additions and 734 deletions

View File

@@ -0,0 +1,187 @@
using AutoMapper;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
using System.Text.Json;
namespace DaisiesWebApi.Adapters;
public class BuyerAdapter : IBuyerAdapter
{
private readonly IBuyerBuisnessLogicContract _buyerBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
private readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
public BuyerAdapter(IBuyerBuisnessLogicContract buyerBusinessLogicContract,
ILogger<BuyerAdapter> logger)
{
_buyerBusinessLogicContract = buyerBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<BuyerBindingModel, BuyerDataModel>();
cfg.CreateMap<BuyerDataModel, BuyerViewModel>()
.ForMember(x => x.Configuration, x => x.MapFrom(src => JsonSerializer.Serialize(src.ConfigurationModel, JsonSerializerOptions)));
});
_mapper = new Mapper(config);
}
public BuyerOperationResponse GetList()
{
try
{
return BuyerOperationResponse.OK([.._buyerBusinessLogicContract.GetAllBuyers().Select(x =>_mapper.Map<BuyerViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return BuyerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return BuyerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return BuyerOperationResponse.InternalServerError(ex.Message);
}
}
public BuyerOperationResponse GetElement(string data)
{
try
{
return
BuyerOperationResponse.OK(_mapper.Map<BuyerViewModel>(_buyerBusinessLogicContract
.GetBuyerByData(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return BuyerOperationResponse.BadRequest("Data is empty");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return BuyerOperationResponse.NotFound($"Not found element by data {data} ");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return BuyerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return BuyerOperationResponse.InternalServerError(ex.Message);
}
}
public BuyerOperationResponse RegisterBuyer(BuyerBindingModel buyerModel)
{
try
{
_buyerBusinessLogicContract.InsertBuyer(_mapper.Map<BuyerDataModel>(buyerModel));
return BuyerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return BuyerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return BuyerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return BuyerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return BuyerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return BuyerOperationResponse.InternalServerError(ex.Message);
}
}
public BuyerOperationResponse ChangeBuyerInfo(BuyerBindingModel buyerModel)
{
try
{
_buyerBusinessLogicContract.UpdateBuyer(_mapper.Map<BuyerDataModel>(buyerModel));
return BuyerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return BuyerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return BuyerOperationResponse.BadRequest($"Incorrect datatransmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return BuyerOperationResponse.BadRequest($"Not found element by Id {buyerModel.Id}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return BuyerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return BuyerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return BuyerOperationResponse.InternalServerError(ex.Message);
}
}
public BuyerOperationResponse RemoveBuyer(string id)
{
try
{
_buyerBusinessLogicContract.DeleteBuyer(id);
return BuyerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return BuyerOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return BuyerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return BuyerOperationResponse.BadRequest($"Not found element by id: {id}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return BuyerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return BuyerOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,205 @@
using AutoMapper;
using DaisiesBuisnessLogic.Implementations;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class ClientDiscountAdapter : IClientDiscountAdapter
{
private readonly IClientDiscountBuisnessLogicContract _clientDiscountBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public ClientDiscountAdapter(IClientDiscountBuisnessLogicContract clientDiscountBusinessLogicContrac, ILogger<ClientDiscountAdapter> logger)
{
_clientDiscountBusinessLogicContract = clientDiscountBusinessLogicContrac;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ClientDiscountBindingModel, ClientDiscountDataModel>();
cfg.CreateMap<ClientDiscountDataModel, ClientDiscountViewModel>();
});
_mapper = new Mapper(config);
}
public ClientDiscountOperationResponse RegisterClientDiscount(ClientDiscountBindingModel
clientDiscountModel)
{
try
{
_clientDiscountBusinessLogicContract.InsertClientDiscount(_mapper.Map<ClientDiscountDataModel>(clientDiscountModel));
return ClientDiscountOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ClientDiscountOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ClientDiscountOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return ClientDiscountOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ClientDiscountOperationResponse.BadRequest($"Error whileworking with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ClientDiscountOperationResponse.InternalServerError(ex.Message);
}
}
public ClientDiscountOperationResponse GetElementByBuyerId(string data)
{
try
{
return
ClientDiscountOperationResponse.OK(_mapper.Map<ClientDiscountViewModel>(_clientDiscountBusinessLogicContract.GetClientDiscountByBuyerId(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ClientDiscountOperationResponse.BadRequest("Data is empty");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ClientDiscountOperationResponse.NotFound($"Not found element by data {data} ");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ClientDiscountOperationResponse.BadRequest($"Element by data: {data} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ClientDiscountOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ClientDiscountOperationResponse.InternalServerError(ex.Message);
}
}
public ClientDiscountOperationResponse GetList(bool onlyActive = true)
{
try
{
return ClientDiscountOperationResponse.OK([..
_clientDiscountBusinessLogicContract.GetAllClientDiscounts().Select(x =>
_mapper.Map<ClientDiscountViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return ClientDiscountOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ClientDiscountOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return ClientDiscountOperationResponse.InternalServerError(ex.Message);
}
}
public ClientDiscountOperationResponse ChangeClientDiscountInfo(ClientDiscountBindingModel clientDiscountModel)
{
try
{
_clientDiscountBusinessLogicContract.UpdateClientDiscount(_mapper.Map<ClientDiscountDataModel>(clientDiscountModel));
return ClientDiscountOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ClientDiscountOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ClientDiscountOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ClientDiscountOperationResponse.BadRequest($"Not found element by BuyerId {clientDiscountModel.BuyerId} ");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return ClientDiscountOperationResponse.BadRequest(ex.Message);
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ClientDiscountOperationResponse.BadRequest($"Element by id: {clientDiscountModel.BuyerId} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ClientDiscountOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ClientDiscountOperationResponse.InternalServerError(ex.Message);
}
}
public ClientDiscountOperationResponse GetElement(string data)
{
try
{
return ClientDiscountOperationResponse.OK(_mapper.Map<ClientDiscountViewModel>(_clientDiscountBusinessLogicContract.GetClientDiscountByBuyerId(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ClientDiscountOperationResponse.BadRequest("Data is empty");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ClientDiscountOperationResponse.NotFound($"Not found element by data {data} ");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ClientDiscountOperationResponse.BadRequest($"Element by data: {data} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ClientDiscountOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return ClientDiscountOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,266 @@
using AutoMapper;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class PostAdapter : IPostAdapter
{
private readonly IPostBuisnessLogicContract _postBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public PostAdapter(IPostBuisnessLogicContract postBusinessLogicContract, ILogger<PostAdapter> logger)
{
_postBusinessLogicContract = postBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<PostBindingModel, PostDataModel>();
cfg.CreateMap<PostDataModel, PostViewModel>();
});
_mapper = new Mapper(config);
}
public PostOperationResponse GetList()
{
try
{
return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllPosts().Select(x => _mapper.Map<PostViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return PostOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse GetHistory(string id)
{
try
{
return PostOperationResponse.OK([.. _postBusinessLogicContract.GetAllDataOfPost(id).Select(x => _mapper.Map<PostViewModel>(x))]);
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return PostOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse GetElement(string data)
{
try
{
return PostOperationResponse.OK(_mapper.Map<PostViewModel>(_postBusinessLogicContract.GetPostByData(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Data is empty");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return PostOperationResponse.NotFound($"Not found element by data {data}");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return PostOperationResponse.BadRequest($"Element by data: {data} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse RegisterPost(PostBindingModel postModel)
{
try
{
_postBusinessLogicContract.InsertPost(_mapper.Map<PostDataModel>(postModel));
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return PostOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return PostOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse ChangePostInfo(PostBindingModel postModel)
{
try
{
_postBusinessLogicContract.UpdatePost(_mapper.Map<PostDataModel>(postModel));
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return PostOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return PostOperationResponse.BadRequest($"Not found element by Id {postModel.Id}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return PostOperationResponse.BadRequest(ex.Message);
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return PostOperationResponse.BadRequest($"Element by id: {postModel.Id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse RemovePost(string id)
{
try
{
_postBusinessLogicContract.DeletePost(id);
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return PostOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return PostOperationResponse.BadRequest($"Not found element by id: {id}");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return PostOperationResponse.BadRequest($"Element by id: {id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
public PostOperationResponse RestorePost(string id)
{
try
{
_postBusinessLogicContract.RestorePost(id);
return PostOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return PostOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return PostOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return PostOperationResponse.BadRequest($"Not found element by id: {id}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return PostOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return PostOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,263 @@
using AutoMapper;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class ProductAdapter : IProductAdapter
{
private readonly IProductBuisnessLogicContract
_productBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public ProductAdapter(IProductBuisnessLogicContract
productBusinessLogicContract, ILogger<ProductAdapter> logger)
{
_productBusinessLogicContract = productBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ProductBindingModel, ProductDataModel>();
cfg.CreateMap<ProductDataModel, ProductViewModel>();
cfg.CreateMap<ProductHistoryDataModel, ProductHistoryViewModel>();
});
_mapper = new Mapper(config);
}
public ProductOperationResponse GetList(bool includeDeleted)
{
try
{
return ProductOperationResponse.OK([.. _productBusinessLogicContract.GetAllProducts(!includeDeleted).Select(x =>_mapper.Map<ProductViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return ProductOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse GetSupplierList(string id, bool includeDeleted)
{
try
{
return ProductOperationResponse.OK([.. _productBusinessLogicContract.GetAllProductsBySupplier(id,!includeDeleted).Select(x => _mapper.Map<ProductViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return ProductOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse GetHistory(string id)
{
try
{
return ProductOperationResponse.OK([.. _productBusinessLogicContract.GetProductHistoryByProduct(id).Select(x => _mapper.Map<ProductHistoryViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return ProductOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse GetElement(string data)
{
try
{
return
ProductOperationResponse.OK(_mapper.Map<ProductViewModel>(_productBusinessLogicContract.GetProductByData(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ProductOperationResponse.BadRequest("Data is empty");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ProductOperationResponse.NotFound($"Not found element by data {data} ");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ProductOperationResponse.BadRequest($"Element by data: {data} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse RegisterProduct(ProductBindingModel
productModel)
{
try
{
_productBusinessLogicContract.InsertProduct(_mapper.Map<ProductDataModel>(productModel));
return ProductOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ProductOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return ProductOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.BadRequest($"Error whileworking with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse ChangeProductInfo(ProductBindingModel
productModel)
{
try
{
_productBusinessLogicContract.UpdateProduct(_mapper.Map<ProductDataModel>(productModel));
return ProductOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ProductOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ProductOperationResponse.BadRequest($"Not found element by Id {productModel.Id} ");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return ProductOperationResponse.BadRequest(ex.Message);
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ProductOperationResponse.BadRequest($"Element by id: {productModel.Id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
public ProductOperationResponse RemoveProduct(string id)
{
try
{
_productBusinessLogicContract.DeleteProduct(id);
return ProductOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return ProductOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return ProductOperationResponse.BadRequest($"Not found element by id: {id} ");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return ProductOperationResponse.BadRequest($"Element by id: {id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ProductOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ProductOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,203 @@
using AutoMapper;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class ReportAdapter : IReportAdapter
{
private readonly IReportContract _reportContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public ReportAdapter(IReportContract reportContract, ILogger logger)
{
_reportContract = reportContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ProductProductHistoryDataModel, ProductProductHistoryViewModel>();
cfg.CreateMap<SaleDataModel, SaleViewModel>(); ;
cfg.CreateMap<SaleProductDataModel, SaleProductViewModel>();
cfg.CreateMap<ClientDiscountByPeriodDataModel, ClientDiscountByPeriodViewModel>();
cfg.CreateMap<ClientDiscountDataModel, ClientDiscountByPeriodDataModel>();
});
_mapper = new Mapper(config);
}
public async Task<ReportOperationResponse> CreateDocumentProductPricesByProductAsync(CancellationToken ct)
{
try
{
return SendStream(await _reportContract.CreateDocumentProductPricesByProductAsync(ct), "Producthistories.xslx");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
return SendStream(await _reportContract.CreateDocumentSalesByPeriodAsync(dateStart, dateFinish, ct),
"sales.xslx");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> GetDataProductPricesByProductAsync(CancellationToken ct)
{
try
{
return ReportOperationResponse.OK([.. (await _reportContract.GetDataProductPricesByProductAsync(ct)).Select(x => _mapper.Map<ProductProductHistoryViewModel>(x))]);
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
return ReportOperationResponse.OK((await _reportContract.GetDataSaleByPeriodAsync(dateStart, dateFinish, ct)).Select(x =>
_mapper.Map<SaleViewModel>(x)).ToList());
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
private static ReportOperationResponse SendStream(Stream stream, string fileName)
{
stream.Position = 0;
return ReportOperationResponse.OK(stream, fileName);
}
public async Task<ReportOperationResponse> GetDataClientDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
return ReportOperationResponse.OK((await _reportContract.GetDataDiscountByPeriodAsync(dateStart, dateFinish, ct))
.Select(x => _mapper.Map<ClientDiscountByPeriodViewModel>(x)).ToList());
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
public async Task<ReportOperationResponse> CreateDocumentClientDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
try
{
return SendStream(await _reportContract.CreateDocumentDiscountByPeriodAsync(dateStart, dateFinish, ct), "discount.pdf");
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return ReportOperationResponse.BadRequest($"Incorrect dates: {ex.Message} ");
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "InvalidOperationException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return ReportOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
ReportOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,263 @@
using AutoMapper;
using DaisiesBuisnessLogic.Implementations;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class SaleAdapter : ISaleAdapter
{
private readonly ISaleBuisnessLogicContract _saleBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public SaleAdapter(ISaleBuisnessLogicContract saleBusinessLogicContract, ILogger<SaleAdapter> logger)
{
_saleBusinessLogicContract = saleBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SaleBindingModel, SaleDataModel>();
cfg.CreateMap<SaleDataModel, SaleViewModel>();
cfg.CreateMap<SaleProductBindingModel, SaleProductDataModel>();
cfg.CreateMap<SaleProductDataModel, SaleProductViewModel>();
});
_mapper = new Mapper(config);
}
public SaleOperationResponse GetList(DateTime fromDate, DateTime toDate)
{
try
{
return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByPeriod(fromDate, toDate).Select(x => _mapper.Map<SaleViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SaleOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SaleOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse GetWorkerList(string id, DateTime fromDate, DateTime toDate)
{
try
{
return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByWorkerByPeriod(id, fromDate, toDate).Select(x => _mapper.Map<SaleViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SaleOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SaleOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse GetBuyerList(string id, DateTime fromDate, DateTime toDate)
{
try
{
return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByBuyerByPeriod(id, fromDate, toDate).Select(x => _mapper.Map<SaleViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SaleOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SaleOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse GetProductList(string id, DateTime fromDate, DateTime toDate)
{
try
{
return SaleOperationResponse.OK([.. _saleBusinessLogicContract.GetAllSalesByProductByPeriod(id, fromDate, toDate).Select(x => _mapper.Map<SaleViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SaleOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SaleOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse GetElement(string id)
{
try
{
return SaleOperationResponse.OK(_mapper.Map<SaleViewModel>(_saleBusinessLogicContract.GetSaleByData(id)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return SaleOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return SaleOperationResponse.NotFound($"Not found element by data {id}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse MakeSale(SaleBindingModel saleModel)
{
try
{
var data = _mapper.Map<SaleDataModel>(saleModel);
_saleBusinessLogicContract.InsertSale(_mapper.Map<SaleDataModel>(saleModel));
return SaleOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return SaleOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
public SaleOperationResponse CancelSale(string id)
{
try
{
_saleBusinessLogicContract.CancelSale(id);
return SaleOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return SaleOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SaleOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return SaleOperationResponse.BadRequest($"Not found element by id: {id}");
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
return SaleOperationResponse.BadRequest($"Element by id: {id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SaleOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return SaleOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,280 @@
using AutoMapper;
using DaisiesBuisnessLogic.Implementations;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.ViewModels;
namespace DaisiesWebApi.Adapters;
public class WorkerAdapter : IWorkerAdapter
{
private readonly IWorkerBuisnessLogicContract _buyerBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public WorkerAdapter(IWorkerBuisnessLogicContract
workerBusinessLogicContract, ILogger<WorkerAdapter> logger)
{
_buyerBusinessLogicContract = workerBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<WorkerBindingModel, WorkerDataModel>();
cfg.CreateMap<WorkerDataModel, WorkerViewModel>();
});
_mapper = new Mapper(config);
}
public WorkerOperationResponse GetList(bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.._buyerBusinessLogicContract.GetAllWorkers(!includeDeleted).Select(x =>_mapper.Map<WorkerViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetPostList(string id, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.._buyerBusinessLogicContract.GetAllWorkersByPost(id, !includeDeleted).Select(x =>_mapper.Map<WorkerViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetListByBirthDate(DateTime fromDate,
DateTime toDate, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.._buyerBusinessLogicContract.GetAllWorkersByBirthDate(fromDate, toDate,!includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return WorkerOperationResponse.BadRequest($"Incorrect dates: {ex.Message} ");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetListByEmploymentDate(DateTime fromDate,
DateTime toDate, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.._buyerBusinessLogicContract.GetAllWorkersByEmploymentDate(fromDate, toDate,!includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return WorkerOperationResponse.BadRequest($"Incorrect dates: {ex.Message} ");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetElement(string data)
{
try
{
return
WorkerOperationResponse.OK(_mapper.Map<WorkerViewModel>(_buyerBusinessLogicContract.GetWorkerByData(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.NotFound($"Not found element by data {data} ");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse RegisterWorker(WorkerBindingModel workerModel)
{
try
{
_buyerBusinessLogicContract.InsertWorker(_mapper.Map<WorkerDataModel>(workerModel));
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return WorkerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse ChangeWorkerInfo(WorkerBindingModel workerModel)
{
try
{
_buyerBusinessLogicContract.UpdateWorker(_mapper.Map<WorkerDataModel>(workerModel));
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.BadRequest($"Not found element by Id {workerModel.Id} ");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return WorkerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse RemoveWorker(string id)
{
try
{
_buyerBusinessLogicContract.DeleteWorker(id);
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message} ");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.BadRequest($"Not found element by id: {id} ");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message} ");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return
WorkerOperationResponse.InternalServerError(ex.Message);
}
}
}

20
DaisiesApi/AuthOptions.cs Normal file
View File

@@ -0,0 +1,20 @@
using System.Text;
using Microsoft.IdentityModel.Tokens;
namespace DaisiesWebApi;
public class AuthOptions
{
public const string ISSUER = "Daisies_AuthServer";
public const string AUDIENCE = "Daisies_AuthClient";
const string KEY = "supersecret_32_chars_long_key_1234567890!!";
public static SymmetricSecurityKey GetSymmetricSecurityKey()
{
var key = Encoding.UTF8.GetBytes(KEY);
if (key.Length * 8 < 256)
throw new Exception("JWT key must be at least 32 characters long!");
return new SymmetricSecurityKey(key);
}
}

View File

@@ -0,0 +1,45 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class BuyersController(IBuyerAdapter adapter) : ControllerBase
{
private readonly IBuyerAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetAllRecords()
{
return _adapter.GetList().GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] BuyerBindingModel model)
{
return _adapter.RegisterBuyer(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] BuyerBindingModel model)
{
return _adapter.ChangeBuyerInfo(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemoveBuyer(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,36 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Net;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class ClientDiscountsController(IClientDiscountAdapter adapter) : ControllerBase
{
private readonly IClientDiscountAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetAllRecords()
{
return _adapter.GetList().GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] ClientDiscountBindingModel model)
{
return _adapter.RegisterClientDiscount(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] ClientDiscountBindingModel model)
{
return _adapter.ChangeClientDiscountInfo(model).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,58 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class PostsController(IPostAdapter adapter) : ControllerBase
{
private readonly IPostAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords()
{
return _adapter.GetList().GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] PostBindingModel model)
{
return _adapter.RegisterPost(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] PostBindingModel model)
{
return _adapter.ChangePostInfo(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemovePost(id).GetResponse(Request, Response);
}
[HttpPatch("{id}")]
public IActionResult Restore(string id)
{
return _adapter.RestorePost(id).GetResponse(Request, Response);
}
[HttpGet("history/{postId}")]
public IActionResult GetHistory(string postId)
{
return _adapter.GetHistory(postId).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,55 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class ProductsController(IProductAdapter adapter) : ControllerBase
{
private readonly IProductAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(bool includeDeleted)
{
return _adapter.GetList(includeDeleted).GetResponse(Request,
Response);
}
[HttpGet]
public IActionResult GetSupplierRecords(string id, bool includeDeleted)
{
return _adapter.GetSupplierList(id,
includeDeleted).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetHistory(string id)
{
return _adapter.GetHistory(id).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] ProductBindingModel model)
{
return _adapter.RegisterProduct(model).GetResponse(Request,
Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] ProductBindingModel model)
{
return _adapter.ChangeProductInfo(model).GetResponse(Request,
Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemoveProduct(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,60 @@
using DaisiesContracts.AdapterContracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
public class ReportController(IReportAdapter adapter) : ControllerBase
{
private readonly IReportAdapter _adapter = adapter;
[HttpGet]
[Consumes("application/json")]
public async Task<IActionResult> GetHistories(CancellationToken ct)
{
return (await _adapter.GetDataProductPricesByProductAsync(ct)).GetResponse(Request, Response);
}
[HttpGet]
[Consumes("application/octet-stream")]
public async Task<IActionResult> LoadHistories(CancellationToken cancellationToken)
{
return (await
_adapter.CreateDocumentProductPricesByProductAsync(cancellationToken)).GetResponse(Request, Response);
}
[HttpGet]
[Consumes("application/json")]
public async Task<IActionResult> GetSales(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
{
return (await _adapter.GetDataSaleByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
}
[HttpGet]
[Consumes("application/octet-stream")]
public async Task<IActionResult> LoadSales(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
{
return (await _adapter.CreateDocumentSalesByPeriodAsync(fromDate,
toDate, cancellationToken)).GetResponse(Request, Response);
}
[HttpGet]
[Consumes("application/json")]
public async Task<IActionResult> GetDiscount(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
{
return (await _adapter.GetDataClientDiscountByPeriodAsync(fromDate, toDate,
cancellationToken)).GetResponse(Request, Response);
}
[HttpGet]
[Consumes("application/octet-stream")]
public async Task<IActionResult> LoadDiscount(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken)
{
return (await _adapter.CreateDocumentClientDiscountByPeriodAsync(fromDate, toDate, cancellationToken)).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,57 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class SalesController(ISaleAdapter adapter) : ControllerBase
{
private readonly ISaleAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(DateTime fromDate, DateTime toDate)
{
return _adapter.GetList(fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetWorkerRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetWorkerList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetBuyerRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetBuyerList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetProductRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetProductList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Sale([FromBody] SaleBindingModel model)
{
return _adapter.MakeSale(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Cancel(string id)
{
return _adapter.CancelSale(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesApi.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}

View File

@@ -0,0 +1,62 @@
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DaisiesWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class WorkersController(IWorkerAdapter adapter) : ControllerBase
{
private readonly IWorkerAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(bool includeDeleted = false)
{
return _adapter.GetList(includeDeleted).GetResponse(Request,
Response);
}
[HttpGet]
public IActionResult GetPostRecords(string id, bool includeDeleted = false)
{
return _adapter.GetPostList(id, includeDeleted).GetResponse(Request,
Response);
}
[HttpGet]
public IActionResult GetBirthDateRecords(DateTime fromDate, DateTime
toDate, bool includeDeleted = false)
{
return _adapter.GetListByBirthDate(fromDate, toDate,
includeDeleted).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetEmploymentRecords(DateTime fromDate, DateTime
toDate, bool includeDeleted = false)
{
return _adapter.GetListByEmploymentDate(fromDate, toDate,
includeDeleted).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] WorkerBindingModel model)
{
return _adapter.RegisterWorker(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] WorkerBindingModel model)
{
return _adapter.ChangeWorkerInfo(model).GetResponse(Request,
Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemoveWorker(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DaisiesBusinessLogic\DaisiesBusinessLogic.csproj" />
<ProjectReference Include="..\DaisiesContracts\DaisiesContracts.csproj" />
<ProjectReference Include="..\DaisiesDatabase\DaisiesDatabase.csproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="DaisiesTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@DaisiesApi_HostAddress = http://localhost:5107
GET {{DaisiesApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,13 @@
using DaisiesContracts.Infrastructure;
namespace DaisiesWebApi.Infrastructure;
public class ConfigurationDatabase(IConfiguration configuration) : IConfigurationDatabase
{
private readonly Lazy<DataBaseSettings> _dataBaseSettings = new(() =>
{
return configuration.GetValue<DataBaseSettings>("DataBaseSettings") ?? throw new InvalidDataException(nameof(DataBaseSettings));
});
public string ConnectionString => _dataBaseSettings.Value.ConnectionString;
}

View File

@@ -0,0 +1,15 @@
using DaisiesContracts.Infrastructure;
namespace DaisiesWebApi.Infrastructure;
public class ConfigurationDiscount(IConfiguration configuration) : IConfigurationDiscount
{
private readonly Lazy<DiscountSettings> _discountSettings = new(() =>
{
return configuration.GetValue<DiscountSettings>("DiscountSettings") ?? throw new InvalidDataException(nameof(DiscountSettings));
});
public double ExtraDiscountSum => _discountSettings.Value.ExtraDiscountSum;
public int MaxConcurrentThreads => _discountSettings.Value.MaxConcurrentThreads;
}

View File

@@ -0,0 +1,6 @@
namespace DaisiesWebApi.Infrastructure;
public class DataBaseSettings
{
public required string ConnectionString { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace DaisiesWebApi.Infrastructure;
public class DiscountSettings
{
public double ExtraDiscountSum { get; set; }
public int MaxConcurrentThreads { get; set; }
}

131
DaisiesApi/Program.cs Normal file
View File

@@ -0,0 +1,131 @@
using DaisiesBuisnessLogic.Implementations;
using DaisiesBuisnessLogic.OfficePackage;
using DaisiesContracts.AdapterContracts;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.Infrastructure;
using DaisiesContracts.StoragesContracts;
using DaisiesDatabase;
using DaisiesDatabase.Implementations;
using DaisiesWebApi;
using DaisiesWebApi.Adapters;
using DaisiesWebApi.Infrastructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddAutoMapper(typeof(Program).Assembly);
builder.Services.AddSingleton<IConfigurationDatabase, ConfigurationDatabase>();
builder.Services.AddSingleton<IConfigurationDatabase, ConfigurationDatabase>();
builder.Services.AddSingleton<IConfigurationDiscount, ConfigurationDiscount>();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
builder.Services.AddTransient<IBuyerBuisnessLogicContract, BuyerBuisnessLogicContract>();
builder.Services.AddTransient<IClientDiscountBuisnessLogicContract, ClientDiscountBuisnessLogicContract>();
builder.Services.AddTransient<IPostBuisnessLogicContract, PostBuisnessLogicContract>();
builder.Services.AddTransient<IProductBuisnessLogicContract, ProductBuisnessLogicContract>();
builder.Services.AddTransient<ISaleBuisnessLogicContract, SaleBusinessLogicContract>();
builder.Services.AddTransient<IWorkerBuisnessLogicContract, WorkerBuisnessLogicContract>();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
builder.Services.AddTransient<DaisiesDbContext>();
builder.Services.AddTransient<IBuyerStorageContract, BuyerStorageContract>();
builder.Services.AddTransient<IPostStorageContract, PostStorageContract>();
builder.Services.AddTransient<IProductStorageContract, ProductStorageContract>();
builder.Services.AddTransient<IClientDiscountStorageContract, ClientDiscountStorageContract>();
builder.Services.AddTransient<ISaleStorageContract, SaleStorageContract>();
builder.Services.AddTransient<IWorkerStorageContract, WorkerStorageContract>();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
builder.Services.AddTransient<IBuyerAdapter, BuyerAdapter>();
builder.Services.AddTransient<IClientDiscountAdapter, ClientDiscountAdapter>();
builder.Services.AddTransient<IPostAdapter, PostAdapter>();
builder.Services.AddTransient<IProductAdapter, ProductAdapter>();
builder.Services.AddTransient<ISaleAdapter, SaleAdapter>();
builder.Services.AddTransient<IWorkerAdapter, WorkerAdapter>();
builder.Services.AddTransient<IReportContract, ReportContract>();
builder.Services.AddTransient<IReportAdapter, ReportAdapter>();
builder.Services.AddTransient<IReportAdapter, ReportAdapter>();
builder.Services.AddTransient<BaseWordBuilder, OpenXmlWordBuilder>();
builder.Services.AddTransient<BaseExcelBuilder, OpenXmlExcelBuilder>();
builder.Services.AddTransient<BasePdfBuilder, MigraDocPdfBuilder>();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
using var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger());
builder.Services.AddSingleton(loggerFactory.CreateLogger("Any"));
builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidateIssuer = true,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidIssuer = AuthOptions.ISSUER,
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidateAudience = true,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidAudience = AuthOptions.AUDIENCE,
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidateLifetime = true,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ValidateIssuerSigningKey = true,
};
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
if (app.Environment.IsProduction())
{
var dbContext = app.Services.GetRequiredService<DaisiesDbContext>();
if (dbContext.Database.CanConnect())
{
dbContext.Database.EnsureCreated();
dbContext.Database.Migrate();
}
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.Map("/login/{username}", (string username) =>
{
return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(
issuer: AuthOptions.ISSUER,
audience: AuthOptions.AUDIENCE,
claims: [new(ClaimTypes.Name, username)],
expires: DateTime.UtcNow.Add(TimeSpan.FromMinutes(2)),
signingCredentials: new
SigningCredentials(AuthOptions.GetSymmetricSecurityKey(),
SecurityAlgorithms.HmacSha256)));
});
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5107",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7197;http://localhost:5107",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,13 @@
namespace DaisiesApi
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,32 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "../logs/chamomiles-.log",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz},{CorrelationId},{Level:u3},{Username},{Message:lj},{Exception}, {NewLine}"
}
}
]
},
"AllowedHosts": "*",
"DiscountSettings": {
"ExtraDiscountSum": 1000,
"MaxConcurrentThreads": 4
},
"DataBaseSettings": {
"ConnectionString": ""
}
}

View File

@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.3" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="PDFsharp-MigraDoc-GDI" Version="6.2.0" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="DaisiesTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DaisiesContracts\DaisiesContracts.csproj" />
<ProjectReference Include="..\DaisiesDatabase\DaisiesDatabase.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,75 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace DaisiesBuisnessLogic.Implementations;
public class BuyerBuisnessLogicContract(IBuyerStorageContract buyerStorageContract, ILogger logger) : IBuyerBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IBuyerStorageContract _buyerStorageContract =
buyerStorageContract;
public List<BuyerDataModel> GetAllBuyers()
{
_logger.LogInformation("GetAllBuyers");
return _buyerStorageContract.GetList() ?? throw new
NullListException();
return [];
}
public BuyerDataModel GetBuyerByData(string data)
{
_logger.LogInformation("Get element by data: {data}", data);
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _buyerStorageContract.GetElementById(data) ?? throw new
ElementNotFoundException(data);
}
if (Regex.IsMatch(data, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\-]{7,10}$"))
{
return _buyerStorageContract.GetElementByPhoneNumber(data) ??
throw new ElementNotFoundException(data);
}
return _buyerStorageContract.GetElementByFIO(data) ?? throw new
ElementNotFoundException(data);
}
public void InsertBuyer(BuyerDataModel buyerDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(buyerDataModel));
ArgumentNullException.ThrowIfNull(buyerDataModel);
buyerDataModel.Validate();
_buyerStorageContract.AddElement(buyerDataModel);
}
public void UpdateBuyer(BuyerDataModel buyerDataModel)
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(buyerDataModel));
ArgumentNullException.ThrowIfNull(buyerDataModel);
buyerDataModel.Validate();
_buyerStorageContract.UpdElement(buyerDataModel);
}
public void DeleteBuyer(string id)
{
_logger.LogInformation("Delete by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_buyerStorageContract.DelElement(id);
}
}

View File

@@ -0,0 +1,163 @@
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
using DaisiesContracts.Infrastructure.BuyerConfigurations;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace DaisiesBuisnessLogic.Implementations;
public class ClientDiscountBuisnessLogicContract(IClientDiscountStorageContract clientDiscountStorageContract, IBuyerStorageContract buyerStorageContract, ISaleStorageContract saleStorageContract, IConfigurationDiscount configuration, ILogger logger) : IClientDiscountBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IClientDiscountStorageContract _clientDiscountStorageContract = clientDiscountStorageContract;
private readonly IBuyerStorageContract _buyerStorageContract = buyerStorageContract;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
private readonly IConfigurationDiscount _discountConfiguration = configuration;
private readonly Lock _lockObject = new();
public List<ClientDiscountDataModel> GetAllClientDiscounts()
{
logger.LogInformation("GetAllClientDiscount");
return _clientDiscountStorageContract.GetList() ?? throw new
NullListException();
return [];
}
public ClientDiscountDataModel GetClientDiscountByBuyerId(string buyerId)
{
_logger.LogInformation("get element by data: {data}", buyerId);
if (buyerId.IsEmpty())
{
throw new ArgumentNullException(nameof(buyerId));
}
if (buyerId.IsGuid())
{
return _clientDiscountStorageContract.GetElementByBuyerId(buyerId) ?? throw new
ElementNotFoundException(buyerId);
}
return _clientDiscountStorageContract.GetElementByBuyerFIO(buyerId) ?? throw new
ElementNotFoundException(buyerId);
}
public void InsertClientDiscount(ClientDiscountDataModel clientDiscountDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(clientDiscountDataModel));
ArgumentNullException.ThrowIfNull(clientDiscountDataModel);
clientDiscountDataModel.Validate();
_clientDiscountStorageContract.AddElement(clientDiscountDataModel);
}
public void UpdateClientDiscount(ClientDiscountDataModel clientDiscountDataModel)
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(clientDiscountDataModel));
ArgumentNullException.ThrowIfNull(clientDiscountDataModel);
clientDiscountDataModel.Validate();
_clientDiscountStorageContract.UpdElement(clientDiscountDataModel);
}
public void DeleteClientDiscount(string id)
{
_logger.LogInformation("Delete by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_clientDiscountStorageContract.DelElement(id);
}
public void CalculateBonusByMounth(DateTime date)
{
_logger.LogInformation("CalculateBonusesForCustomers: {date}", date);
var startDate = new DateTime(date.Year, date.Month, 1);
var finishDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
// Получаем список всех покупателей
var buyers = _buyerStorageContract.GetList() ?? throw new NullListException();
foreach (var buyer in buyers)
{
// Получаем сумму покупок покупателя за месяц
var buyerOrders = _saleStorageContract.GetList(startDate, finishDate, buyerId: buyer.Id);
var ordersSum = _saleStorageContract.GetList(startDate, finishDate, buyerId: buyer.Id).Sum(x => x.Sum);
var discount = buyer.ConfigurationModel switch
{
null => 0,
ConstantBuyerConfiguration cpc => CalculateBonusForConstBuyer(buyerOrders, cpc),
VipBuyerConfiguration spc => CalculateBonusForVipBuyer(buyerOrders, startDate, finishDate, spc),
BuyerConfiguration pc => (double)(ordersSum * 0.001)
};
_logger.LogDebug("Customer {customerId} received a bonus of {bonus} for the month", buyer.Id, discount);
_clientDiscountStorageContract.AddElement(new ClientDiscountDataModel(buyer.Id, ordersSum, discount));
}
}
private double CalculateBonusForVipBuyer(List<SaleDataModel> sales, DateTime startDate, DateTime finishDate, VipBuyerConfiguration config)
{
var calcBonuses = 0.0;
var options = new ParallelOptions
{
MaxDegreeOfParallelism = _discountConfiguration.MaxConcurrentThreads
};
Parallel.ForEach(Enumerable.Range(0, (finishDate - startDate).Days), options, i =>
{
var dateInTask = startDate.AddDays(i);
var ordersInDay = sales.Where(x => x.SaleDate >= dateInTask && x.SaleDate < dateInTask.AddDays(1)).ToArray();
if (ordersInDay.Length > 0)
{
lock (_lockObject)
{
foreach (var order in ordersInDay)
calcBonuses += (double)(order.Sum * 0.001) * (config.ExtraDiscountMultiplyer + config.DiscountMultiplier);
}
}
});
var calcBonusTask = Task.Run(() =>
{
return (double)(sales.Where(x => x.Sum > _discountConfiguration.ExtraDiscountSum).Sum(x => x.Sum) * 0.001) * config.ExtraDiscountMultiplyer;
});
try
{
calcBonusTask.Wait();
}
catch (AggregateException agEx)
{
foreach (var ex in agEx.InnerExceptions)
{
_logger.LogError(ex, "Error in vip buyer discount calculation");
}
return 0;
}
return calcBonuses + (double)calcBonusTask.Result;
}
private double CalculateBonusForConstBuyer(List<SaleDataModel> sales, ConstantBuyerConfiguration config)
{
try
{
var totalDiscount = 0.0;
foreach (var order in sales)
{
totalDiscount += (double)(order.Sum * 0.001) * config.RegularDiscountMultiplyer;
}
return totalDiscount;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in constant customer discount calculation");
return 0;
}
}
}

View File

@@ -0,0 +1,95 @@
using System.Text.Json;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace DaisiesBuisnessLogic.Implementations;
public class PostBuisnessLogicContract(IPostStorageContract postStorageContract, ILogger logger) : IPostBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IPostStorageContract _postStorageContract = postStorageContract;
public List<PostDataModel> GetAllPosts()
{
_logger.LogInformation("GetAllPosts params: {onlyActive}");
return _postStorageContract.GetList() ?? throw new NullListException();
}
public List<PostDataModel> GetAllDataOfPost(string postId)
{
_logger.LogInformation("GetAllDataOfPost for {postId}", postId);
if (postId.IsEmpty())
{
throw new ArgumentNullException(nameof(postId));
}
if (!postId.IsGuid())
{
throw new ValidationException("The value in the field postId is not a unique identifier.");
}
return _postStorageContract.GetPostWithHistory(postId) ?? throw new NullListException();
}
public PostDataModel GetPostByData(string data)
{
_logger.LogInformation("Get element by data: {data}", data);
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _postStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _postStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertPost(PostDataModel postDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate();
_postStorageContract.AddElement(postDataModel);
}
public void UpdatePost(PostDataModel postDataModel)
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(postDataModel));
ArgumentNullException.ThrowIfNull(postDataModel);
postDataModel.Validate();
_postStorageContract.UpdElement(postDataModel);
}
public void DeletePost(string id)
{
_logger.LogInformation("Delete by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_postStorageContract.DelElement(id);
}
public void RestorePost(string id)
{
_logger.LogInformation("Restore by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_postStorageContract.ResElement(id);
}
}

View File

@@ -0,0 +1,97 @@
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Enum;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.StoragesContracts;
using System.Text.Json;
using Microsoft.Extensions.Logging;
namespace DaisiesBuisnessLogic.Implementations;
public class ProductBuisnessLogicContract(IProductStorageContract productStorageContract, ILogger logger) : IProductBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IProductStorageContract _productStorageContract = productStorageContract;
public List<ProductDataModel> GetAllProducts(bool onlyActive)
{
_logger.LogInformation("GetAllProducts params: {onlyActive}", onlyActive);
return _productStorageContract.GetList(onlyActive) ?? throw new NullListException();
}
public List<ProductHistoryDataModel> GetProductHistoryByProduct(string productId)
{
_logger.LogInformation("GetProductHistoryByProduct for {productId}", productId);
if (productId.IsEmpty())
{
throw new ArgumentNullException(nameof(productId));
}
if (!productId.IsGuid())
{
throw new ValidationException("The value in the field productId is not a unique identifier.");
}
return _productStorageContract.GetHistoryByProductId(productId) ?? throw new NullListException();
}
public List<ProductDataModel> GetAllProductsBySupplier(string
supplierId, bool onlyActive = true)
{
if (supplierId.IsEmpty())
{
throw new ArgumentNullException(nameof(supplierId));
}
if (!supplierId.IsGuid())
{
throw new ValidationException("The value in the field supplierId is not a unique identifier.");
}
_logger.LogInformation("GetAllProducts params: {supplierId}, { onlyActive} ", supplierId, onlyActive);
return _productStorageContract.GetList(onlyActive, supplierId) ??
throw new NullListException();
return [];
}
public ProductDataModel GetProductByData(string data)
{
_logger.LogInformation("Get element by data: {data}", data);
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _productStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _productStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertProduct(ProductDataModel productDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(productDataModel));
ArgumentNullException.ThrowIfNull(productDataModel);
productDataModel.Validate();
_productStorageContract.AddElement(productDataModel);
}
public void UpdateProduct(ProductDataModel productDataModel)
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(productDataModel));
ArgumentNullException.ThrowIfNull(productDataModel);
productDataModel.Validate();
_productStorageContract.UpdElement(productDataModel);
}
public void DeleteProduct(string id)
{
_logger.LogInformation("Delete by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_productStorageContract.DelElement(id);
}
}

View File

@@ -0,0 +1,148 @@
using DaisiesBuisnessLogic.OfficePackage;
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace DaisiesBuisnessLogic.Implementations;
public class ReportContract(IProductStorageContract productStorageContract, ILogger logger, BaseWordBuilder baseWordBuilder, ISaleStorageContract saleStorageContract,
IClientDiscountStorageContract discountStorageContract, BaseExcelBuilder baseExcelBuilder, BasePdfBuilder basePdfBuilder) : IReportContract
{
private readonly ILogger _logger = logger;
private readonly IProductStorageContract _productStorageContract = productStorageContract;
private readonly BaseWordBuilder _baseWordBuilder = baseWordBuilder;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
private readonly IClientDiscountStorageContract _discountStorageContract = discountStorageContract;
private readonly BaseExcelBuilder _baseExcelBuilder = baseExcelBuilder;
private readonly BasePdfBuilder _basePdfBuilder = basePdfBuilder;
internal static readonly string[] tableHeader = ["Дата", "Сумма", "Скидка", "Продукт", "Кол-во"];
internal static readonly string[] documentHeader = ["Название продукта", "Цены", "Дата"];
public Task<List<ProductProductHistoryDataModel>> GetDataProductPricesByProductAsync(CancellationToken ct)
{
_logger.LogInformation("Get data ProductPricesByProduct");
return GetDataByHistoriesAsync(ct);
}
private async Task<List<ProductProductHistoryDataModel>> GetDataByHistoriesAsync(CancellationToken ct)
{
return [.. (await _productStorageContract.GetListAsync(ct)).GroupBy(x => x.ProductName).Select(x => new ProductProductHistoryDataModel {
ProductName = x.Key, HistoryPriceProducts = [.. x.Select(y => y.OldPrice.ToString())], Data = [.. x.Select(y => y.ChangeDate.ToString())] })];
}
public async Task<Stream> CreateDocumentProductPricesByProductAsync(CancellationToken ct)
{
_logger.LogInformation("Create report ProductPricesByProduct");
var data = await GetDataByHistoriesAsync(ct) ?? throw new InvalidOperationException("No found data");
var tableData = new List<string[]>
{
documentHeader
};
foreach (var product in data)
{
tableData.Add(new string[] { product.ProductName, "", "" });
var pairs = product.HistoryPriceProducts.Zip(product.Data,
(price, date) => new string[] { "", price, date });
tableData.AddRange(pairs);
}
return _baseWordBuilder
.AddHeader("Истории продукта по продуктам")
.AddParagraph($"Сформировано на дату {DateTime.Now}")
.AddTable(
widths: new[] { 3000, 3000, 3000 },
data: tableData
)
.Build();
}
public Task<List<SaleDataModel>> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Get data SalesByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
return GetDataBySalesAsync(dateStart, dateFinish, ct);
}
private async Task<List<SaleDataModel>> GetDataBySalesAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
if (dateStart.IsDateNotOlder(dateFinish))
{
throw new IncorrectDatesException(dateStart, dateFinish);
}
return [.. (await _saleStorageContract.GetListAsync(dateStart, dateFinish, ct)).OrderBy(x => x.SaleDate)];
}
public async Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
logger.LogInformation("Create report SalesByPeriod from {dateStart} to {dateFinish}", dateStart, dateFinish);
var data = await GetDataBySalesAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
var tableHeader = new string[] { "Дата", "ФИО", "Сумма", "Продукт", "Количество" };
return _baseExcelBuilder
.AddHeader("Заказы за период", 0, 5)
.AddParagraph($"c {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}", 2)
.AddTable(
[10, 10, 10, 10, 10],
[.. new List<string[]>() { tableHeader }
.Union(data.SelectMany(x =>
(new List<string[]>() {
new string[] {
x.SaleDate.ToShortDateString(),
x.BuyerFIO,
x.Sum.ToString("N2"),
"",
""
}
})
.Union(x.Products!.Select(y => new string[] {
"",
"",
"",
y.ProductName,
y.Count.ToString("N2")
}))
.ToArray()
)
.Union([[
"Всего",
"",
data.Sum(x => x.Sum).ToString("N2"),
"",
""
]]))
])
.Build();
}
public Task<List<ClientDiscountByPeriodDataModel>> GetDataDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
logger.LogInformation("Get data DiscountByPeriod from {dateStart} to { dateFinish}", dateStart, dateFinish);
return GetDataByDiscountAsync(dateStart, dateFinish, ct);
}
private async Task<List<ClientDiscountByPeriodDataModel>> GetDataByDiscountAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
if (dateStart.IsDateNotOlder(dateFinish))
{
throw new IncorrectDatesException(dateStart, dateFinish);
}
return [.. (await _discountStorageContract.GetListAsync(dateStart, dateFinish, ct)).GroupBy(x => x.BuyerFIO).Select(x => new ClientDiscountByPeriodDataModel
{
BuyerFIO = x.Key,
TotalDiscount = x.Sum(y => y.PersonalDiscount),
FromPeriod = x.Min(y => y.DiscountDate),
ToPeriod = x.Max(y => y.DiscountDate) }).OrderBy(x => x.BuyerFIO)];
}
public async Task<Stream> CreateDocumentDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct)
{
_logger.LogInformation("Create report DiscountByPeriod from {dateStart} to { dateFinish} ", dateStart, dateFinish);
var data = await GetDataByDiscountAsync(dateStart, dateFinish, ct) ?? throw new InvalidOperationException("No found data");
return _basePdfBuilder.AddHeader("Bедомость Скидок").AddParagraph($"за период с {dateStart.ToShortDateString()} по {dateFinish.ToShortDateString()}")
.AddPieChart("Начисления", [.. data.Select(x => (x.BuyerFIO, x.TotalDiscount))]).Build();
}
}

View File

@@ -0,0 +1,116 @@
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace DaisiesBuisnessLogic.Implementations;
public class SaleBusinessLogicContract(ISaleStorageContract saleStorageContract, ILogger logger) : ISaleBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly ISaleStorageContract _saleStorageContract = saleStorageContract;
public List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSales params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
return _saleStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByWorkerByPeriod(string workerId, DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSales params: {workerId}, {fromDate}, {toDate}", workerId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (workerId.IsEmpty())
{
throw new ArgumentNullException(nameof(workerId));
}
if (!workerId.IsGuid())
{
throw new ValidationException("The value in the field workerId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, workerId: workerId) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByBuyerByPeriod(string buyerId, DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSales params: {buyerId}, {fromDate}, {toDate}", buyerId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (buyerId.IsEmpty())
{
throw new ArgumentNullException(nameof(buyerId));
}
if (!buyerId.IsGuid())
{
throw new ValidationException("The value in the field buyerId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, buyerId: buyerId) ?? throw new NullListException();
}
public List<SaleDataModel> GetAllSalesByProductByPeriod(string productId, DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSales params: {productId}, {fromDate}, {toDate}", productId, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (productId.IsEmpty())
{
throw new ArgumentNullException(nameof(productId));
}
if (!productId.IsGuid())
{
throw new ValidationException("The value in the field productId is not a unique identifier.");
}
return _saleStorageContract.GetList(fromDate, toDate, productId: productId) ?? throw new NullListException();
}
public SaleDataModel GetSaleByData(string data)
{
_logger.LogInformation("Get element by data: {data}", data);
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (!data.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
return _saleStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
public void InsertSale(SaleDataModel saleDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(saleDataModel));
ArgumentNullException.ThrowIfNull(saleDataModel);
saleDataModel.Validate();
_saleStorageContract.AddElement(saleDataModel);
}
public void CancelSale(string id)
{
_logger.LogInformation("Cancel by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_saleStorageContract.DelElement(id);
}
}

View File

@@ -0,0 +1,100 @@
using DaisiesContracts.BuisnessLogicContracts;
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
using DaisiesContracts.Extensions;
using System.Text.Json;
namespace DaisiesBuisnessLogic.Implementations;
public class WorkerBuisnessLogicContract(IWorkerStorageContract workerStorageContract, ILogger logger) : IWorkerBuisnessLogicContract
{
private readonly ILogger _logger = logger;
private readonly IWorkerStorageContract _workerStorageContract = workerStorageContract;
public List<WorkerDataModel> GetAllWorkers(bool onlyActive = true)
{
_logger.LogInformation("GetAllWorkers params: {onlyActive}", onlyActive);
return _workerStorageContract.GetList(onlyActive) ?? throw new NullListException();
}
public List<WorkerDataModel> GetAllWorkersByPost(string postId, bool onlyActive = true)
{
_logger.LogInformation("GetAllWorkers params: {postId}, {onlyActive},", postId, onlyActive);
if (postId.IsEmpty())
{
throw new ArgumentNullException(nameof(postId));
}
if (!postId.IsGuid())
{
throw new ValidationException("The value in the field postId is not a unique identifier.");
}
return _workerStorageContract.GetList(onlyActive, postId) ?? throw new NullListException();
}
public List<WorkerDataModel> GetAllWorkersByBirthDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
{
_logger.LogInformation("GetAllWorkers params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
return _workerStorageContract.GetList(onlyActive, fromBirthDate: fromDate, toBirthDate: toDate) ?? throw new NullListException();
}
public List<WorkerDataModel> GetAllWorkersByEmploymentDate(DateTime fromDate, DateTime toDate, bool onlyActive = true)
{
_logger.LogInformation("GetAllWorkers params: {onlyActive}, {fromDate}, {toDate}", onlyActive, fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
return _workerStorageContract.GetList(onlyActive, fromEmploymentDate: fromDate, toEmploymentDate: toDate) ?? throw new NullListException();
}
public WorkerDataModel GetWorkerByData(string data)
{
_logger.LogInformation("Get element by data: {data}", data);
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _workerStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _workerStorageContract.GetElementByFIO(data) ?? throw new ElementNotFoundException(data);
}
public void InsertWorker(WorkerDataModel workerDataModel)
{
_logger.LogInformation("New data: {json}", JsonSerializer.Serialize(workerDataModel));
ArgumentNullException.ThrowIfNull(workerDataModel);
workerDataModel.Validate();
_workerStorageContract.AddElement(workerDataModel);
}
public void UpdateWorker(WorkerDataModel workerDataModel)
{
_logger.LogInformation("Update data: {json}", JsonSerializer.Serialize(workerDataModel));
ArgumentNullException.ThrowIfNull(workerDataModel);
workerDataModel.Validate();
_workerStorageContract.UpdElement(workerDataModel);
}
public void DeleteWorker(string id)
{
_logger.LogInformation("Delete by id: {id}", id);
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_workerStorageContract.DelElement(id);
}
}

View File

@@ -0,0 +1,9 @@
namespace DaisiesBuisnessLogic.OfficePackage;
public abstract class BaseExcelBuilder
{
public abstract BaseExcelBuilder AddHeader(string header, int startIndex, int count);
public abstract BaseExcelBuilder AddParagraph(string text, int columnIndex);
public abstract BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -0,0 +1,9 @@
namespace DaisiesBuisnessLogic.OfficePackage;
public abstract class BasePdfBuilder
{
public abstract BasePdfBuilder AddHeader(string header);
public abstract BasePdfBuilder AddParagraph(string text);
public abstract BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data);
public abstract Stream Build();
}

View File

@@ -0,0 +1,8 @@
namespace DaisiesBuisnessLogic.OfficePackage;
public abstract class BaseWordBuilder
{
public abstract BaseWordBuilder AddHeader(string header);
public abstract BaseWordBuilder AddParagraph(string text);
public abstract BaseWordBuilder AddTable(int[] widths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -0,0 +1,74 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace DaisiesBuisnessLogic.OfficePackage;
public class MigraDocPdfBuilder : BasePdfBuilder
{
private readonly Document _document;
public MigraDocPdfBuilder()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_document = new Document();
DefineStyles();
}
public override BasePdfBuilder AddHeader(string header)
{
_document.AddSection().AddParagraph(header, "NormalBold");
return this;
}
public override BasePdfBuilder AddParagraph(string text)
{
_document.LastSection.AddParagraph(text, "Normal");
return this;
}
public override BasePdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data)
{
if (data == null || data.Count == 0)
{
return this;
}
var chart = new Chart(ChartType.Pie2D);
var series = chart.SeriesCollection.AddSeries();
series.Add(data.Select(x => x.Value).ToArray());
var xseries = chart.XValues.AddXSeries();
xseries.Add(data.Select(x => x.Caption).ToArray());
chart.DataLabel.Type = DataLabelType.Percent;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
chart.Width = Unit.FromCentimeter(16);
chart.Height = Unit.FromCentimeter(12);
chart.TopArea.AddParagraph(title);
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.TopArea.AddLegend();
_document.LastSection.Add(chart);
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(stream);
return stream;
}
private void DefineStyles()
{
var headerStyle = _document.Styles.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@@ -0,0 +1,303 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace DaisiesBuisnessLogic.OfficePackage;
public class OpenXmlExcelBuilder : BaseExcelBuilder
{
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public OpenXmlExcelBuilder()
{
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public override BaseExcelBuilder AddHeader(string header, int startIndex, int count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference =
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public override BaseExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public override BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
{
if (columnsWidths == null || columnsWidths.Length == 0)
{
throw new ArgumentNullException(nameof(columnsWidths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != columnsWidths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
uint counter = 1;
int coef = 2;
_columns.Append(columnsWidths.Select(x => new Column
{
Min = counter,
Max = counter++,
Width = x * coef,
CustomWidth = true
}));
for (var j = 0; j < data.First().Length; ++j)
{
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
for (var i = 1; i < data.Count - 1; ++i)
{
for (var j = 0; j < data[i].Length; ++j)
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
GenerateStyle(workbookpart);
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
if (_columns.HasChildren)
{
worksheetPart.Worksheet.Append(_columns);
}
worksheetPart.Worksheet.Append(_sheetData);
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист 1"
};
sheets.Append(sheet);
if (_mergeCells.HasChildren)
{
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
}
return stream;
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2, KnownFonts = BooleanValue.FromBoolean(true) };
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) }
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) },
Bold = new Bold()
});
workbookStylesPart.Stylesheet.Append(fonts);
// Default Fill
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill() { PatternType = new EnumValue<PatternValues>(PatternValues.None) }
});
workbookStylesPart.Stylesheet.Append(fills);
// Default Border
var borders = new Borders() { Count = 2 };
borders.Append(new Border
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
borders.Append(new Border
{
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin },
RightBorder = new RightBorder() { Style = BorderStyleValues.Thin },
TopBorder = new TopBorder() { Style = BorderStyleValues.Thin },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }
});
workbookStylesPart.Stylesheet.Append(borders);
// Default cell format and a date cell format
var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorder = 1,
BoldTextWithoutBorder = 2,
BoldTextWithBorder = 3
}
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
{
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex;
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>()
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
private static string GetExcelColumnName(int columnNumber)
{
columnNumber += 1;
int dividend = columnNumber;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
}

View File

@@ -0,0 +1,94 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
namespace DaisiesBuisnessLogic.OfficePackage;
public class OpenXmlWordBuilder : BaseWordBuilder
{
private readonly Document _document;
private readonly Body _body;
public OpenXmlWordBuilder()
{
_document = new Document();
_body = _document.AppendChild(new Body());
}
public override BaseWordBuilder AddHeader(string header)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new RunProperties(new Bold()));
run.AppendChild(new Text(header));
return this;
}
public override BaseWordBuilder AddParagraph(string text)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text(text));
return this;
}
public override BaseWordBuilder AddTable(int[] widths, List<string[]> data)
{
if (widths == null || widths.Length == 0)
{
throw new ArgumentNullException(nameof(widths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != widths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
var table = new Table();
table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 }
)
));
// Заголовок
var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j)
{
tr.Append(new TableCell(
new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
}
table.Append(tr);
// Данные
table.Append(data.Skip(1).Select(x =>
new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y))))))));
_body.Append(table);
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
var mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = _document;
return stream;
}
}

View File

@@ -0,0 +1,17 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface IBuyerAdapter
{
BuyerOperationResponse GetList();
BuyerOperationResponse GetElement(string data);
BuyerOperationResponse RegisterBuyer(BuyerBindingModel buyerModel);
BuyerOperationResponse ChangeBuyerInfo(BuyerBindingModel buyerModel);
BuyerOperationResponse RemoveBuyer(string id);
}

View File

@@ -0,0 +1,13 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface IClientDiscountAdapter
{
ClientDiscountOperationResponse GetList(bool onlyActive = true);
ClientDiscountOperationResponse GetElement(string data);
ClientDiscountOperationResponse RegisterClientDiscount(ClientDiscountBindingModel clientDiscountModel);
ClientDiscountOperationResponse ChangeClientDiscountInfo(ClientDiscountBindingModel clientDiscountModel);
}

View File

@@ -0,0 +1,21 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface IPostAdapter
{
PostOperationResponse GetList();
PostOperationResponse GetHistory(string id);
PostOperationResponse GetElement(string data);
PostOperationResponse RegisterPost(PostBindingModel postModel);
PostOperationResponse ChangePostInfo(PostBindingModel postModel);
PostOperationResponse RemovePost(string id);
PostOperationResponse RestorePost(string id);
}

View File

@@ -0,0 +1,15 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface IProductAdapter
{
ProductOperationResponse GetList(bool includeDeleted);
ProductOperationResponse GetSupplierList(string id, bool includeDeleted);
ProductOperationResponse GetHistory(string id);
ProductOperationResponse GetElement(string data);
ProductOperationResponse RegisterProduct(ProductBindingModel productModel);
ProductOperationResponse ChangeProductInfo(ProductBindingModel productModel);
ProductOperationResponse RemoveProduct(string id);
}

View File

@@ -0,0 +1,13 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
namespace DaisiesContracts.AdapterContracts;
public interface IReportAdapter
{
Task<ReportOperationResponse> GetDataProductPricesByProductAsync(CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentProductPricesByProductAsync(CancellationToken ct);
Task<ReportOperationResponse> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> GetDataClientDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<ReportOperationResponse> CreateDocumentClientDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -0,0 +1,21 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface ISaleAdapter
{
SaleOperationResponse GetList(DateTime fromDate, DateTime toDate);
SaleOperationResponse GetWorkerList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetBuyerList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetProductList(string id, DateTime fromDate, DateTime toDate);
SaleOperationResponse GetElement(string id);
SaleOperationResponse MakeSale(SaleBindingModel saleModel);
SaleOperationResponse CancelSale(string id);
}

View File

@@ -0,0 +1,23 @@
using DaisiesContracts.AdapterContracts.OperationResponses;
using DaisiesContracts.BindingModels;
namespace DaisiesContracts.AdapterContracts;
public interface IWorkerAdapter
{
WorkerOperationResponse GetList(bool includeDeleted);
WorkerOperationResponse GetPostList(string id, bool includeDeleted);
WorkerOperationResponse GetListByBirthDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
WorkerOperationResponse GetListByEmploymentDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
WorkerOperationResponse GetElement(string data);
WorkerOperationResponse RegisterWorker(WorkerBindingModel workerModel);
WorkerOperationResponse ChangeWorkerInfo(WorkerBindingModel workerModel);
WorkerOperationResponse RemoveWorker(string id);
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,22 @@
using DaisiesContracts.Infrastructure;
using DaisiesContracts.ViewModels;
namespace DaisiesContracts.AdapterContracts.OperationResponses;
public class ProductOperationResponse : OperationResponse
{
public static ProductOperationResponse OK(List<ProductViewModel> data) =>
OK<ProductOperationResponse, List<ProductViewModel>>(data);
public static ProductOperationResponse OK(List<ProductHistoryViewModel>
data) => OK<ProductOperationResponse, List<ProductHistoryViewModel>>(data);
public static ProductOperationResponse OK(ProductViewModel data) =>
OK<ProductOperationResponse, ProductViewModel>(data);
public static ProductOperationResponse NoContent() =>
NoContent<ProductOperationResponse>();
public static ProductOperationResponse NotFound(string message) =>
NotFound<ProductOperationResponse>(message);
public static ProductOperationResponse BadRequest(string message) =>
BadRequest<ProductOperationResponse>(message);
public static ProductOperationResponse InternalServerError(string message)
=> InternalServerError<ProductOperationResponse>(message);
}

View File

@@ -0,0 +1,14 @@
using DaisiesContracts.Infrastructure;
using DaisiesContracts.ViewModels;
namespace DaisiesContracts.AdapterContracts.OperationResponses;
public class ReportOperationResponse : OperationResponse
{
public static ReportOperationResponse OK(List<ProductProductHistoryViewModel> data) => OK<ReportOperationResponse, List<ProductProductHistoryViewModel>>(data);
public static ReportOperationResponse OK(List<SaleViewModel> data) => OK<ReportOperationResponse, List<SaleViewModel>>(data);
public static ReportOperationResponse OK(Stream data, string filename) => OK<ReportOperationResponse, Stream>(data, filename);
public static ReportOperationResponse BadRequest(string message) => BadRequest<ReportOperationResponse>(message);
public static ReportOperationResponse InternalServerError(string message) => InternalServerError<ReportOperationResponse>(message);
public static ReportOperationResponse OK(List<ClientDiscountByPeriodViewModel> data) => OK<ReportOperationResponse, List<ClientDiscountByPeriodViewModel>>(data);
}

View File

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

View File

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

View File

@@ -0,0 +1,12 @@
namespace DaisiesContracts.BindingModels;
public class BuyerBindingModel
{
public string? Id { get; set; }
public string? FIO { get; set; }
public string? PhoneNumber { get; set; }
public double DiscountSize { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace DaisiesContracts.BindingModels;
public class ClientDiscountBindingModel
{
public string BuyerId { get; set; }
public string BuyerFIO { get; set; }
public double TotalSum { get; set; }
public double PersonalDiscount { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace DaisiesContracts.BindingModels;
public class PostBindingModel
{
public string? Id { get; set; }
public string? PostId => Id;
public string? PostName { get; set; }
public string? PostType { get; set; }
public double Salary { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace DaisiesContracts.BindingModels;
public class ProductBindingModel
{
public required string Id { get; set; }
public string? ProductName { get; set; }
public string? SupplierId { get; set; }
public string? ProductType { get; set; }
public double Price { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace DaisiesContracts.BindingModels;
public class SaleBindingModel
{
public string? Id { get; set; }
public string? WorkerId { get; set; }
public string? BuyerId { get; set; }
public int DiscountType { get; set; }
public List<SaleProductBindingModel>? Products { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace DaisiesContracts.BindingModels;
public class SaleProductBindingModel
{
public string? SaleId { get; set; }
public string? ProductId { get; set; }
public int Count { get; set; }
public double Price { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace DaisiesContracts.BindingModels;
public class WorkerBindingModel
{
public string? Id { get; set; }
public string? FIO { get; set; }
public string? PostId { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
}

View File

@@ -0,0 +1,16 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IBuyerBuisnessLogicContract
{
List<BuyerDataModel> GetAllBuyers();
BuyerDataModel GetBuyerByData(string data);
void InsertBuyer(BuyerDataModel buyerDataModel);
void UpdateBuyer(BuyerDataModel buyerDataModel);
void DeleteBuyer(string id);
}

View File

@@ -0,0 +1,16 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IClientDiscountBuisnessLogicContract
{
List<ClientDiscountDataModel> GetAllClientDiscounts();
ClientDiscountDataModel GetClientDiscountByBuyerId(string buyerId);
void InsertClientDiscount(ClientDiscountDataModel clientDiscountDataModel);
void UpdateClientDiscount(ClientDiscountDataModel clientDiscountDataModel);
void DeleteClientDiscount(string buyerId);
}

View File

@@ -0,0 +1,20 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IPostBuisnessLogicContract
{
List<PostDataModel> GetAllPosts();
List<PostDataModel> GetAllDataOfPost(string postId);
PostDataModel GetPostByData(string data);
void InsertPost(PostDataModel postDataModel);
void UpdatePost(PostDataModel postDataModel);
void DeletePost(string id);
void RestorePost(string id);
}

View File

@@ -0,0 +1,19 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IProductBuisnessLogicContract
{
List<ProductDataModel> GetAllProducts(bool onlyActive = true);
List<ProductDataModel> GetAllProductsBySupplier(string supplierId, bool onlyActive = true);
List<ProductHistoryDataModel> GetProductHistoryByProduct(string productId);
ProductDataModel GetProductByData(string data);
void InsertProduct(ProductDataModel productDataModel);
void UpdateProduct(ProductDataModel productDataModel);
void DeleteProduct(string id);
}

View File

@@ -0,0 +1,14 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IReportContract
{
Task<List<ProductProductHistoryDataModel>> GetDataProductPricesByProductAsync(CancellationToken ct);
Task<Stream> CreateDocumentProductPricesByProductAsync(CancellationToken ct);
Task<Stream> CreateDocumentSalesByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<List<ClientDiscountByPeriodDataModel>> GetDataDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<Stream> CreateDocumentDiscountByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
Task<List<SaleDataModel>> GetDataSaleByPeriodAsync(DateTime dateStart, DateTime dateFinish, CancellationToken ct);
}

View File

@@ -0,0 +1,20 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface ISaleBuisnessLogicContract
{
List<SaleDataModel> GetAllSalesByPeriod(DateTime fromDate, DateTime toDate);
List<SaleDataModel> GetAllSalesByWorkerByPeriod(string workerId, DateTime fromDate, DateTime toDate);
List<SaleDataModel> GetAllSalesByBuyerByPeriod(string buyerId, DateTime fromDate, DateTime toDate);
List<SaleDataModel> GetAllSalesByProductByPeriod(string productId, DateTime fromDate, DateTime toDate);
SaleDataModel GetSaleByData(string data);
void InsertSale(SaleDataModel saleDataModel);
void CancelSale(string id);
}

View File

@@ -0,0 +1,15 @@
using DaisiesContracts.DataModels;
namespace DaisiesContracts.BuisnessLogicContracts;
public interface IWorkerBuisnessLogicContract
{
List<WorkerDataModel> GetAllWorkers(bool onlyActive = true);
List<WorkerDataModel> GetAllWorkersByPost(string postId, bool onlyActive = true);
List<WorkerDataModel> GetAllWorkersByBirthDate(DateTime fromDate, DateTime toDate, bool onlyActive = true);
List<WorkerDataModel> GetAllWorkersByEmploymentDate(DateTime fromDate, DateTime toDate, bool onlyActive = true);
WorkerDataModel GetWorkerByData(string data);
void InsertWorker(WorkerDataModel workerDataModel);
void UpdateWorker(WorkerDataModel workerDataModel);
void DeleteWorker(string id);
}

View File

@@ -1,9 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.5" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,41 +0,0 @@
using DaisiesContracts.Enums;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class BouquetDataModel(string id, string employeeId, string? customerId, string name, DateTime compositionDate, BouquetType type, List<BouquetItemDataModel> items) : IValidation
{
public string Id { get; private set; } = id;
/// <summary>
/// Идентификатор сотрудника (обычно флориста), составившего букет.
/// </summary>
public string EmployeeId { get; private set; } = employeeId;
/// <summary>
/// Идентификатор покупателя (необязательное поле для клиентов без регистрации).
/// </summary>
public string? CustomerId { get; private set; } = customerId;
public string Name { get; private set; } = name;
public DateTime CompositionDate { get; private set; } = compositionDate;
public BouquetType Type { get; private set; } = type;
public List<BouquetItemDataModel> Items { get; private set; } = items;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Bouquet Id пустой");
if (!Id.IsGuid())
throw new ValidationException("Bouquet Id не является валидным GUID");
if (EmployeeId.IsEmpty())
throw new ValidationException("Employee Id пустой");
if (!EmployeeId.IsGuid())
throw new ValidationException("Employee Id не является валидным GUID");
if (!string.IsNullOrEmpty(CustomerId) && !CustomerId.IsGuid())
throw new ValidationException("Customer Id не является валидным GUID");
if (Type == BouquetType.None)
throw new ValidationException("Тип букета должен быть указан");
if ((Items?.Count ?? 0) == 0)
throw new ValidationException("Букет должен содержать хотя бы один элемент");
}
}

View File

@@ -1,20 +0,0 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class BouquetHistoryDataModel(string bouquetId, string oldName, DateTime changeDate) : IValidation
{
public string BouquetId { get; private set; } = bouquetId;
public string OldName { get; private set; } = oldName;
public DateTime ChangeDate { get; private set; } = changeDate;
public void Validate()
{
if (BouquetId.IsEmpty())
throw new ValidationException("Bouquet Id пустой");
if (!BouquetId.IsGuid())
throw new ValidationException("Bouquet Id не является валидным GUID");
}
}

View File

@@ -1,21 +0,0 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class BouquetItemDataModel(string flowerId, int quantity) : IValidation
{
public string FlowerId { get; private set; } = flowerId;
public int Quantity { get; private set; } = quantity;
public void Validate()
{
if (FlowerId.IsEmpty())
throw new ValidationException("Flower Id пустой");
if (!FlowerId.IsGuid())
throw new ValidationException("Flower Id не является валидным GUID");
if (Quantity <= 0)
throw new ValidationException("Количество должно быть больше 0");
}
}

View File

@@ -0,0 +1,71 @@
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
using System.Text.RegularExpressions;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Infrastructure.BuyerConfigurations;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace DaisiesContracts.DataModels;
public class BuyerDataModel : IValidation
{
public string Id { get; private set; }
public string FIO { get; private set; }
public string PhoneNumber { get; private set; }
public double DiscountSize { get; private set; }
public BuyerConfiguration ConfigurationModel { get; private set; }
public BuyerDataModel(string id, string fio, string phoneNumber, double discountSize, BuyerConfiguration buyerConfiguration)
{
Id = id;
FIO = fio;
PhoneNumber = phoneNumber;
DiscountSize = discountSize;
ConfigurationModel = buyerConfiguration;
}
public BuyerDataModel(string id, string fio, string phoneNumber, double discountSize, string configurationJson)
: this(id, fio, phoneNumber, discountSize, (BuyerConfiguration)null)
{
var obj = JToken.Parse(configurationJson);
if (obj is not null)
{
ConfigurationModel = obj.Value<string>("Type") switch
{
nameof(ConstantBuyerConfiguration) => JsonConvert.DeserializeObject<ConstantBuyerConfiguration>(configurationJson)!,
nameof(VipBuyerConfiguration) => JsonConvert.DeserializeObject<VipBuyerConfiguration>(configurationJson)!,
_ => JsonConvert.DeserializeObject<BuyerConfiguration>(configurationJson)!,
};
}
}
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
if (FIO.IsEmpty())
throw new ValidationException("Field FIO is empty");
if (!Regex.IsMatch(FIO, @"^([А-ЯЁ][а-яё]*(-[А-ЯЁ][а-яё]*)?)\s([А-ЯЁ]\.?\s?([А-ЯЁ]\.?\s?)?)?$"))
throw new ValidationException("Field FIO is not a fio");
if (PhoneNumber.IsEmpty()) throw new ValidationException("Field PhoneNumber is empty");
if (!Regex.IsMatch(PhoneNumber, @"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\-]?)?[\d\- ]{7,10}$")) throw new ValidationException("Field PhoneNumber is not a phone number");
if (ConfigurationModel is null)
throw new ValidationException("Field ConfigurationModel is not initialized");
if (ConfigurationModel!.DiscountMultiplier < 0)
throw new ValidationException("Field DiscountRate is less zero");
if (ConfigurationModel!.DiscountMultiplier > 1)
throw new ValidationException("Field DiscountRate is more one");
}
public BuyerDataModel()
{
Id = Guid.NewGuid().ToString();
FIO = "Иванов И.И.";
PhoneNumber = "+7-777-777-77-77";
DiscountSize = .0001;
ConfigurationModel = new BuyerConfiguration() { DiscountMultiplier = (int).0001 };
}
}

View File

@@ -0,0 +1,8 @@
namespace DaisiesContracts.DataModels;
public class ClientDiscountByPeriodDataModel
{
public required string BuyerFIO { get; set; }
public double TotalDiscount { get; set; }
public DateTime FromPeriod { get; set; }
public DateTime ToPeriod { get; set; }
}

View File

@@ -0,0 +1,54 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class ClientDiscountDataModel(string buyerId, double totalSum, double personalDiscount, DateTime? discountDate = null) : IValidation
{
private readonly BuyerDataModel? _buyer;
public string BuyerId { get; private set; } = buyerId;
public double TotalSum { get; private set; } = totalSum;
public double PersonalDiscount { get; private set; } = personalDiscount;
public DateTime DiscountDate { get; private set; } = discountDate ?? DateTime.UtcNow;
public string BuyerFIO => _buyer?.FIO ?? string.Empty;
public ClientDiscountDataModel(string? buyerId, double totalSum, double personalDiscount, BuyerDataModel buyer) : this(buyerId, totalSum, personalDiscount)
{
_buyer = buyer;
}
public ClientDiscountDataModel(string? buyerId, double totalSum, double personalDiscount, BuyerDataModel buyer, DateTime discountDate) : this(buyerId, totalSum, personalDiscount, discountDate)
{
_buyer = buyer;
}
public void Validate()
{
if (BuyerId.IsEmpty())
{
throw new ValidationException("Field Id is empty");
}
if (!BuyerId.IsGuid())
{
throw new ValidationException("The value in the field Id is not a unique identifier");
}
if (TotalSum < 0)
{
throw new ValidationException("TotalSum cannot be less than zero");
}
if (PersonalDiscount < 0)
{
throw new ValidationException("PersonalDiscount cannot be less than zero");
}
}
}

View File

@@ -1,28 +0,0 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
using System.Text.RegularExpressions;
namespace DaisiesContracts.DataModels;
public class CustomerDataModel(string id, string fullName, string phoneNumber, decimal discount, DateTime registrationDate) : IValidation
{
public string Id { get; private set; } = id;
public string FullName { get; private set; } = fullName;
public string PhoneNumber { get; private set; } = phoneNumber;
public DateTime RegistrationDate { get; private set; } = registrationDate;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Customer Id пустой");
if (!Id.IsGuid())
throw new ValidationException("Customer Id не является валидным GUID");
if (FullName.IsEmpty())
throw new ValidationException("Customer Full Name пустой");
if (PhoneNumber.IsEmpty())
throw new ValidationException("Customer Phone Number пустой");
if (!Regex.IsMatch(PhoneNumber, @"^(?:\+?7|8)?(?:[\s\-(_]+)?(\d{3})(?:[\s\-_)]+)?(\d{3})(?:[\s\-_]+)?(\d{2})(?:[\s\-_]+)?(\d{2})$"))
throw new ValidationException("PhoneNumber не является номером телефона");
}
}

View File

@@ -1,29 +0,0 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class CustomerDiscount(string id, string customerId, decimal discount) : IValidation
{
public string Id { get; private set; } = id;
public string CustomerId { get; private set; } = customerId;
/// <summary>
/// Скидка в процентах (от 0 до 100)
/// </summary>
public decimal Discount { get; private set; } = discount;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("History Id пустой");
if (!Id.IsGuid())
throw new ValidationException("History Id не является валидным GUID");
if (CustomerId.IsEmpty())
throw new ValidationException("Customer Id пустой");
if (!CustomerId.IsGuid())
throw new ValidationException("Customer Id не является валидным GUID");
if (Discount < 0 || Discount > 100)
throw new ValidationException("Скидка должна быть в диапазоне от 0 до 100");
}
}

View File

@@ -1,30 +0,0 @@
using DaisiesContracts.Enums;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
using System.Text.RegularExpressions;
namespace DaisiesContracts.DataModels;
public class EmployeeDataModel(string id, string fullName, EmployeeRole role, DateTime employmentDate, bool isActive) : IValidation
{
public string Id { get; private set; } = id;
public string FullName { get; private set; } = fullName;
public EmployeeRole Role { get; private set; } = role;
public DateTime EmploymentDate { get; private set; } = employmentDate;
public bool IsActive { get; private set; } = isActive;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Employee Id пустой");
if (!Id.IsGuid())
throw new ValidationException("Employee Id не является валидным GUID");
if (FullName.IsEmpty())
throw new ValidationException("Employee Full Name пустой");
if (!Regex.IsMatch(FullName, @"^[A-ZА-ЯЁ][a-zа-яё]*(\s[A-ZА-ЯЁ][a-zа-яё]*)+$"))
throw new ValidationException("Поле FullName не является корректным полным именем");
if (EmploymentDate.Date > DateTime.Now.Date)
throw new ValidationException("Дата приема на работу не может быть в будущем");
}
}

View File

@@ -1,24 +0,0 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class FlowerDataModel(string id, string name, decimal price) : IValidation
{
public string Id { get; private set; } = id;
public string Name { get; private set; } = name;
public decimal Price { get; private set; } = price;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Flower Id пустой");
if (!Id.IsGuid())
throw new ValidationException("Flower Id не является валидным GUID");
if (Name.IsEmpty())
throw new ValidationException("Flower Name пустой");
if (Price <= 0)
throw new ValidationException("Цена цветка должна быть положительной");
}
}

View File

@@ -0,0 +1,35 @@
using DaisiesContracts.Enum;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class PostDataModel(string postId, string postName, PostType postType, double salary) : IValidation
{
public string Id { get; private set; } = postId;
public string PostName { get; private set; } = postName;
public PostType PostType { get; private set; } = postType;
public double Salary { get; private set; } = salary;
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
if (PostName.IsEmpty())
throw new ValidationException("Field PostName is empty");
if (PostType == PostType.None)
throw new ValidationException("Field PostType is empty");
if (Salary <= 0)
throw new ValidationException("Field Salary is empty");
}
}

View File

@@ -0,0 +1,47 @@
using DaisiesContracts.Enum;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class ProductDataModel : IValidation
{
public string Id { get; private set; }
public string ProductName { get; private set; }
public ProductType ProductType { get; private set; }
public string SupplierId { get; private set; }
public double Price { get; private set; }
public bool IsDeleted { get; private set; }
public ProductDataModel()
{
}
public ProductDataModel(string id, string productName, ProductType productType, string SupplierId, double price, bool isDeleted)
{
Id = id;
ProductName = productName;
ProductType = productType;
this.SupplierId = SupplierId;
Price = price;
IsDeleted = isDeleted;
}
public void Validate()
{
if (Id.IsEmpty()) { throw new ValidationException("Field Id is empty"); }
if (!Id.IsGuid()) { throw new ValidationException("The value in the field Id is a unique identifier"); }
if (ProductName.IsEmpty()) { throw new ValidationException("Field Id is empty"); }
if (ProductType == ProductType.None) { throw new ValidationException("Field ProductType is empty"); }
if (SupplierId.IsEmpty()) { throw new ValidationException("Field SupplierId is empty"); }
if (!SupplierId.IsGuid()) { throw new ValidationException("The value in the field SupplierId is not a unique identifier"); }
if (Price <= 0) { throw new ValidationException("Field Prise is less than or equal to 0"); }
}
}

View File

@@ -0,0 +1,35 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class ProductHistoryDataModel(string productId, double oldPrice) : IValidation
{
public ProductHistoryDataModel() : this(string.Empty, 0) { }
private readonly ProductDataModel? _product;
public string ProductId { get; private set; } = productId;
public double OldPrice { get; private set; } = oldPrice;
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
public string ProductName => _product?.ProductName ?? string.Empty;
public ProductHistoryDataModel(
string productId,
double oldPrice,
DateTime changeDate,
ProductDataModel product) : this(productId, oldPrice)
{
ChangeDate = changeDate;
_product = product;
}
public void Validate()
{
if (ProductId.IsEmpty()) { throw new ValidationException("Field ProductId is empty"); }
if (!ProductId.IsGuid()) { throw new ValidationException("The value in the field ProductId is a unique identifier"); }
if (OldPrice <= 0) { throw new ValidationException("Field OldPrice is less than or equal to 0"); }
}
}

View File

@@ -0,0 +1,8 @@
namespace DaisiesContracts.DataModels;
public class ProductProductHistoryDataModel
{
public required string ProductName { get; set; }
public required List<string> HistoryPriceProducts { get; set; }
public required List<string> Data { get; set; }
}

View File

@@ -0,0 +1,73 @@
using DaisiesContracts.DataModels;
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
public class SaleDataModel: IValidation
{
public string Id { get; private set; }
public string WorkerId { get; private set; }
public string? BuyerId { get; private set; }
public DateTime SaleDate { get; private set; }
public double Sum { get; private set; }
public bool IsCancel { get; private set; }
public List<SaleProductDataModel> Products { get; private set; }
private readonly BuyerDataModel? _buyer;
private readonly WorkerDataModel? _worker;
public string BuyerFIO => _buyer?.FIO ?? string.Empty;
public string WorkerFIO => _worker?.FIO ?? string.Empty;
public SaleDataModel(string id, string workerId, string? buyerId, DateTime saleDate, double sum, bool isCancel, List<SaleProductDataModel> saleProducts, WorkerDataModel worker, BuyerDataModel? buyer) : this(id, workerId, buyerId, sum, isCancel, saleProducts)
{
SaleDate = saleDate;
_worker = worker;
_buyer = buyer;
}
public SaleDataModel(string id, string workerId, string? buyerId, List<SaleProductDataModel> products) : this(id, workerId, buyerId, 1, false, products) { }
public SaleDataModel(string id, string workerId, string? buyerId, double sum, bool isCancel, List<SaleProductDataModel> products)
{
Id = id;
WorkerId = workerId;
BuyerId = buyerId;
Sum = sum;
IsCancel = isCancel;
Products = products;
}
public void Validate()
{
if (Id.IsEmpty())
throw new ValidationException("Field Id is empty");
if (!Id.IsGuid())
throw new ValidationException("The value in the field Id is not a unique identifier");
if (WorkerId.IsEmpty())
throw new ValidationException("Field WorkerId is empty");
if (!WorkerId.IsGuid())
throw new ValidationException("The value in the field WorkerId is not a unique identifier");
if (!BuyerId?.IsGuid() ?? !BuyerId?.IsEmpty() ?? false)
throw new ValidationException("The value in the field BuyerId is not a unique identifier");
if (Sum <= 0)
throw new ValidationException("Field Sum is less than or equal to 0");
if ((Products?.Count ?? 0) == 0)
throw new ValidationException("The sale must include products");
}
}

View File

@@ -0,0 +1,32 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
namespace DaisiesContracts.DataModels;
public class SaleProductDataModel(string saleId, string productId, int count) : IValidation
{
private readonly ProductDataModel? _product;
public string SaleId { get; private set; } = saleId;
public string ProductId { get; private set; } = productId;
public int Count { get; private set; } = count;
public string ProductName => _product?.ProductName ?? string.Empty;
public SaleProductDataModel(string saleId, string productId, int count, ProductDataModel product) : this(saleId, productId, count)
{
_product = product;
}
public void Validate()
{
if (SaleId.IsEmpty()) { throw new ValidationException("Field SaleId is empty"); }
if (!SaleId.IsGuid()) { throw new ValidationException("The value in the field SaleId is a unique identifier"); }
if (ProductId.IsEmpty()) { throw new ValidationException("Field ProductId is empty"); }
if (!ProductId.IsGuid()) { throw new ValidationException("The value in the field ProductId is a unique identifier"); }
if (Count <= 0) { throw new ValidationException("Field Count is less than or equal to 0"); }
}
}

View File

@@ -0,0 +1,50 @@
using DaisiesContracts.Exceptions;
using DaisiesContracts.Extensions;
using DaisiesContracts.Infrastructure;
using Microsoft.Extensions.Hosting;
namespace DaisiesContracts.DataModels;
public class WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation
{
public string Id { get; private set; } = id;
public string FIO { get; private set; } = fio;
public string PostId { get; private set; } = postId;
public DateTime BirthDate { get; private set; } = birthDate;
public DateTime EmploymentDate { get; private set; } = employmentDate;
public bool IsDeleted { get; private set; } = isDeleted;
private readonly PostDataModel? _post;
public string PostName => _post?.PostName ?? string.Empty;
public WorkerDataModel(string id, string fio, string postId, DateTime
birthDate, DateTime employmentDate, bool isDeleted, PostDataModel post) :
this(id, fio, postId, birthDate, employmentDate, isDeleted)
{
_post = post;
}
public WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate) :
this(id, fio, postId, birthDate, employmentDate, false)
{
}
public void Validate()
{
if (Id.IsEmpty()) { throw new ValidationException("Field Id is empty"); }
if (!Id.IsGuid()) { throw new ValidationException("The value in the field Id is a unique identifier"); }
if (FIO.IsEmpty()) { throw new ValidationException("Field FIO is empty"); }
if (PostId.IsEmpty()) { throw new ValidationException("Field PostId is empty"); }
if (!PostId.IsGuid()) { throw new ValidationException("The value in the field PostId is a unique identifier"); }
if (BirthDate.Date > DateTime.Now.AddYears(-16).Date) { throw new ValidationException($"Minors cannot be hired (BirthDate = {BirthDate.ToShortDateString()})"); }
if (EmploymentDate.Date < BirthDate.Date) { throw new ValidationException("The date of employment cannot be less than the date of birth"); }
if ((EmploymentDate - BirthDate).TotalDays / 365 < 16) { throw new ValidationException($"Minors cannot be hired (EmploymentDate - {EmploymentDate.ToShortDateString()}, BirthDate - {BirthDate.ToShortDateString()})"); }
}
}

View File

@@ -0,0 +1,10 @@
namespace DaisiesContracts.Enum;
[Flags]
public enum DiscountType
{
None = 0,
OnSale = 1,
RegularBuyer = 2,
Certificate = 4
}

View File

@@ -0,0 +1,9 @@
namespace DaisiesContracts.Enum;
public enum PostType
{
None = 0,
Administrator = 1,
Florist = 2,
Assistant = 3,
}

View File

@@ -0,0 +1,9 @@
namespace DaisiesContracts.Enum;
public enum ProductType
{
None = 0,
Composition = 1,
Bouquet = 2,
Accessory = 3
}

View File

@@ -1,9 +0,0 @@
namespace DaisiesContracts.Enums;
public enum BouquetType
{
None = 0,
Standard = 1,
Special = 2,
Wedding = 3
}

View File

@@ -1,9 +0,0 @@
namespace DaisiesContracts.Enums;
public enum EmployeeRole
{
None = 0,
Florist = 1,
Helper = 2,
Administrator = 3
}

View File

@@ -0,0 +1,9 @@
namespace DaisiesContracts.Exceptions;
public static class DateTimeExtensions
{
public static bool IsDateNotOlder(this DateTime date, DateTime olderDate)
{
return date >= olderDate;
}
}

View File

@@ -0,0 +1,6 @@
namespace DaisiesContracts.Exceptions;
public class ElementDeletedException : Exception
{
public ElementDeletedException(string id) : base($"Cannot modify a deleted item (id: {id})") { }
}

View File

@@ -0,0 +1,14 @@
namespace DaisiesContracts.Exceptions;
public class ElementExistsException : Exception
{
public string ParamName { get; private set; }
public string ParamValue { get; private set; }
public ElementExistsException(string paramName, string paramValue) : base($"There is already an element with value{paramValue} of parameter { paramName}")
{
ParamName = paramName;
ParamValue = paramValue;
}
}

View File

@@ -0,0 +1,11 @@
namespace DaisiesContracts.Exceptions;
public class ElementNotFoundException : Exception
{
public string Value { get; private set; }
public ElementNotFoundException(string value) : base($"Element not found at value = { value}")
{
Value = value;
}
}

View File

@@ -0,0 +1,8 @@
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace DaisiesContracts.Exceptions;
public class IncorrectDatesException : Exception
{
public IncorrectDatesException(DateTime start, DateTime end) : base($"The end date must be later than the start date..StartDate: { start: dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}") { }
}

View File

@@ -0,0 +1,6 @@
namespace DaisiesContracts.Exceptions;
public class NullListException : Exception
{
public NullListException() : base("The returned list is null") { }
}

View File

@@ -0,0 +1,6 @@
namespace DaisiesContracts.Exceptions;
public class StorageException : Exception
{
public StorageException(Exception ex) : base($"Error while working in storage: { ex.Message}", ex) { }
}

View File

@@ -1,5 +1,3 @@
namespace DaisiesContracts.Exceptions; namespace DaisiesContracts.Exceptions;
public class ValidationException(string message) : Exception(message) public class ValidationException(string message) : Exception(message) { }
{
}

Some files were not shown because too many files have changed in this diff Show More