From dbd151ff414b2f81f97ea0a381297dab80dce491 Mon Sep 17 00:00:00 2001 From: vettaql Date: Sun, 22 Dec 2024 12:53:35 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Atelier/Atelier/Forms/FormOrderReports.cs | 105 +++++----- Atelier/Atelier/Reports/DocReport.cs | 196 ++++++++++-------- Atelier/Atelier/Reports/TableReport.cs | 49 +++-- .../Implementations/OrderRepository.cs | 65 +++++- 4 files changed, 234 insertions(+), 181 deletions(-) diff --git a/Atelier/Atelier/Forms/FormOrderReports.cs b/Atelier/Atelier/Forms/FormOrderReports.cs index 1fc2727..016f906 100644 --- a/Atelier/Atelier/Forms/FormOrderReports.cs +++ b/Atelier/Atelier/Forms/FormOrderReports.cs @@ -1,77 +1,66 @@ using Atelier.Reports; using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; using Unity; -namespace Atelier.Forms; - -public partial class FormOrderReports : Form +namespace Atelier.Forms { - private readonly IUnityContainer _container; - public FormOrderReports(IUnityContainer container, IOrderRepository orderRepository, IModelRepository modelRepository) + public partial class FormOrderReports : Form { - InitializeComponent(); - _container = container ?? - throw new ArgumentNullException(nameof(container)); - comboBoxModel.DataSource = modelRepository.ReadModels(); - comboBoxModel.DisplayMember = "ModelType"; - comboBoxModel.ValueMember = "Id"; - } - private void ButtonFile_Click(object sender, EventArgs e) - { - var sfd = new SaveFileDialog() + private readonly IUnityContainer _container; + + public FormOrderReports(IUnityContainer container, IOrderRepository orderRepository, IModelRepository modelRepository) { - Filter = "Excel Files | *.xlsx" - }; - if (sfd.ShowDialog() != DialogResult.OK) - { - return; + InitializeComponent(); + _container = container ?? throw new ArgumentNullException(nameof(container)); + comboBoxModel.DataSource = modelRepository.ReadModels(); + comboBoxModel.DisplayMember = "ModelType"; + comboBoxModel.ValueMember = "Id"; } - textBoxFile.Text = sfd.FileName; - } - private void ButtonBuild_Click(object sender, EventArgs e) - { - try + + private void ButtonFile_Click(object sender, EventArgs e) { - if (string.IsNullOrWhiteSpace(textBoxFile.Text)) + var sfd = new SaveFileDialog() { - throw new Exception("Отсутствует имя файла для отчета"); + Filter = "Excel Files | *.xlsx" + }; + if (sfd.ShowDialog() != DialogResult.OK) + { + return; } - if (comboBoxModel.SelectedIndex < 0) + textBoxFile.Text = sfd.FileName; + } + + private void ButtonBuild_Click(object sender, EventArgs e) + { + try { - throw new Exception("Не выбран клиент"); + if (string.IsNullOrWhiteSpace(textBoxFile.Text)) + { + throw new Exception("Отсутствует имя файла для отчета"); + } + if (comboBoxModel.SelectedIndex < 0) + { + throw new Exception("Не выбрана модель"); + } + if (dateTimePickerEnd.Value <= dateTimePickerStart.Value) + { + throw new Exception("Дата начала должна быть раньше даты окончания"); + } + if (_container.Resolve().CreateTable(textBoxFile.Text, (int)comboBoxModel.SelectedValue!, dateTimePickerStart.Value, dateTimePickerEnd.Value)) + { + MessageBox.Show("Документ сформирован", "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + MessageBox.Show("Возникли ошибки при формировании документа. Подробности в логах", "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } - if (dateTimePickerEnd.Value <= dateTimePickerStart.Value) + catch (Exception ex) { - throw new Exception("Дата начала должна быть раньше даты окончания"); - } - if - (_container.Resolve().CreateTable(textBoxFile.Text, - (int)comboBoxModel.SelectedValue!, dateTimePickerStart.Value, dateTimePickerEnd.Value)) - { - MessageBox.Show("Документ сформирован", - "Формирование документа", - MessageBoxButtons.OK, - MessageBoxIcon.Information); - } - else - { - MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", - "Формирование документа", - MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error); } } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Ошибка при создании очета", - MessageBoxButtons.OK, MessageBoxIcon.Error); - } } -} \ No newline at end of file +} diff --git a/Atelier/Atelier/Reports/DocReport.cs b/Atelier/Atelier/Reports/DocReport.cs index 8068686..e812c90 100644 --- a/Atelier/Atelier/Reports/DocReport.cs +++ b/Atelier/Atelier/Reports/DocReport.cs @@ -3,104 +3,118 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Atelier.Reports; - -internal class DocReport +namespace Atelier.Reports { - private readonly IClientRepository _clientRepository; - private readonly IFabricRepository _fabricRepository; - private readonly IModelRepository _modelRepository; - private readonly ILogger _logger; - public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger logger) + internal class DocReport { - _clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository)); - _fabricRepository = fabricRepository ?? throw new ArgumentNullException(nameof(fabricRepository)); - _modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - public bool CreateDoc(string filePath, bool includeClients, bool includeFabrics, bool includeModels) - { - try + private readonly IClientRepository _clientRepository; + private readonly IFabricRepository _fabricRepository; + private readonly IModelRepository _modelRepository; + private readonly ILogger _logger; + + public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger logger) { - var builder = new WordBuilder(filePath) - .AddHeader("Документ со справочниками"); - if (includeClients) - { - builder.AddParagraph("Клиенты") - .AddTable([2400, 2400, 2400], GetClients()); - } - if (includeFabrics) - { - builder.AddParagraph("Ткани") - .AddTable([2400, 2400, 2400], GetFabrics()); - } - if (includeModels) - { - builder.AddParagraph("Модели") - .AddTable([2400, 2400, 1200, 1200], GetModels()); - } - builder.Build(); - return true; + _clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository)); + _fabricRepository = fabricRepository ?? throw new ArgumentNullException(nameof(fabricRepository)); + _modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - catch (Exception ex) + + public bool CreateDoc(string filePath, bool includeClients, bool includeFabrics, bool includeModels) { - _logger.LogError(ex, "Ошибка при формировании документа"); - return false; - } - } - private List GetClients() - { - return [ - ["Имя", "Фамилия", "Контактные данные"], -.. _clientRepository -.ReadClients() -.Select(x => new string[] { x.FirstName, x.LastName, x.ContactInformation }), -]; - } - private List GetFabrics() - { - return [ - ["Тип ткани", "Цвет", "Метраж"], -.. _fabricRepository -.ReadFabrics() -.Select(x => new string[] { x.FabricType.ToString(), x.Color.ToString(), x.Metrage.ToString() }), -]; - } - private List GetModels() - { - // Заголовок таблицы - var result = new List - { - new[] { "Тип модели", "Цена", "Ткань", "Количество" } - }; - - // Добавляем строки с данными - var models = _modelRepository.ReadModels().ToList(); - _logger.LogDebug("Models: {Models}", JsonConvert.SerializeObject(models)); - - result.AddRange( - models.Select(x => + try { - // Формируем строки для каждой модели - var fabricTypes = string.Join(", ", x.FabricModel - .Select(y => _fabricRepository.ReadFabricById(y.FabricId)?.FabricType) - .Where(type => type != null)); // Filter out null types - var fabricCounts = string.Join(", ", x.FabricModel.Select(y => y.Count.ToString())); - _logger.LogDebug("ModelType: {ModelType}, Price: {Price}, FabricTypes: {FabricTypes}, FabricCounts: {FabricCounts}", x.ModelType, x.Price, fabricTypes, fabricCounts); - - return new[] + var builder = new WordBuilder(filePath) + .AddHeader("Документ со справочниками"); + if (includeClients) { - x.ModelType.ToString(), - x.Price.ToString(), - fabricTypes, - fabricCounts - }; - }) - ); + builder.AddParagraph("Клиенты") + .AddTable(new[] { 2400, 2400, 2400 }, GetClients()); + } + if (includeFabrics) + { + builder.AddParagraph("Ткани") + .AddTable(new[] { 2400, 2400, 2400 }, GetFabrics()); + } + if (includeModels) + { + builder.AddParagraph("Модели") + .AddTable(new[] { 2400, 2400, 1200, 1200 }, GetModels()); + } + builder.Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } - return result; + private List GetClients() + { + var clients = _clientRepository.ReadClients() + .Select(x => new string[] { x.FirstName, x.LastName, x.ContactInformation }) + .ToList(); + + var result = new List + { + new[] { "Имя", "Фамилия", "Контактные данные" } + }; + + result.AddRange(clients); + return result; + } + + private List GetFabrics() + { + var fabrics = _fabricRepository.ReadFabrics() + .Select(x => new string[] { x.FabricType.ToString(), x.Color.ToString(), x.Metrage.ToString() }) + .ToList(); + + var result = new List + { + new[] { "Тип ткани", "Цвет", "Метраж" } + }; + + result.AddRange(fabrics); + return result; + } + + private List GetModels() + { + // Заголовок таблицы + var result = new List + { + new[] { "Тип модели", "Цена", "Ткань", "Количество" } + }; + + // Добавляем строки с данными + var models = _modelRepository.ReadModels().ToList(); + _logger.LogDebug("Models: {Models}", JsonConvert.SerializeObject(models)); + + result.AddRange( + models.Select(x => + { + // Формируем строки для каждой модели + var fabricTypes = string.Join(", ", x.FabricModel + .Select(y => _fabricRepository.ReadFabricById(y.FabricId)?.FabricType) + .Where(type => type != null)); // Filter out null types + var fabricCounts = string.Join(", ", x.FabricModel.Select(y => y.Count.ToString())); + _logger.LogDebug("ModelType: {ModelType}, Price: {Price}, FabricTypes: {FabricTypes}, FabricCounts: {FabricCounts}", x.ModelType, x.Price, fabricTypes, fabricCounts); + + return new[] + { + x.ModelType.ToString(), + x.Price.ToString(), + fabricTypes, + fabricCounts + }; + }) + ); + + return result; + } } -} \ No newline at end of file +} diff --git a/Atelier/Atelier/Reports/TableReport.cs b/Atelier/Atelier/Reports/TableReport.cs index b32519b..6c2653c 100644 --- a/Atelier/Atelier/Reports/TableReport.cs +++ b/Atelier/Atelier/Reports/TableReport.cs @@ -9,14 +9,14 @@ namespace Atelier.Reports internal class TableReport { private readonly IOrderRepository _orderRepository; - private readonly IStorageRepository _storageRepository; + private readonly IModelRepository _modelRepository; private readonly ILogger _logger; - internal static readonly string[] item = ["Клиент", "Дата", "Модель", "Количество"]; + internal static readonly string[] item = ["Клиент", "Дата", "Модель", "Статус", "Новые заказы", "Заказы в работе", "Выполненные заказы"]; - public TableReport(IOrderRepository orderRepository, IStorageRepository storageRepository, ILogger logger) + public TableReport(IOrderRepository orderRepository, IModelRepository modelRepository, ILogger logger) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); - _storageRepository = storageRepository ?? throw new ArgumentNullException(nameof(storageRepository)); + _modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -27,7 +27,7 @@ namespace Atelier.Reports new ExcelBuilder(filePath) .AddHeader("Сводка по заказам", 0, 4) .AddParagraph("за период", 0) - .AddTable(new[] { 15, 15, 20, 15 }, GetData(modelId, startDate, endDate)) + .AddTable(new[] { 15, 15, 15, 15, 15, 15, 15 }, GetData(modelId, startDate, endDate)) .Build(); return true; } @@ -40,27 +40,34 @@ namespace Atelier.Reports private List GetData(int modelId, DateTime startDate, DateTime endDate) { - var orderData = _orderRepository - .ReadOrders() - .Where(x => x.Date >= startDate && x.Date <= endDate && x.ModelOrder.Any(y => y.ModelId == modelId)) - .SelectMany(x => x.ModelOrder, (order, modelOrder) => new { order.ClientId, order.Date, modelOrder.ModelId, modelOrder.Count }) - .OrderBy(x => x.Date); + var orders = _orderRepository + .ReadOrders(modelId, startDate, endDate) + .ToList(); - var storageData = _storageRepository - .ReadStorage() - .Where(x => x.DateStorage >= startDate && x.DateStorage <= endDate) - .Select(x => new { x.FabricId, x.DateStorage, x.StockMetrage }) - .OrderBy(x => x.DateStorage); - - _logger.LogDebug("Order Data: {OrderData}", JsonConvert.SerializeObject(orderData)); - _logger.LogDebug("Storage Data: {StorageData}", JsonConvert.SerializeObject(storageData)); + _logger.LogDebug("Orders: {Orders}", JsonConvert.SerializeObject(orders)); var result = new List() { item }; - result.AddRange(orderData.Select(x => new string[] { x.ClientId.ToString(), x.Date.ToString("yyyy-MM-dd"), x.ModelId.ToString(), x.Count.ToString() })); - result.AddRange(storageData.Select(x => new string[] { "", x.DateStorage.ToString("yyyy-MM-dd"), x.FabricId.ToString(), x.StockMetrage.ToString() })); + var newOrdersCount = 0; + var inProcessOrdersCount = 0; + var doneOrdersCount = 0; - result.Add(new[] { "Всего", "", "", (orderData.Sum(x => x.Count) + storageData.Sum(x => x.StockMetrage)).ToString() }); + foreach (var order in orders) + { + var model = _modelRepository.ReadModelById(modelId); + var modelName = model?.ModelType.ToString() ?? "Неизвестно"; + var newOrder = order.Status == Status.Waiting ? "1" : "0"; + var inProcessOrder = order.Status == Status.InProcess ? "1" : "0"; + var doneOrder = order.Status == Status.Done ? "1" : "0"; + + result.Add(new string[] { order.ClientId.ToString(), order.Date.ToString("yyyy-MM-dd"), modelName, order.Status.ToString(), newOrder, inProcessOrder, doneOrder }); + + if (order.Status == Status.Waiting) newOrdersCount++; + if (order.Status == Status.InProcess) inProcessOrdersCount++; + if (order.Status == Status.Done) doneOrdersCount++; + } + + result.Add(new[] { "Всего", "", "", "", newOrdersCount.ToString(), inProcessOrdersCount.ToString(), doneOrdersCount.ToString() }); return result; } diff --git a/Atelier/Atelier/Repositories/Implementations/OrderRepository.cs b/Atelier/Atelier/Repositories/Implementations/OrderRepository.cs index 1de539e..106517e 100644 --- a/Atelier/Atelier/Repositories/Implementations/OrderRepository.cs +++ b/Atelier/Atelier/Repositories/Implementations/OrderRepository.cs @@ -75,26 +75,69 @@ WHERE Id=@id"; } } - public IEnumerable ReadOrders(int? id = null, DateTime?dateForm = null, DateTime? dateTo = null, - Status? status = null, int? clientId = null) + + + public IEnumerable ReadOrders(int? modelId = null, DateTime? startDate = null, DateTime? endDate = null, Status? status = null, int? clientId = null) { _logger.LogInformation("Получение всех объектов"); try { - using var connection = new - NpgsqlConnection(_connectionString.ConnectionString); - var querySelect = @"SELECT * FROM Orders"; - var orders = - connection.Query(querySelect); - _logger.LogDebug("Полученные объекты: {json}", - JsonConvert.SerializeObject(orders)); + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT o.Id, o.Date, o.Status, o.ClientId, m.ModelId, m.Count, m.OrderId + FROM Orders o + LEFT JOIN ModelOrder m ON o.Id = m.OrderId"; + + var parameters = new DynamicParameters(); + if (modelId.HasValue) + { + querySelect += " WHERE m.ModelId = @ModelId"; + parameters.Add("@ModelId", modelId.Value); + } + if (startDate.HasValue) + { + querySelect += " AND o.Date >= @StartDate"; + parameters.Add("@StartDate", startDate.Value); + } + if (endDate.HasValue) + { + querySelect += " AND o.Date <= @EndDate"; + parameters.Add("@EndDate", endDate.Value); + } + if (status.HasValue) + { + querySelect += " AND o.Status = @Status"; + parameters.Add("@Status", status.Value); + } + if (clientId.HasValue) + { + querySelect += " AND o.ClientId = @ClientId"; + parameters.Add("@ClientId", clientId.Value); + } + + var orders = connection.Query( + querySelect, + (order, modelOrder) => + { + var newOrder = Order.CreateOperation(order.Id, order.Date, order.Status, order.ClientId, new List()); + if (modelOrder != null) + { + var modelOrders = new List(newOrder.ModelOrder); + modelOrders.Add(modelOrder); + newOrder = Order.CreateOperation(order.Id, order.Date, order.Status, order.ClientId, modelOrders); + } + return newOrder; + }, + param: parameters, + splitOn: "OrderId").ToList(); + + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(orders)); return orders; } catch (Exception ex) { - _logger.LogError(ex, "Ошибка при чтении объектов"); + _logger.LogError(ex, "Ошибка при чтении данных о заказах"); throw; } - } }