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

This commit is contained in:
Есения Андрианова 2024-12-15 10:49:23 +04:00
parent 995ad19310
commit 8ff00e215b
17 changed files with 197 additions and 89 deletions

View File

@ -1,18 +1,22 @@
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(IConnectionString connectionString, ICheckRepository checkRepository, IProductRepository productRepository, ILoggerFactory loggerFactory)
{ {
_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>();
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(checkRepository));
} }
public bool CreateChart(string filePath, DateTime dateTime) public bool CreateChart(string filePath, DateTime dateTime)
@ -21,7 +25,7 @@ internal class ChartReport
{ {
new PdfBuilder(filePath) new PdfBuilder(filePath)
.AddHeader("Отчет по продажам товаров") .AddHeader("Отчет по продажам товаров")
.AddPieChart("Проданные товары", GetData(dateTime)) .AddPieChart("Проданные товары за" + dateTime.ToLongDateString(), GetData(dateTime)) // Диаграмма с продуктами
.Build(); .Build();
return true; return true;
@ -35,21 +39,17 @@ internal class ChartReport
private List<(string Caption, double Value)> GetData(DateTime dateTime) private List<(string Caption, double Value)> GetData(DateTime dateTime)
{ {
// Читаем чеки и их продукты за указанную дату с помощью оптимизированного метода
var checkData = _checkRepository var checkData = _checkRepository.ReadAll(startDate: dateTime.Date, endDate: dateTime.Date.AddDays(1))
.ReadAll() .SelectMany(x => x.Products)
.Where(x => x.PurchaseDate.Date == dateTime.Date) .GroupBy(p => p.ProductID)
.SelectMany(x => x.Products)
.GroupBy(p => p.ProductID)
.Select(g => .Select(g =>
{ {
var productName = _productRepository.Read(g.Key).Name;
var product = _productRepository.Read(g.Key); return (Caption: productName, Value: (double)g.Sum(p => p.Count));
return (Caption: product.Name, Value: (double)g.Sum(p => p.Count));
}) })
.ToList(); .ToList();
return checkData; return checkData;
} }
} }

View File

@ -84,10 +84,10 @@ namespace CompShop.DocumentsBuilder
CustomWidth = true CustomWidth = true
})); }));
// Добавляем строки таблицы
for (int i = 0; i < data.Count; ++i) for (int i = 0; i < data.Count; ++i)
{ {
var isBoldRow = i == 0 || i == data.Count - 1; var isBoldRow = i == 0 || i == data.Count - 1; // Только заголовок и последняя строка жирные
var styleIndex = isBoldRow ? StyleIndex.BoldTextWithBorders : StyleIndex.SimpleTextWithBorders; var styleIndex = isBoldRow ? StyleIndex.BoldTextWithBorders : StyleIndex.SimpleTextWithBorders;
for (int j = 0; j < data[i].Length; ++j) for (int j = 0; j < data[i].Length; ++j)
@ -143,6 +143,7 @@ namespace CompShop.DocumentsBuilder
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>(); var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet(); workbookStylesPart.Stylesheet = new Stylesheet();
// Шрифты
var fonts = new Fonts() { Count = 2 }; var fonts = new Fonts() { Count = 2 };
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{ {
@ -156,16 +157,16 @@ namespace CompShop.DocumentsBuilder
FontName = new FontName() { Val = "Calibri" } FontName = new FontName() { Val = "Calibri" }
}); });
// Заполнение
var fills = new Fills() { Count = 1 }; var fills = new Fills() { Count = 1 };
fills.Append(new Fill fills.Append(new Fill
{ {
PatternFill = new PatternFill { PatternType = PatternValues.None } PatternFill = new PatternFill { PatternType = PatternValues.None }
}); });
// Границы
var borders = new Borders() { Count = 2 }; var borders = new Borders() { Count = 2 };
borders.Append(new Border()); borders.Append(new Border()); // Без границ
borders.Append(new Border borders.Append(new Border
{ {
LeftBorder = new LeftBorder { Style = BorderStyleValues.Thin }, LeftBorder = new LeftBorder { Style = BorderStyleValues.Thin },
@ -174,7 +175,7 @@ namespace CompShop.DocumentsBuilder
BottomBorder = new BottomBorder { Style = BorderStyleValues.Thin } BottomBorder = new BottomBorder { Style = BorderStyleValues.Thin }
}); });
// Форматы ячеек
var cellFormats = new CellFormats() { Count = 4 }; var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat cellFormats.Append(new CellFormat
{ {
@ -182,14 +183,14 @@ namespace CompShop.DocumentsBuilder
FillId = 0, FillId = 0,
BorderId = 0, BorderId = 0,
ApplyFont = true ApplyFont = true
}); }); // Обычный текст без границ
cellFormats.Append(new CellFormat cellFormats.Append(new CellFormat
{ {
FontId = 1, FontId = 1,
FillId = 0, FillId = 0,
BorderId = 0, BorderId = 0,
ApplyFont = true ApplyFont = true
}); }); // Жирный текст без границ
cellFormats.Append(new CellFormat cellFormats.Append(new CellFormat
{ {
FontId = 0, FontId = 0,
@ -197,7 +198,7 @@ namespace CompShop.DocumentsBuilder
BorderId = 1, BorderId = 1,
ApplyFont = true, ApplyFont = true,
ApplyBorder = true ApplyBorder = true
}); }); // Обычный текст с границами
cellFormats.Append(new CellFormat cellFormats.Append(new CellFormat
{ {
FontId = 1, FontId = 1,
@ -205,7 +206,7 @@ namespace CompShop.DocumentsBuilder
BorderId = 1, BorderId = 1,
ApplyFont = true, ApplyFont = true,
ApplyBorder = true ApplyBorder = true
}); }); // Жирный текст с границами
workbookStylesPart.Stylesheet.Append(fonts); workbookStylesPart.Stylesheet.Append(fonts);
workbookStylesPart.Stylesheet.Append(fills); workbookStylesPart.Stylesheet.Append(fills);

View File

@ -1,6 +1,10 @@
using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts; using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering; using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Chart = MigraDoc.DocumentObjectModel.Shapes.Charts.Chart; using Chart = MigraDoc.DocumentObjectModel.Shapes.Charts.Chart;

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CompShop.DocumentsBuilder
{
public class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}
}

View File

@ -1,19 +1,22 @@
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;
internal static readonly string[] Headers = { "Клиент", "Дата", "Количество" }; internal static readonly string[] Headers = { "Клиент", "Дата", "Количество" };
public TableReport(ICheckRepository checkRepository, IProductRepository productRepository, ILoggerFactory loggerFactory) public TableReport(IClientRepository clientRepository, ICheckRepository checkRepository, IProductRepository productRepository, ILoggerFactory loggerFactory)
{ {
_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));
_clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository));
_logger = loggerFactory.CreateLogger<TableReport>(); _logger = loggerFactory.CreateLogger<TableReport>();
} }
@ -22,7 +25,7 @@ internal class TableReport
try try
{ {
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Отчет по продажам товара", 0, 3) .AddHeader("Отчет по продажам товара " + _productRepository.Read(productId).Name, 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();
@ -38,40 +41,23 @@ 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 var checksWithProduct = _checkRepository.ReadAll(startDate, endDate, productId);
.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);
// Формирование итоговой таблицы
return new List<string[]> { Headers } var headers = new List<string[]> { Headers };
.Union( var rows = checksWithProduct.Select(x => new string[]
checksWithProduct.Select(x => new string[] {
{ _clientRepository.Read(x.ClientId).Name,
x.ClientName, x.PurchaseDate.ToShortDateString(),
x.Date.ToShortDateString(), x.Products.Count.ToString()
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();
} }
} }

View File

@ -35,12 +35,12 @@ namespace CompShop.DocumentsBuilder
var paragraph = _body.AppendChild(new Paragraph()); var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run()); var run = paragraph.AppendChild(new Run());
// Добавляем свойства для жирного текста
var runProperties = new RunProperties(); var runProperties = new RunProperties();
runProperties.AppendChild(new Bold()); runProperties.AppendChild(new Bold());
run.PrependChild(runProperties); run.PrependChild(runProperties);
// Добавляем текст заголовка
run.AppendChild(new Text(header)); run.AppendChild(new Text(header));
return this; return this;
@ -109,7 +109,7 @@ namespace CompShop.DocumentsBuilder
) )
)); ));
// Заголовок
var tr = new TableRow(); var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j) for (var j = 0; j < widths.Length; ++j)
{ {
@ -124,7 +124,7 @@ namespace CompShop.DocumentsBuilder
} }
table.Append(tr); table.Append(tr);
// Данные
table.Append(data.Skip(1).Select(x => table.Append(data.Skip(1).Select(x =>
new TableRow(x.Select(y => new TableCell(new Paragraph(new new TableRow(x.Select(y => new TableCell(new Paragraph(new
Run(new Text(y)))))))); Run(new Text(y))))))));

View File

@ -1,15 +1,20 @@
using CompShop.Entites; using CompShop.Entites;
using System.ComponentModel;
namespace CompShop.Entites namespace CompShop.Entites
{ {
public class Check public class Check
{ {
[System.ComponentModel.Browsable(false)]
public int Id { get; set; } public int Id { get; set; }
[DisplayName("Товары")]
public List<ProductInCheck> Products { get; set; } public List<ProductInCheck> Products { get; set; }
[DisplayName("Клиент")]
public Client Client { get; set; } public Client Client { get; set; }
[System.ComponentModel.Browsable(false)] [System.ComponentModel.Browsable(false)]
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("Дата покупки")]
public DateTime PurchaseDate { get; set; } public DateTime PurchaseDate { get; set; }
public static Check CreateEntity(int id, List<ProductInCheck> products, Client client, DateTime purchaseDate) public static Check CreateEntity(int id, List<ProductInCheck> products, Client client, DateTime purchaseDate)

View File

@ -1,6 +1,7 @@
using CompShop.Entites.Enums; using CompShop.Entites.Enums;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,8 +11,12 @@ namespace CompShop.Entites
public class Client public class Client
{ {
public int Id { get; set; } public int Id { get; set; }
[DisplayName("Имя")]
public string Name { get; set; } public string Name { get; set; }
[DisplayName("Номер телефона")]
public string PhoneNumber { get; set; } public string PhoneNumber { get; set; }
[DisplayName("Вид клиента")]
public ClientType ClientType { get; set; } public ClientType ClientType { get; set; }
public static Client CreateEntity(int id, string name, string phoneNumber, ClientType clientType) public static Client CreateEntity(int id, string name, string phoneNumber, ClientType clientType)

View File

@ -1,13 +1,18 @@
using CompShop.Entites.Enums; using CompShop.Entites.Enums;
using System.ComponentModel;
namespace CompShop.Entites namespace CompShop.Entites
{ {
public class Product public class Product
{ {
public int ID { get; private set; } public int ID { get; private set; }
[DisplayName("Имя")]
public string Name { get; private set; } public string Name { get; private set; }
[DisplayName("Описание")]
public string Description { get; private set; } public string Description { get; private set; }
[DisplayName("Цена")]
public decimal Price { get; private set; } public decimal Price { get; private set; }
[DisplayName("Вид")]
public ProductType ProductType { get; private set; } public ProductType ProductType { get; private set; }
public static Product CreateEntity(int id, string name, string desc, decimal price, ProductType productType) public static Product CreateEntity(int id, string name, string desc, decimal price, ProductType productType)

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -8,9 +9,13 @@ namespace CompShop.Entites
{ {
public class ProductInCheck public class ProductInCheck
{ {
[System.ComponentModel.Browsable(false)]
public int ID { get; set; } public int ID { get; set; }
[Browsable(false)]
public int ProductID { get; set; } public int ProductID { get; set; }
[Browsable(false)]
public int CheckID { get; set; } public int CheckID { get; set; }
[DisplayName("Количество")]
public int Count { get; set; } public int Count { get; set; }
public static ProductInCheck CreateElement(int id, int count) public static ProductInCheck CreateElement(int id, int count)
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -8,13 +9,17 @@ namespace CompShop.Entites
{ {
public class ProductsOnStorage public class ProductsOnStorage
{ {
[System.ComponentModel.Browsable(false)]
public int Id { get; set; } public int Id { get; set; }
[System.ComponentModel.Browsable(false)] [System.ComponentModel.Browsable(false)]
public int ProductId { get; set; } public int ProductId { get; set; }
[DisplayName("Товар")]
public Product Product { get; set; } public Product Product { get; set; }
[System.ComponentModel.Browsable(false)] [System.ComponentModel.Browsable(false)]
public int StorageId { get; set; } public int StorageId { get; set; }
[DisplayName("Склад")]
public Storage Storage { get; set; } public Storage Storage { get; set; }
[DisplayName("Количество")]
public int Count { get; set; } public int Count { get; set; }
public static ProductsOnStorage CreateEntity(int id, Product product, Storage storage, int count) public static ProductsOnStorage CreateEntity(int id, Product product, Storage storage, int count)

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,8 +10,11 @@ namespace CompShop.Entites
{ {
public class Storage public class Storage
{ {
[System.ComponentModel.Browsable(false)]
public int Id { get; set; } public int Id { get; set; }
[DisplayName("Вместимость")]
public int Size { get; set; } // Вместимость public int Size { get; set; } // Вместимость
[DisplayName("Адрес")]
public string Adress { get; set; } public string Adress { get; set; }
public static Storage CreateEntity(int id, int size, string adress) public static Storage CreateEntity(int id, int size, string adress)

View File

@ -37,7 +37,12 @@ namespace CompShop.Forms
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => productsDataGridView.DataSource = _repository.ReadAll(); private void LoadList()
{
productsDataGridView.DataSource = _repository.ReadAll();
productsDataGridView.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -36,7 +36,12 @@ namespace CompShop
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void LoadList() => productsDataGridView.DataSource = _productRepository.ReadAll(); private void LoadList()
{
productsDataGridView.DataSource = _productRepository.ReadAll();
productsDataGridView.Columns["ID"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id) private bool TryGetIdentifierFromSelectedRow(out int id)
{ {

View File

@ -16,13 +16,15 @@ namespace CompShop.Forms.Receipt
{ {
private readonly IUnityContainer _container; private readonly IUnityContainer _container;
private readonly ICheckRepository _checkRepository; private readonly ICheckRepository _checkRepository;
private readonly IClientRepository _clientRepository;
public CheckForm(IUnityContainer unityContainer, ICheckRepository checkRepository) public CheckForm(IUnityContainer unityContainer, ICheckRepository checkRepository, IClientRepository clientRepository)
{ {
InitializeComponent(); InitializeComponent();
_container = unityContainer ?? throw new ArgumentNullException(nameof(unityContainer)); _container = unityContainer ?? throw new ArgumentNullException(nameof(unityContainer));
_checkRepository = checkRepository ?? throw new ArgumentNullException(nameof(checkRepository)); _checkRepository = checkRepository ?? throw new ArgumentNullException(nameof(checkRepository));
_clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository));
} }
private void CheckForm_Load(object sender, EventArgs e) private void CheckForm_Load(object sender, EventArgs e)
@ -37,7 +39,17 @@ namespace CompShop.Forms.Receipt
} }
} }
private void LoadList() => checksDataGridView.DataSource = _checkRepository.ReadAll(); private void LoadList()
{
var checks = _checkRepository.ReadAll();
foreach (var check in checks)
{
check.Client = _clientRepository.Read(check.ClientId);
}
checksDataGridView.DataSource = checks;
}
private void addButton_Click(object sender, EventArgs e) private void addButton_Click(object sender, EventArgs e)
{ {

View File

@ -4,7 +4,7 @@ namespace CompShop.Repos
{ {
public interface ICheckRepository public interface ICheckRepository
{ {
IEnumerable<Check> ReadAll(); IEnumerable<Check> ReadAll(DateTime? startDate = null, DateTime? endDate = null, int? productId = null, int? clientId = null);
Check Read(int id); Check Read(int id);
void Create(Check check); void Create(Check check);
} }

View File

@ -1,11 +1,15 @@
using CompShop.Entites; using CompShop.DocumentsBuilder;
using CompShop.Entites;
using Dapper; using Dapper;
using DocumentFormat.OpenXml.Drawing.Charts;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql; using Npgsql;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using System.Windows.Forms;
namespace CompShop.Repos.Impements namespace CompShop.Repos.Impements
{ {
@ -92,32 +96,54 @@ namespace CompShop.Repos.Impements
} }
} }
public IEnumerable<Check> ReadAll() public IEnumerable<Check> ReadAll(DateTime? startDate = null, DateTime? endDate = null, int? productId = null, int? clientId = null)
{ {
_logger.LogInformation("Чтение всех чеков"); _logger.LogInformation("Чтение всех чеков с использованием фильтров");
using (var connection = CreateConnection()) try
{ {
try var builder = new QueryBuilder();
{
var checksSql = "SELECT * FROM \"Checks\"";
var checks = connection.Query<Check>(checksSql).ToList();
foreach (var check in checks) // Добавляем условия фильтрации, если параметры заданы
if (startDate.HasValue)
builder.AddCondition("\"Checks\".\"PurchaseDate\" >= @StartDate");
if (endDate.HasValue)
builder.AddCondition("\"Checks\".\"PurchaseDate\" <= @EndDate");
if (productId.HasValue)
builder.AddCondition("\"ProductsInCheck\".\"ProductID\" = @ProductId");
if (clientId.HasValue)
builder.AddCondition("\"Checks\".\"ClientId\" = @ClientId");
// Формируем основной SQL-запрос
var query = $"SELECT \"Checks\".*, \"Clients\".\"Name\" AS \"ClientName\" FROM \"Checks\" LEFT JOIN \"Clients\" ON \"Checks\".\"ClientId\" = \"Clients\".\"Id\" LEFT JOIN \"ProductsInCheck\" ON \"ProductsInCheck\".\"CheckId\" = \"Checks\".\"Id\" { builder.Build()} GROUP BY \"Checks\".\"Id\", \"Clients\".\"Name\" ORDER BY \"Checks\".\"PurchaseDate\"";
// Выполняем запрос
using var connection = CreateConnection();
var checks = connection.Query<Check, Client, Check>(
query,
(check, client) =>
{ {
check.Client = _clientRepository.Read(check.ClientId); check.Client = client;
return check;
},
new { StartDate = startDate, EndDate = endDate, ProductId = productId, ClientId = clientId },
splitOn: "ClientName"
).ToList();
var productSql = "SELECT * FROM \"ProductsInCheck\" WHERE \"CheckId\" = @CheckId"; // Загружаем товары для каждого чека
check.Products = connection.Query<ProductInCheck>(productSql, new { CheckId = check.Id }).ToList(); foreach (var check in checks)
}
return checks;
}
catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка при чтении всех чеков"); var productQuery = "SELECT * FROM \"ProductsInCheck\" WHERE \"CheckId\" = @CheckId";
throw; check.Products = connection.Query<ProductInCheck>(productQuery, new { CheckId = check.Id }).ToList();
} }
return checks;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении всех чеков");
throw;
} }
} }
} }
} }