Report logic

This commit is contained in:
ShabOl 2024-05-02 00:10:15 +04:00
parent 6b9da32038
commit 16837f9d4d
17 changed files with 499 additions and 20 deletions

View File

@ -102,7 +102,7 @@ namespace ComputerShopBusinessLogic.BusinessLogics
if (string.IsNullOrEmpty(Model.Category))
throw new ArgumentException($"У сборки отсутствует категория");
if (Model.Price <= 0)
if (Model.Price < 0)
throw new ArgumentException("Цена сборки должна быть больше 0", nameof(Model.Price));
var Element = _assemblyStorage.GetElement(new AssemblySearchModel

View File

@ -110,7 +110,7 @@ namespace ComputerShopBusinessLogic.BusinessLogics
if (string.IsNullOrEmpty(Model.ProductName))
throw new ArgumentException($"У товара отсутствует название");
if (Model.Price <= 0)
if (Model.Price < 0)
throw new ArgumentException("Цена товара должна быть больше 0", nameof(Model.Price));
if (Model.Warranty <= 0)

View File

@ -0,0 +1,44 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
namespace ComputerShopBusinessLogic.BusinessLogics
{
public class ReportGuarantorLogic : IReportGuarantorLogic
{
private readonly IComponentStorage _componentStorage;
public ReportGuarantorLogic(IComponentStorage ComponentStorage)
{
_componentStorage = ComponentStorage;
}
/// <summary>
/// Получение отчёта для Word или Excel
/// </summary>
public List<ReportComponentWithShipmentViewModel> GetReportComponentsWithShipments(List<ComponentSearchModel> SelectedComponents)
{
return _componentStorage.GetComponentsWithShipments(SelectedComponents);
}
/// <summary>
/// Получение отчёта для отправки на почту
/// </summary>
public List<ReportComponentByDateViewModel> GetReportComponentsByRequestDate(UserSearchModel CurrentUser, ReportBindingModel Report)
{
return _componentStorage.GetComponentsByShipmentDate(Report, CurrentUser);
}
public void SaveReportToWordFile(ReportBindingModel Model)
{
throw new NotImplementedException();
}
public void SaveReportToExcelFile(ReportBindingModel Model)
{
throw new NotImplementedException();
}
}
}

View File

@ -15,5 +15,7 @@ namespace ComputerShopContracts.BindingModels
public string Category { get; set; } = string.Empty;
public Dictionary<int, (IComponentModel, int)> AssemblyComponents { get; set; } = new();
public Dictionary<int, int> Test { get; set; } = new();
}
}

View File

@ -0,0 +1,23 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.ViewModels;
namespace ComputerShopContracts.BusinessLogicContracts
{
public interface IReportGuarantorLogic
{
/// <summary>
/// Получение отчёта для Word или Excel
/// </summary>
List<ReportComponentWithShipmentViewModel> GetReportComponentsWithShipments(List<ComponentSearchModel> SelectedComponents);
/// <summary>
/// Получение отчёта для отправки на почту
/// </summary>
List<ReportComponentByDateViewModel> GetReportComponentsByRequestDate(UserSearchModel CurrentUser, ReportBindingModel Report);
void SaveReportToWordFile(ReportBindingModel Model);
void SaveReportToExcelFile(ReportBindingModel Model);
}
}

View File

@ -17,5 +17,9 @@ namespace ComputerShopContracts.StorageContracts
ComponentViewModel? Update(ComponentBindingModel Model);
ComponentViewModel? Delete(ComponentBindingModel Model);
List<ReportComponentWithShipmentViewModel> GetComponentsWithShipments(List<ComponentSearchModel> Models);
List<ReportComponentByDateViewModel> GetComponentsByShipmentDate(ReportBindingModel ReportModel, UserSearchModel UserModel);
}
}

View File

@ -0,0 +1,25 @@
namespace ComputerShopContracts.ViewModels
{
public class ReportComponentByDateViewModel
{
public int ComponentId { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double ComponentCost { get; set; }
public int AssemblyId { get; set; }
public string AssemblyName { get; set; } = string.Empty;
public double AssemblyPrice { get; set; }
public string AssemblyCategory { get; set; } = string.Empty;
public int RequestId { get; set; }
public DateTime DateRequest { get; set; }
public string ClientFIO { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,13 @@
namespace ComputerShopContracts.ViewModels
{
public class ReportComponentWithShipmentViewModel
{
public int ComponentId { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double ComponentCost { get; set; }
public List<(int Count, string ProductName, double ProductPrice, string ProviderName, DateTime ShipmentDate)> Shipments { get; set; } = new();
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerShopDataModels.Enums
namespace ComputerShopDataModels.Enums
{
public enum UserRole
{

View File

@ -17,6 +17,7 @@ namespace ComputerShopDatabaseImplement
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
}
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Component> Components { get; set; }
@ -31,9 +32,13 @@ namespace ComputerShopDatabaseImplement
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Request> Requests { get; set; }
public virtual DbSet<Shipment> Shipments { get; set; }
public virtual DbSet<ShipmentOrder> ShipmentOrders { get; set; }
public virtual DbSet<RequestOrder> RequestOrders { get; set; }
}
}

View File

@ -15,7 +15,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Select(x => x.ViewModel)
.ToList();
}
@ -29,7 +29,7 @@ namespace ComputerShopDatabaseImplement.Implements
{
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId && x.Category == Model.Category)
.Select(x => x.ViewModel)
.ToList();
@ -37,7 +37,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId)
.Select(x => x.ViewModel)
.ToList();
@ -52,14 +52,14 @@ namespace ComputerShopDatabaseImplement.Implements
{
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.AssemblyName == Model.AssemblyName)?
.ViewModel;
}
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.Id == Model.Id)?
.ViewModel;
}

View File

@ -3,6 +3,7 @@ using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
using ComputerShopDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace ComputerShopDatabaseImplement.Implements
{
@ -86,5 +87,56 @@ namespace ComputerShopDatabaseImplement.Implements
return ExistingComponent.ViewModel;
}
public List<ReportComponentWithShipmentViewModel> GetComponentsWithShipments(List<ComponentSearchModel> Models)
{
using var Context = new ComputerShopDatabase();
return Context.Components
.Include(x => x.ProductComponents)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Shipment)
.Where(x =>
Models.Select(x => x.Id).Contains(x.Id) // Компонент, указанный пользователем,
&& x.ProductComponents.Any(y => y.Product.Shipment != null)) // который содержится в товаре, имеющем партию товаров
.ToList()
.Select(x => new ReportComponentWithShipmentViewModel
{
ComponentId = x.Id,
ComponentName = x.ComponentName,
ComponentCost = x.Cost,
Shipments = x.ProductComponents
.Select(y => (y.Count, y.Product.ProductName, y.Product.Price, y.Product.Shipment!.ProviderName, y.Product.Shipment.DateShipment))
.ToList(),
})
.ToList();
}
public List<ReportComponentByDateViewModel> GetComponentsByShipmentDate(ReportBindingModel ReportModel, UserSearchModel UserModel)
{
using var Context = new ComputerShopDatabase();
return Context.Components
.Where(c => c.UserId == UserModel.Id)
.Include(c => c.AssemblyComponents)
.ThenInclude(ac => ac.Assembly)
.ThenInclude(a => a.Requests.Where(r => r.DateRequest >= ReportModel.DateFrom && r.DateRequest <= ReportModel.DateTo))
.ToList()
.SelectMany(c => c.AssemblyComponents
.SelectMany(ac => ac.Assembly.Requests.Select(r => new ReportComponentByDateViewModel
{
ComponentId = c.Id,
ComponentName = c.ComponentName,
ComponentCost = c.Cost,
AssemblyId = ac.Assembly.Id,
AssemblyName = ac.Assembly.AssemblyName,
AssemblyPrice = ac.Assembly.Price,
AssemblyCategory = ac.Assembly.Category,
RequestId = r.Id,
DateRequest = r.DateRequest,
ClientFIO = r.ClientFIO,
})))
.ToList();
}
}
}

View File

@ -16,7 +16,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Select(x => x.ViewModel)
.ToList();
}
@ -31,7 +31,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId && x.ShipmentId == Model.ShipmentId)
.Select(x => x.ViewModel)
.ToList();
@ -40,7 +40,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId)
.Select(x => x.ViewModel)
.ToList();
@ -56,7 +56,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.ProductName == Model.ProductName)?
.ViewModel;
}
@ -64,7 +64,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.Id == Model.Id)?
.ViewModel;
}

View File

@ -0,0 +1,114 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace ComputerShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class AssemblyController : Controller
{
private readonly ILogger _logger;
private readonly IAssemblyLogic _assemblyLogic;
private readonly IReportGuarantorLogic _reportGuarantorLogic;
public AssemblyController(IAssemblyLogic Logic, ILogger<AssemblyController> Logger, IReportGuarantorLogic reportGuarantorLogic)
{
_logger = Logger;
_assemblyLogic = Logic;
_reportGuarantorLogic = reportGuarantorLogic;
}
[HttpGet]
public AssemblyViewModel? GetAssembly(int Id)
{
try
{
return _assemblyLogic.ReadElement(new AssemblySearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения сборки");
throw;
}
}
[HttpGet]
public List<AssemblyViewModel>? GetAssemblies(int? UserId)
{
// Implementer should be able to get all assemblies for Request binding
if (UserId == null)
{
try
{
return _assemblyLogic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка всех сборок");
throw;
}
}
try
{
return _assemblyLogic.ReadList(new AssemblySearchModel
{
UserId = UserId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка сборок пользователя с Id = {Id}", UserId);
throw;
}
}
[HttpPost]
public void CreateAssembly(AssemblyBindingModel Model)
{
try
{
_assemblyLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания сборки");
throw;
}
}
[HttpPost]
public void UpdateAssembly(AssemblyBindingModel Model)
{
try
{
_assemblyLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления сборки");
throw;
}
}
[HttpDelete]
public void DeleteAssembly(AssemblyBindingModel Model)
{
try
{
_assemblyLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления сборки");
throw;
}
}
}
}

View File

@ -0,0 +1,98 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace ComputerShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ComponentController : Controller
{
private readonly ILogger _logger;
private readonly IComponentLogic _componentLogic;
public ComponentController(IComponentLogic Logic, ILogger<ComponentController> Logger)
{
_logger = Logger;
_componentLogic = Logic;
}
[HttpGet]
public ComponentViewModel? GetComponent(int Id)
{
try
{
return _componentLogic.ReadElement(new ComponentSearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения комплектующей");
throw;
}
}
[HttpGet]
public List<ComponentViewModel>? GetComponents(int? UserId)
{
try
{
return _componentLogic.ReadList(new ComponentSearchModel
{
UserId = UserId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка комплектующих пользователя с Id = {Id}", UserId);
throw;
}
}
[HttpPost]
public void CreateComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания комплектующей");
throw;
}
}
[HttpPost]
public void UpdateComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления комплектующей");
throw;
}
}
[HttpDelete]
public void DeleteComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления комплектующей");
throw;
}
}
}
}

View File

@ -0,0 +1,98 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace ComputerShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ProductController : Controller
{
private readonly ILogger _logger;
private readonly IProductLogic _productLogic;
public ProductController(IProductLogic Logic, ILogger<ProductController> Logger)
{
_logger = Logger;
_productLogic = Logic;
}
[HttpGet]
public ProductViewModel? GetProduct(int Id)
{
try
{
return _productLogic.ReadElement(new ProductSearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения товара");
throw;
}
}
[HttpGet]
public List<ProductViewModel>? GetProducts(int? UserId)
{
try
{
return _productLogic.ReadList(new ProductSearchModel
{
UserId = UserId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка товаров пользователя с Id = {Id}", UserId);
throw;
}
}
[HttpPost]
public void CreateProduct(ProductBindingModel Model)
{
try
{
_productLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания товара");
throw;
}
}
[HttpPost]
public void UpdateProduct(ProductBindingModel Model)
{
try
{
_productLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления товара");
throw;
}
}
[HttpDelete]
public void DeleteProduct(ProductBindingModel Model)
{
try
{
_productLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления товара");
throw;
}
}
}
}

View File

@ -13,12 +13,19 @@ Builder.Services.AddTransient<IUserStorage, UserStorage>();
Builder.Services.AddTransient<IShipmentStorage, ShipmentStorage>();
Builder.Services.AddTransient<IRequestStorage, RequestStorage>();
Builder.Services.AddTransient<IOrderStorage, OrderStorage>();
Builder.Services.AddTransient<IAssemblyStorage, AssemblyStorage>();
Builder.Services.AddTransient<IComponentStorage, ComponentStorage>();
Builder.Services.AddTransient<IProductStorage, ProductStorage>();
Builder.Services.AddTransient<IUserLogic, UserLogic>();
Builder.Services.AddTransient<IShipmentLogic, ShipmentLogic>();
Builder.Services.AddTransient<IRequestLogic, RequestLogic>();
Builder.Services.AddTransient<IOrderLogic, OrderLogic>();
Builder.Services.AddTransient<IAssemblyLogic, AssemblyLogic>();
Builder.Services.AddTransient<IComponentLogic, ComponentLogic>();
Builder.Services.AddTransient<IProductLogic, ProductLogic>();
Builder.Services.AddTransient<IReportGuarantorLogic, ReportGuarantorLogic>();
Builder.Services.AddControllers();