Лабораторная 4

This commit is contained in:
Есения Андрианова 2024-12-16 11:45:49 +04:00
parent b92d13c0ee
commit 1f7e0c93e8
2 changed files with 45 additions and 30 deletions

View File

@ -1,14 +1,11 @@
using CompShop.DocumentsBuilder; using CompShop.DocumentsBuilder;
using CompShop.Repos; using CompShop.Repos;
using Dapper;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Npgsql;
internal class ChartReport internal class ChartReport
{ {
private readonly ICheckRepository _checkRepository; // Репозиторий для получения данных о чеках private readonly ICheckRepository _checkRepository; // Репозиторий для получения данных о чеках
private readonly IProductRepository _productRepository; // Репозиторий для получения данных о продуктах private readonly IProductRepository _productRepository; // Репозиторий для получения данных о продуктах
private readonly IConnectionString _connectionString;
private readonly ILogger<ChartReport> _logger; private readonly ILogger<ChartReport> _logger;
public ChartReport(ICheckRepository checkRepository, IProductRepository productRepository, ILoggerFactory loggerFactory) public ChartReport(ICheckRepository checkRepository, IProductRepository productRepository, ILoggerFactory loggerFactory)
@ -16,7 +13,6 @@ internal class ChartReport
_checkRepository = checkRepository ?? throw new ArgumentNullException(nameof(checkRepository)); _checkRepository = checkRepository ?? throw new ArgumentNullException(nameof(checkRepository));
_productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository)); _productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
_logger = loggerFactory.CreateLogger<ChartReport>(); _logger = loggerFactory.CreateLogger<ChartReport>();
} }
public bool CreateChart(string filePath, DateTime dateTime) public bool CreateChart(string filePath, DateTime dateTime)
@ -25,7 +21,7 @@ internal class ChartReport
{ {
new PdfBuilder(filePath) new PdfBuilder(filePath)
.AddHeader("Отчет по продажам товаров") .AddHeader("Отчет по продажам товаров")
.AddPieChart("Проданные товары", GetData(dateTime)) .AddPieChart("Проданные товары", GetData(dateTime)) // Диаграмма с продуктами
.Build(); .Build();
return true; return true;
@ -39,17 +35,21 @@ internal class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime) private List<(string Caption, double Value)> GetData(DateTime dateTime)
{ {
// Читаем чеки и их продукты за указанную дату с помощью оптимизированного метода // Получаем все чеки, которые были оформлены в указанную дату
var checkData = _checkRepository.ReadAll(startDate: dateTime.Date, endDate: dateTime.Date.AddDays(1)) var checkData = _checkRepository
.SelectMany(x => x.Products) .ReadAll()
.GroupBy(p => p.ProductID) .Where(x => x.PurchaseDate.Date == dateTime.Date) // Фильтрация по дате
.SelectMany(x => x.Products) // Получаем все продукты из всех чеков
.GroupBy(p => p.ProductID) // Группируем по ID продукта
.Select(g => .Select(g =>
{ {
var productName = _productRepository.Read(g.Key).Name; // Получаем продукт по ProductID
return (Caption: productName, Value: (double)g.Sum(p => p.Count)); var product = _productRepository.Read(g.Key);
return (Caption: product.Name, Value: (double)g.Sum(p => p.Count)); // Преобразуем Count в double
}) })
.ToList(); .ToList();
return checkData; return checkData;
} }
} }

View File

@ -1,12 +1,10 @@
using CompShop.DocumentsBuilder; using CompShop.DocumentsBuilder;
using CompShop.Entites;
using CompShop.Repos; using CompShop.Repos;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
internal class TableReport internal class TableReport
{ {
private readonly ICheckRepository _checkRepository; private readonly ICheckRepository _checkRepository;
private readonly IClientRepository _clientRepository;
private readonly IProductRepository _productRepository; private readonly IProductRepository _productRepository;
private readonly ILogger<TableReport> _logger; private readonly ILogger<TableReport> _logger;
@ -24,7 +22,7 @@ internal class TableReport
try try
{ {
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Отчет по продажам товара ", 0, 3) .AddHeader("Отчет по продажам товара", 0, 3)
.AddParagraph($"за период с {startDate.ToShortDateString()} по {endDate.ToShortDateString()}", 0) .AddParagraph($"за период с {startDate.ToShortDateString()} по {endDate.ToShortDateString()}", 0)
.AddTable(new[] { 20, 20, 15 }, GetData(productId, startDate, endDate)) .AddTable(new[] { 20, 20, 15 }, GetData(productId, startDate, endDate))
.Build(); .Build();
@ -40,23 +38,40 @@ internal class TableReport
private List<string[]> GetData(int productId, DateTime startDate, DateTime endDate) private List<string[]> GetData(int productId, DateTime startDate, DateTime endDate)
{ {
// Получение данных о чеках через SQL-запрос // Получение данных о чеках, содержащих указанный товар
var checksWithProduct = _checkRepository.ReadAll(startDate, endDate, productId); var checksWithProduct = _checkRepository
.ReadAll()
.Where(c => c.PurchaseDate >= startDate && c.PurchaseDate <= endDate
&& c.Products.Any(p => p.ProductID == productId))
.Select(c => new
{
ClientName = c.Client?.ToString() ?? "Неизвестно",
Date = c.PurchaseDate,
Quantity = c.Products
.Where(p => p.ProductID == productId)
.Sum(p => p.Count)
})
.OrderBy(x => x.Date);
// Формирование итоговой таблицы // Формирование итоговой таблицы
var headers = new List<string[]> { Headers }; return new List<string[]> { Headers }
var rows = checksWithProduct.Select(x => new string[] .Union(
{ checksWithProduct.Select(x => new string[]
_clientRepository.Read(x.ClientId).Name, {
x.PurchaseDate.ToShortDateString(), x.ClientName,
x.Products.Count.ToString() x.Date.ToShortDateString(),
}); x.Quantity.ToString()
})
var total = new[] )
{ .Union(new[]
new string[] { "Всего", "", checksWithProduct.Sum(x => x.Products.Count).ToString() } {
}; new string[]
{
return headers.Union(rows).Union(total).ToList(); "Всего",
"",
checksWithProduct.Sum(x => x.Quantity).ToString()
}
})
.ToList();
} }
} }