From 033ba7ab4cd7a719d689838a95c017bbdce818fb Mon Sep 17 00:00:00 2001 From: Aleksey-Skvortsov Date: Mon, 23 Dec 2024 19:31:37 +0400 Subject: [PATCH] work lab 4 --- Project/Entities/Manufacturer.cs | 6 ++- Project/Entities/Product.cs | 18 ++++++++ Project/Entities/Sale.cs | 21 +++++++-- Project/Entities/SaleProduct.cs | 1 + Project/Entities/TempSaleProduct.cs | 15 ------- Project/Entities/Work.cs | 13 ++++++ Project/Entities/WorkType.cs | 11 ++++- Project/Forms/FormManufacturers.cs | 7 ++- Project/Forms/FormProducts.cs | 7 ++- Project/Forms/FormSales.cs | 7 ++- Project/Forms/FormWorkTypes.cs | 7 ++- Project/Forms/FormWorks.cs | 7 ++- Project/Reports/ChartReport.cs | 9 ++-- Project/Reports/TableReport.cs | 6 +-- Project/Repositories/ISaleRepository.cs | 2 +- Project/Repositories/IWorkRepository.cs | 2 +- .../Implementations/ProductRepository.cs | 3 +- .../Implementations/QueryBuilder.cs | 33 ++++++++++++++ .../Implementations/SaleRepository.cs | 43 ++++++++++++++++--- .../Implementations/WorkRepository.cs | 18 ++++++-- 20 files changed, 185 insertions(+), 51 deletions(-) delete mode 100644 Project/Entities/TempSaleProduct.cs create mode 100644 Project/Repositories/Implementations/QueryBuilder.cs diff --git a/Project/Entities/Manufacturer.cs b/Project/Entities/Manufacturer.cs index 9582122..3e2b0ca 100644 --- a/Project/Entities/Manufacturer.cs +++ b/Project/Entities/Manufacturer.cs @@ -1,8 +1,12 @@ -namespace Project.Entities; +using System.ComponentModel; + +namespace Project.Entities; public class Manufacturer { public int Id { get; private set; } + + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; public static Manufacturer CreateOperation(int id, string name) { diff --git a/Project/Entities/Product.cs b/Project/Entities/Product.cs index e0231e0..9191d99 100644 --- a/Project/Entities/Product.cs +++ b/Project/Entities/Product.cs @@ -1,16 +1,34 @@ using Project.Entities.Enums; +using System.ComponentModel; namespace Project.Entities; public class Product { public int Id { get; private set; } + + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; + + [DisplayName("Описание")] public string Description { get; private set; } = string.Empty; + + [DisplayName("Цена продажи")] public float Price { get; private set; } + + [DisplayName("Цена закупки")] public float Cost { get; private set; } + + [Browsable(false)] public int ManufacturerId { get; private set; } + + [DisplayName("Производитель")] + public string ManufacturerName { get; private set; } = string.Empty; + + [DisplayName("Категория")] public CategoryType Category { get; private set; } + + [DisplayName("Аттрибуты")] public ProductAttributes Attributes { get; private set; } public static Product CreteOperation(int id, string name, string description, float price, float cost, int manufacturerId, CategoryType category, ProductAttributes attributes) { diff --git a/Project/Entities/Sale.cs b/Project/Entities/Sale.cs index 39e2b9e..cc368d8 100644 --- a/Project/Entities/Sale.cs +++ b/Project/Entities/Sale.cs @@ -1,16 +1,31 @@ -namespace Project.Entities; +using System.ComponentModel; + +namespace Project.Entities; public class Sale { public int Id { get; private set; } + + [DisplayName("Дата")] public DateTime Date { get; private set; } + + [DisplayName("Продажи")] + public string Sales => SaleProducts != null ? + string.Join(", ", SaleProducts.Select(x => $"{x.ProductName} {x.Quantity}")) : + string.Empty; + + [Browsable(false)] public IEnumerable SaleProducts { get; private set; } = []; public static Sale CreteOperation(int id, DateTime date, IEnumerable saleProducts) { return new Sale { Id = id, Date = date, SaleProducts = saleProducts }; } - public static Sale CreteOperation(TempSaleProduct tempSaleProduct, IEnumerable saleProducts) + + public void SetSaleProducts(IEnumerable saleProducts) { - return new Sale { Id = tempSaleProduct.Id, Date = tempSaleProduct.Date, SaleProducts = saleProducts }; + if (saleProducts != null && saleProducts.Any()) + { + SaleProducts = saleProducts; + } } } diff --git a/Project/Entities/SaleProduct.cs b/Project/Entities/SaleProduct.cs index 496c3a1..f9c20e8 100644 --- a/Project/Entities/SaleProduct.cs +++ b/Project/Entities/SaleProduct.cs @@ -4,6 +4,7 @@ public class SaleProduct { public int Id { get; private set; } public int ProductId { get; private set;} + public string ProductName { get; private set;} = string.Empty; public int Quantity { get; private set; } public static SaleProduct CreateOperation(int id, int productId, int quantity) { diff --git a/Project/Entities/TempSaleProduct.cs b/Project/Entities/TempSaleProduct.cs deleted file mode 100644 index 07ac187..0000000 --- a/Project/Entities/TempSaleProduct.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Project.Entities; - -public class TempSaleProduct -{ - public int Id { get; private set; } - public DateTime Date { get; private set; } - public int ProductId { get; private set; } - public int Quantity { get; private set; } -} diff --git a/Project/Entities/Work.cs b/Project/Entities/Work.cs index 004a30c..160d651 100644 --- a/Project/Entities/Work.cs +++ b/Project/Entities/Work.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,20 @@ namespace Project.Entities; public class Work { public int Id { get; private set; } + + [Browsable(false)] public int ProductId { get; private set; } + + [Browsable(false)] public int WorkTypeID { get; private set; } + + [DisplayName("Продукт")] + public string ProductName { get; private set; } = string.Empty; + + [DisplayName("Тип работы")] + public string WorkTypeName { get; private set; } = string.Empty; + + [DisplayName("Дата")] public DateTime Date { get; private set; } public static Work CreateOperation(int id, int productId, int workTypeID, DateTime date) diff --git a/Project/Entities/WorkType.cs b/Project/Entities/WorkType.cs index aff4751..371ea18 100644 --- a/Project/Entities/WorkType.cs +++ b/Project/Entities/WorkType.cs @@ -1,11 +1,20 @@ -namespace Project.Entities; +using System.ComponentModel; + +namespace Project.Entities; public class WorkType { public int Id { get; private set; } + + [DisplayName("Название")] public string Name { get; private set; } = string.Empty; + + [DisplayName("Описание")] public string Description { get; private set; } = string.Empty; + + [DisplayName("Цена")] public float Price { get; private set; } + public static WorkType CreateOperation(int id, string name, string description, float price) { return new WorkType { Id = id, Name = name, Description = description, Price = price }; diff --git a/Project/Forms/FormManufacturers.cs b/Project/Forms/FormManufacturers.cs index 4f55cf4..50e8198 100644 --- a/Project/Forms/FormManufacturers.cs +++ b/Project/Forms/FormManufacturers.cs @@ -70,8 +70,11 @@ public partial class FormManufacturers : Form } } - private void LoadList() => dataGridViewGroups.DataSource = _manufacturerRepository.GetAllManufacturers(); - + private void LoadList() + { + dataGridViewGroups.DataSource = _manufacturerRepository.GetAllManufacturers(); + dataGridViewGroups.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/Project/Forms/FormProducts.cs b/Project/Forms/FormProducts.cs index b1137ac..1c4b1fb 100644 --- a/Project/Forms/FormProducts.cs +++ b/Project/Forms/FormProducts.cs @@ -70,8 +70,11 @@ public partial class FormProducts : Form } } - private void LoadList() => dataGridViewGroups.DataSource = _productRepository.GetAllProducts(); - + private void LoadList() + { + dataGridViewGroups.DataSource = _productRepository.GetAllProducts(); + dataGridViewGroups.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/Project/Forms/FormSales.cs b/Project/Forms/FormSales.cs index ed1227f..73a0ee6 100644 --- a/Project/Forms/FormSales.cs +++ b/Project/Forms/FormSales.cs @@ -51,8 +51,11 @@ public partial class FormSales : Form } } - private void LoadList() => dataGridViewGroups.DataSource = _saleRepository.GetAllSales(); - + private void LoadList() + { + dataGridViewGroups.DataSource = _saleRepository.GetAllSales(); + dataGridViewGroups.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/Project/Forms/FormWorkTypes.cs b/Project/Forms/FormWorkTypes.cs index 8b6795c..0ea5a35 100644 --- a/Project/Forms/FormWorkTypes.cs +++ b/Project/Forms/FormWorkTypes.cs @@ -70,8 +70,11 @@ public partial class FormWorkTypes : Form } } - private void LoadList() => dataGridViewGroups.DataSource = _workTypeRepository.GetAllWorkTypes(); - + private void LoadList() + { + dataGridViewGroups.DataSource = _workTypeRepository.GetAllWorkTypes(); + dataGridViewGroups.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/Project/Forms/FormWorks.cs b/Project/Forms/FormWorks.cs index 13955ad..020cfa6 100644 --- a/Project/Forms/FormWorks.cs +++ b/Project/Forms/FormWorks.cs @@ -51,8 +51,11 @@ public partial class FormWorks : Form } } - private void LoadList() => dataGridViewGroups.DataSource = _workRepository.GetAllWorks(); - + private void LoadList() + { + dataGridViewGroups.DataSource = _workRepository.GetAllWorks(); + dataGridViewGroups.Columns["Id"].Visible = false; + } private bool TryGetIdentifierFromSelectedRow(out int id) { id = 0; diff --git a/Project/Reports/ChartReport.cs b/Project/Reports/ChartReport.cs index 01619af..7f8b4f0 100644 --- a/Project/Reports/ChartReport.cs +++ b/Project/Reports/ChartReport.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Logging; using Project.Repositories; +using System; namespace Project.Reports; @@ -22,7 +23,7 @@ internal class ChartReport { new PdfBuilder(filePath) .AddHeader("Количество продаж по товарам") - .AddPieChart("Продажи товаров", GetData(date)) + .AddPieChart($"Продажи товаров на {date:dd.MM.yyyy}", GetData(date)) .Build(); return true; } @@ -33,13 +34,11 @@ internal class ChartReport } } - private List<(string Caption, double Value)> GetData(DateTime date) + private List<(string Caption, double Value)> GetData(DateTime dateTime) { var productNames = _productRepository.GetAllProducts() .ToDictionary(p => p.Id, p => p.Name); - - var sales = _saleRepository.GetAllSales() - .Where(s => s.Date.Date == date.Date) + var sales = _saleRepository.GetAllSales(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1)) .SelectMany(s => s.SaleProducts) .GroupBy(sp => sp.ProductId) .Select(g => new diff --git a/Project/Reports/TableReport.cs b/Project/Reports/TableReport.cs index 6478d5d..00fac88 100644 --- a/Project/Reports/TableReport.cs +++ b/Project/Reports/TableReport.cs @@ -44,8 +44,7 @@ public class TableReport var workTypes = _workTypeRepository.GetAllWorkTypes() .ToDictionary(wt => wt.Id, wt => new { wt.Name, wt.Description }); - var sales = _saleRepository.GetAllSales() - .Where(s => s.Date >= startDate && s.Date <= endDate) + var sales = _saleRepository.GetAllSales(startDate, endDate) .Select(s => new { s.Date, @@ -55,8 +54,7 @@ public class TableReport Comment = string.Empty }); - var works = _workRepository.GetAllWorks() - .Where(w => w.Date >= startDate && w.Date <= endDate) + var works = _workRepository.GetAllWorks(startDate, endDate) .Select(w => new { w.Date, diff --git a/Project/Repositories/ISaleRepository.cs b/Project/Repositories/ISaleRepository.cs index 1744ce0..6f7e79e 100644 --- a/Project/Repositories/ISaleRepository.cs +++ b/Project/Repositories/ISaleRepository.cs @@ -4,7 +4,7 @@ namespace Project.Repositories; public interface ISaleRepository { - IEnumerable GetAllSales(); + IEnumerable GetAllSales(DateTime? dateFrom = null, DateTime? dateTo = null); void AddSale(Sale sale); void DeleteSale(int id); } diff --git a/Project/Repositories/IWorkRepository.cs b/Project/Repositories/IWorkRepository.cs index 599f09e..c5e3b97 100644 --- a/Project/Repositories/IWorkRepository.cs +++ b/Project/Repositories/IWorkRepository.cs @@ -4,7 +4,7 @@ namespace Project.Repositories; public interface IWorkRepository { - IEnumerable GetAllWorks(); + IEnumerable GetAllWorks(DateTime? dateFrom = null, DateTime? dateTo = null); void AddWork(Work work); void DeleteWork(int id); } \ No newline at end of file diff --git a/Project/Repositories/Implementations/ProductRepository.cs b/Project/Repositories/Implementations/ProductRepository.cs index 185f686..b9ff0b5 100644 --- a/Project/Repositories/Implementations/ProductRepository.cs +++ b/Project/Repositories/Implementations/ProductRepository.cs @@ -63,7 +63,8 @@ public class ProductRepository : IProductRepository try { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM Product"; + var querySelect = @"SELECT pr.*, ma.Name as ManufacturerName FROM Product pr + LEFT JOIN Manufacturer ma on ma.Id = pr.ManufacturerId"; var products = connection.Query(querySelect); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(products)); diff --git a/Project/Repositories/Implementations/QueryBuilder.cs b/Project/Repositories/Implementations/QueryBuilder.cs new file mode 100644 index 0000000..6c9826e --- /dev/null +++ b/Project/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 Project.Repositories.Implementations; + +internal 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}"; + } +} \ No newline at end of file diff --git a/Project/Repositories/Implementations/SaleRepository.cs b/Project/Repositories/Implementations/SaleRepository.cs index 653b1dc..75e8ba7 100644 --- a/Project/Repositories/Implementations/SaleRepository.cs +++ b/Project/Repositories/Implementations/SaleRepository.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Npgsql; using Project.Entities; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Project.Repositories.Implementations; @@ -83,18 +84,48 @@ public class SaleRepository : ISaleRepository } } - public IEnumerable GetAllSales() + public IEnumerable GetAllSales(DateTime? dateFrom = null, DateTime? dateTo = null) { _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + if (dateFrom.HasValue) + { + builder.AddCondition("sa.Date >= @dateFrom"); + } + if (dateTo.HasValue) + { + builder.AddCondition("sa.Date <= @dateTo"); + } using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = @"SELECT sa.*, sap.ProductId, sap.Quantity FROM Sale sa - INNER JOIN SaleProduct sap on sap.SaleId = sa.Id"; - var sales = connection.Query(querySelect); + var querySelect = $@"SELECT sa.*, sap.ProductId, sap.Quantity, pr.Name as ProductName FROM Sale sa + INNER JOIN SaleProduct sap on sap.SaleId = sa.Id + LEFT JOIN Product pr on pr.Id = sap.ProductId + {builder.Build()}"; + var salesDict = new Dictionary>(); + + var saleProducts = connection.Query(querySelect, + (sale, saleProduct) => + { + if (!salesDict.TryGetValue(sale.Id, out var ccf)) + { + ccf = []; + salesDict.Add(sale.Id, ccf); + } + + ccf.Add(saleProduct); + return sale; + }, splitOn: "ProductId", param: new {dateFrom, dateTo}); _logger.LogDebug("Полученные объекты: {json}", - JsonConvert.SerializeObject(sales)); - return sales.GroupBy(x => x.Id, y => y, (key, value) => Sale.CreteOperation(value.First(), value.Select(z => SaleProduct.CreateOperation(0, z.ProductId, z.Quantity)))).ToList(); + JsonConvert.SerializeObject(saleProducts)); + + return salesDict.Select(x => + { + var cf = saleProducts.First(y => y.Id == x.Key); + cf.SetSaleProducts(x.Value); + return cf; + }).ToArray(); } catch (Exception ex) { diff --git a/Project/Repositories/Implementations/WorkRepository.cs b/Project/Repositories/Implementations/WorkRepository.cs index 7845fa9..a8c0532 100644 --- a/Project/Repositories/Implementations/WorkRepository.cs +++ b/Project/Repositories/Implementations/WorkRepository.cs @@ -56,14 +56,26 @@ public class WorkRepository : IWorkRepository } } - public IEnumerable GetAllWorks() + public IEnumerable GetAllWorks(DateTime? dateFrom = null, DateTime? dateTo = null) { _logger.LogInformation("Получение всех объектов"); try { + var builder = new QueryBuilder(); + if (dateFrom.HasValue) + { + builder.AddCondition("wo.Date >= @dateFrom"); + } + if (dateTo.HasValue) + { + builder.AddCondition("wo.Date <= @dateTo"); + } using var connection = new NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = "SELECT * FROM Work"; - var works = connection.Query(querySelect); + var querySelect = $@"SELECT wo.*, wot.Name as WorkTypeName, pro.Name as ProductName FROM Work wo + LEFT JOIN WorkType wot on wot.Id = wo.WorkTypeID + LEFT JOIN Product pro on pro.Id = wo.ProductId + {builder.Build()}"; + var works = connection.Query(querySelect, new { dateFrom, dateTo }); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(works)); return works; -- 2.25.1