From 387952f66a6900809aa732f8965972767da7655e Mon Sep 17 00:00:00 2001 From: Glliza Date: Mon, 23 Dec 2024 17:55:39 +0400 Subject: [PATCH] =?UTF-8?q?=D0=AD=D0=A2=D0=9E=20=D0=9F=D0=9E=D0=91=D0=95?= =?UTF-8?q?=D0=94=D0=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ShoeStore/Entities/Employee.cs | 3 ++ ShoeStore/Entities/Product.cs | 4 ++ ShoeStore/Entities/ProductSale.cs | 1 + ShoeStore/Entities/Receipt.cs | 9 +++- ShoeStore/Entities/Sale.cs | 18 +++++--- ShoeStore/Entities/Storage.cs | 4 ++ ShoeStore/Entities/TempProductSale.cs | 15 ------- ShoeStore/Forms/FormEmployees.cs | 7 ++- ShoeStore/Forms/FormProducts.cs | 7 ++- ShoeStore/Forms/FormReceipts.cs | 6 ++- ShoeStore/Forms/FormSales.cs | 7 ++- ShoeStore/Forms/FormStorages.cs | 6 ++- ShoeStore/Reports/ChartReport.cs | 6 +-- ShoeStore/Reports/TableReport.cs | 8 ++-- .../Implementations/QueryBuilder.cs | 33 ++++++++++++++ .../Implementations/ReceiptRepository.cs | 4 +- .../Implementations/SaleRepository.cs | 43 +++++++++++++++---- 17 files changed, 138 insertions(+), 43 deletions(-) delete mode 100644 ShoeStore/Entities/TempProductSale.cs create mode 100644 ShoeStore/Repositories/Implementations/QueryBuilder.cs diff --git a/ShoeStore/Entities/Employee.cs b/ShoeStore/Entities/Employee.cs index 53c50a9..8ed9115 100644 --- a/ShoeStore/Entities/Employee.cs +++ b/ShoeStore/Entities/Employee.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -9,7 +10,9 @@ namespace ShoeStore.Entities; public class Employee { public int Id { get; private set; } + [DisplayName("Дата")] public DateTime Date { get; private set; } + [DisplayName("Номер склада")] public int NumberStorage { get; private set; } public static Employee CreateEntity(int id, DateTime date,int numberStorage) { diff --git a/ShoeStore/Entities/Product.cs b/ShoeStore/Entities/Product.cs index 1b58e8a..db1f209 100644 --- a/ShoeStore/Entities/Product.cs +++ b/ShoeStore/Entities/Product.cs @@ -1,6 +1,7 @@ using ShoeStore.Entities.Enums; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -11,8 +12,11 @@ namespace ShoeStore.Entities; public class Product { public int Id { get; private set; } + [DisplayName("Название обуви")] public string NameOfShoes { get; private set; } + [DisplayName("Компания производителя")] public ManufacturingCompany ManufacturingCompany { get; private set; } + [DisplayName("Цена")] public int Price { get; private set; } public static Product CreateEntity(int id, string nameOfShoes, ManufacturingCompany manufacturingCompany, int price) { diff --git a/ShoeStore/Entities/ProductSale.cs b/ShoeStore/Entities/ProductSale.cs index 6f096fc..e9147c9 100644 --- a/ShoeStore/Entities/ProductSale.cs +++ b/ShoeStore/Entities/ProductSale.cs @@ -11,6 +11,7 @@ public class ProductSale public int ProductId { get; private set; } public int SaleId { get; private set; } public int SalesNumber { get; private set; } + public string ProductName { get; private set; } public static ProductSale CreateOperation(int productId, int saleId, int salesNumber) { diff --git a/ShoeStore/Entities/Receipt.cs b/ShoeStore/Entities/Receipt.cs index 9c849bf..42e0aa4 100644 --- a/ShoeStore/Entities/Receipt.cs +++ b/ShoeStore/Entities/Receipt.cs @@ -1,6 +1,7 @@ using ShoeStore.Entities.Enums; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -10,10 +11,16 @@ namespace ShoeStore.Entities; public class Receipt { public int Id { get; private set; } + [DisplayName("Тип обуви")] public ProductType ProductType { get; private set; } + [DisplayName("Дата поступления")] public DateTime DateOfReceipt { get; private set; } - public int NumberOfPairsReceived { get; private set; } + [DisplayName("Количество")] + public int NumberOfPairsReceived { get; private set; } + [Browsable(false)] public int ProductId { get; private set; } + [DisplayName("Продукт")] + public string ProductName { get; private set; } public static Receipt CreateOperation(int id,ProductType productType, DateTime date,int numberOfPairsReceived, int productId) { diff --git a/ShoeStore/Entities/Sale.cs b/ShoeStore/Entities/Sale.cs index b93babc..16a68b6 100644 --- a/ShoeStore/Entities/Sale.cs +++ b/ShoeStore/Entities/Sale.cs @@ -2,6 +2,7 @@ using ShoeStore.Entities.Enums; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,13 +14,20 @@ namespace ShoeStore.Entities; public class Sale { public int Id { get; private set; } + [DisplayName("Дата продажи")] public DateTime DateOfSale { get; private set; } + + [Browsable(false)] public IEnumerable Product { get; private set; } = []; + [DisplayName("Продукты")] + public string Products => Product != null ? + string.Join(", ", Product.Select(x => $"{x.ProductName}, {x.SalesNumber}")) : string.Empty; + public static Sale CreateOperation(int id, DateTime date, IEnumerable product) { return new Sale @@ -30,14 +38,12 @@ public class Sale }; } - public static Sale CreateOperation(TempProductSale tempProductSale, IEnumerable products) + public void SetProductSales (IEnumerable products) { - return new Sale + if (products != null && products.Any()) { - Id = tempProductSale.Id, - DateOfSale = tempProductSale.DateOfSale, - Product = products - }; + Product = products; + } } } diff --git a/ShoeStore/Entities/Storage.cs b/ShoeStore/Entities/Storage.cs index c45fd25..4cfa012 100644 --- a/ShoeStore/Entities/Storage.cs +++ b/ShoeStore/Entities/Storage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -9,8 +10,11 @@ namespace ShoeStore.Entities; public class Storage { public int Id { get; private set; } + [DisplayName("Размер")] public int Size { get; private set; } + [DisplayName("Количество на складе")] public int QuantityInStock { get; private set; } + [DisplayName("Номер склада")] public int NumberStorage { get; private set; } public static Storage CreateEntity(int id, int size, int quantityInStock, int numberStorage) { diff --git a/ShoeStore/Entities/TempProductSale.cs b/ShoeStore/Entities/TempProductSale.cs deleted file mode 100644 index 4498636..0000000 --- a/ShoeStore/Entities/TempProductSale.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ShoeStore.Entities; - -public class TempProductSale -{ - public int Id { get; private set; } - public DateTime DateOfSale { get; private set; } - public int ProductId { get; private set; } - public int SalesNumber { get; private set; } -} diff --git a/ShoeStore/Forms/FormEmployees.cs b/ShoeStore/Forms/FormEmployees.cs index a5aed2d..48f819f 100644 --- a/ShoeStore/Forms/FormEmployees.cs +++ b/ShoeStore/Forms/FormEmployees.cs @@ -86,7 +86,12 @@ public partial class FormEmployees : Form MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - private void LoadList() => dataGridViewData.DataSource = _employeeRepository.ReadEmployees(); + private void LoadList() + { + dataGridViewData.DataSource = _employeeRepository.ReadEmployees(); + dataGridViewData.Columns["Id"].Visible = false; + } + private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/ShoeStore/Forms/FormProducts.cs b/ShoeStore/Forms/FormProducts.cs index f282cb1..d5dea85 100644 --- a/ShoeStore/Forms/FormProducts.cs +++ b/ShoeStore/Forms/FormProducts.cs @@ -83,7 +83,12 @@ namespace ShoeStore.Forms MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - private void LoadList() => dataGridViewProduct.DataSource = _productRepository.ReadProducts(); + private void LoadList() + { + dataGridViewProduct.DataSource = _productRepository.ReadProducts(); + dataGridViewProduct.Columns["Id"].Visible = false; + } + private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/ShoeStore/Forms/FormReceipts.cs b/ShoeStore/Forms/FormReceipts.cs index b8dfb3b..ffcda84 100644 --- a/ShoeStore/Forms/FormReceipts.cs +++ b/ShoeStore/Forms/FormReceipts.cs @@ -38,7 +38,11 @@ public partial class FormReceipts : Form } } - private void LoadList() => dataGridView1.DataSource = _receiptRepository.ReadReceipts(); + private void LoadList() + { + dataGridView1.DataSource = _receiptRepository.ReadReceipts(); + dataGridView1.Columns["Id"].Visible = false; + } private void FormReceipts_Load(object sender, EventArgs e) { diff --git a/ShoeStore/Forms/FormSales.cs b/ShoeStore/Forms/FormSales.cs index 79f4477..8474e9b 100644 --- a/ShoeStore/Forms/FormSales.cs +++ b/ShoeStore/Forms/FormSales.cs @@ -51,7 +51,12 @@ namespace ShoeStore.Froms MessageBoxButtons.OK, MessageBoxIcon.Error); } } - private void LoadList() => dataGridView1.DataSource = _saleRepository.ReadSales(); + private void LoadList() + { + dataGridView1.DataSource = _saleRepository.ReadSales(); + dataGridView1.Columns["Id"].Visible = false; + //dataGridView1.Columns["Date"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm"; + } private void buttonDel_Click(object sender, EventArgs e) { diff --git a/ShoeStore/Forms/FormStorages.cs b/ShoeStore/Forms/FormStorages.cs index 21f1d39..2af01ed 100644 --- a/ShoeStore/Forms/FormStorages.cs +++ b/ShoeStore/Forms/FormStorages.cs @@ -12,7 +12,11 @@ namespace ShoeStore.Forms private readonly IStorageRepository _storageRepository; - private void LoadList() => dataGridViewStorages.DataSource = _storageRepository.ReadStorages(); + private void LoadList() + { + dataGridViewStorages.DataSource = _storageRepository.ReadStorages(); + dataGridViewStorages.Columns["Id"].Visible = false; + } public FormStorages(IUnityContainer container, IStorageRepository storageRepository) diff --git a/ShoeStore/Reports/ChartReport.cs b/ShoeStore/Reports/ChartReport.cs index 3134b25..6ff1410 100644 --- a/ShoeStore/Reports/ChartReport.cs +++ b/ShoeStore/Reports/ChartReport.cs @@ -23,7 +23,7 @@ public class ChartReport { new PdfBuilder(filePath) .AddHeader("Количество поступивших товаров") - .AddPieChart("Товары", GetData(dateTime)) + .AddPieChart($"Товары на {dateTime: dd MMMM yyyy}", GetData(dateTime)) .Build(); return true; } @@ -39,8 +39,8 @@ public class ChartReport return _receiptRepository .ReadReceipts() .Where(x => x.DateOfReceipt.Date == dateTime.Date) - .GroupBy(x => x.ProductId, (key, group) => new { ID = key, Count = group.Sum(y => y.NumberOfPairsReceived) }) - .Select(x => (x.ID.ToString(), (double)x.Count)) + .GroupBy(x => x.ProductName, (key, group) => new { Name = key, Count = group.Sum(y => y.NumberOfPairsReceived) }) + .Select(x => (x.Name, (double)x.Count)) .ToList(); } } diff --git a/ShoeStore/Reports/TableReport.cs b/ShoeStore/Reports/TableReport.cs index d5ed765..0c3ccb3 100644 --- a/ShoeStore/Reports/TableReport.cs +++ b/ShoeStore/Reports/TableReport.cs @@ -29,7 +29,7 @@ internal class TableReport try { new ExcelBuilder(filePath) .AddHeader("Сводка по движению товара", 0, 4) - .AddParagraph("за период", 0) + .AddParagraph($"За период c {startDate:dd.MM.yyyy} по {endDate: dd.MM.yyyy}", 0) .AddTable([10, 10, 15, 15], GetData(startDate, endDate)) .Build(); return true; @@ -46,18 +46,18 @@ internal class TableReport var data = _saleRepository .ReadSales() .Where(x => x.DateOfSale >= startDate && x.DateOfSale <= endDate && x.Product.Any(y => y.SaleId == x.Id)) - .Select(x => new { x.Product.First(y => y.SaleId == x.Id).ProductId, Date = x.DateOfSale, CountIn = (int?)null, CountOut = (int?)x.Product.FirstOrDefault(y => y.SaleId == x.Id)?.SalesNumber }) + .Select(x => new { x.Product.First(y => y.SaleId == x.Id).ProductName, Date = x.DateOfSale, CountIn = (int?)null, CountOut = (int?)x.Product.FirstOrDefault(y => y.SaleId == x.Id)?.SalesNumber }) .Union( _receiptRepository .ReadReceipts() .Where(x => x.DateOfReceipt >= startDate && x.DateOfReceipt <= endDate) - .Select(x => new { x.ProductId, Date = x.DateOfReceipt, CountIn = (int?)x.NumberOfPairsReceived, CountOut = (int?)null })) + .Select(x => new { x.ProductName, Date = x.DateOfReceipt, CountIn = (int?)x.NumberOfPairsReceived, CountOut = (int?)null })) .OrderBy(x => x.Date); return new List() { item } .Union( data - .Select(x => new string[] { x.ProductId.ToString(), x.Date.ToString(), x.CountIn?.ToString() ?? string.Empty, x.CountOut?.ToString() ?? string.Empty })) + .Select(x => new string[] { x.ProductName, x.Date.ToString(), x.CountIn?.ToString() ?? string.Empty, x.CountOut?.ToString() ?? string.Empty })) .Union([["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString(), data.Sum(x => x.CountOut ?? 0).ToString()]]) .ToList(); diff --git a/ShoeStore/Repositories/Implementations/QueryBuilder.cs b/ShoeStore/Repositories/Implementations/QueryBuilder.cs new file mode 100644 index 0000000..47c0b21 --- /dev/null +++ b/ShoeStore/Repositories/Implementations/QueryBuilder.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShoeStore.Repositories.Implementations; + +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}"; + } +} diff --git a/ShoeStore/Repositories/Implementations/ReceiptRepository.cs b/ShoeStore/Repositories/Implementations/ReceiptRepository.cs index 8ab6f4a..b134780 100644 --- a/ShoeStore/Repositories/Implementations/ReceiptRepository.cs +++ b/ShoeStore/Repositories/Implementations/ReceiptRepository.cs @@ -50,7 +50,9 @@ public class ReceiptRepository : IReceiptRepository try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM Receipt"; + var querySelect = @"SELECT r.*, p.NameOfShoes as ProductName + FROM Receipt r + INNER JOIN Product p ON p.Id = r.ProductId"; var receipt = connection.Query(querySelect); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(receipt)); diff --git a/ShoeStore/Repositories/Implementations/SaleRepository.cs b/ShoeStore/Repositories/Implementations/SaleRepository.cs index 2b1b931..7ca4158 100644 --- a/ShoeStore/Repositories/Implementations/SaleRepository.cs +++ b/ShoeStore/Repositories/Implementations/SaleRepository.cs @@ -84,17 +84,44 @@ public class SaleRepository : ISaleRepository _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + if (dateForm.HasValue) + { + builder.AddCondition("s.DateOfSale >= @dateForm"); + } + if (dateTo.HasValue) + { + builder.AddCondition("s.DateOfSale <= @dateTo"); + } + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = @"SELECT s.*, ps.ProductId, ps.SalesNumber + var querySelect = @$"SELECT s.*, ps.ProductId, ps.SaleId, ps.SalesNumber, p.NameOfShoes as ProductName FROM Sale s - INNER JOIN ProductSale ps ON ps.SaleId = s.Id"; - var sale = connection.Query(querySelect); - _logger.LogDebug("Полученные объекты: {json}", - JsonConvert.SerializeObject(sale)); - return sale.GroupBy(x => x.Id, y => y, - (key, value) => Sale.CreateOperation(value.First(), - value.Select(z => ProductSale.CreateOperation( z.ProductId, z.Id, z.SalesNumber)))).ToList(); + INNER JOIN ProductSale ps ON ps.SaleId = s.Id + INNER JOIN Product p ON p.Id = ps.ProductId + {builder.Build()}"; + var productDict = new Dictionary>(); + var sales = connection.Query(querySelect, + (sale, ProductSales) => + { + if (!productDict.TryGetValue(sale.Id, out var pr)) + { + pr = []; + productDict.Add(sale.Id, pr); + } + pr.Add(ProductSales); + return sale; + }, splitOn: "ProductId", param: new { dateForm, dateTo}); + + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(sales)); + + return productDict.Select(x => + { + var pr = sales.First(y => y.Id == x.Key); + pr.SetProductSales(x.Value); + return pr; + }).ToArray(); } catch (Exception ex) {