правки

This commit is contained in:
vettaql 2024-12-22 12:53:35 +04:00
parent 132a1e3134
commit dbd151ff41
4 changed files with 234 additions and 181 deletions

View File

@ -1,77 +1,66 @@
using Atelier.Reports; using Atelier.Reports;
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Unity; using Unity;
namespace Atelier.Forms; namespace Atelier.Forms
public partial class FormOrderReports : Form
{ {
private readonly IUnityContainer _container; public partial class FormOrderReports : Form
public FormOrderReports(IUnityContainer container, IOrderRepository orderRepository, IModelRepository modelRepository)
{ {
InitializeComponent(); private readonly IUnityContainer _container;
_container = container ??
throw new ArgumentNullException(nameof(container)); public FormOrderReports(IUnityContainer container, IOrderRepository orderRepository, IModelRepository modelRepository)
comboBoxModel.DataSource = modelRepository.ReadModels();
comboBoxModel.DisplayMember = "ModelType";
comboBoxModel.ValueMember = "Id";
}
private void ButtonFile_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{ {
Filter = "Excel Files | *.xlsx" InitializeComponent();
}; _container = container ?? throw new ArgumentNullException(nameof(container));
if (sfd.ShowDialog() != DialogResult.OK) comboBoxModel.DataSource = modelRepository.ReadModels();
{ comboBoxModel.DisplayMember = "ModelType";
return; comboBoxModel.ValueMember = "Id";
} }
textBoxFile.Text = sfd.FileName;
} private void ButtonFile_Click(object sender, EventArgs e)
private void ButtonBuild_Click(object sender, EventArgs e)
{
try
{ {
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<TableReport>().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("Дата начала должна быть раньше даты окончания"); MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if
(_container.Resolve<TableReport>().CreateTable(textBoxFile.Text,
(int)comboBoxModel.SelectedValue!, dateTimePickerStart.Value, dateTimePickerEnd.Value))
{
MessageBox.Show("Документ сформирован",
"Формирование документа",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах",
"Формирование документа",
MessageBoxButtons.OK, MessageBoxIcon.Information);
} }
} }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при создании очета",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} }
} }

View File

@ -3,104 +3,118 @@ using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Atelier.Reports; namespace Atelier.Reports
internal class DocReport
{ {
private readonly IClientRepository _clientRepository; internal class DocReport
private readonly IFabricRepository _fabricRepository;
private readonly IModelRepository _modelRepository;
private readonly ILogger<DocReport> _logger;
public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger<DocReport> logger)
{ {
_clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository)); private readonly IClientRepository _clientRepository;
_fabricRepository = fabricRepository ?? throw new ArgumentNullException(nameof(fabricRepository)); private readonly IFabricRepository _fabricRepository;
_modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository)); private readonly IModelRepository _modelRepository;
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); private readonly ILogger<DocReport> _logger;
}
public bool CreateDoc(string filePath, bool includeClients, bool includeFabrics, bool includeModels) public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger<DocReport> logger)
{
try
{ {
var builder = new WordBuilder(filePath) _clientRepository = clientRepository ?? throw new ArgumentNullException(nameof(clientRepository));
.AddHeader("Документ со справочниками"); _fabricRepository = fabricRepository ?? throw new ArgumentNullException(nameof(fabricRepository));
if (includeClients) _modelRepository = modelRepository ?? throw new ArgumentNullException(nameof(modelRepository));
{ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
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;
} }
catch (Exception ex)
public bool CreateDoc(string filePath, bool includeClients, bool includeFabrics, bool includeModels)
{ {
_logger.LogError(ex, "Ошибка при формировании документа"); try
return false;
}
}
private List<string[]> GetClients()
{
return [
["Имя", "Фамилия", "Контактные данные"],
.. _clientRepository
.ReadClients()
.Select(x => new string[] { x.FirstName, x.LastName, x.ContactInformation }),
];
}
private List<string[]> GetFabrics()
{
return [
["Тип ткани", "Цвет", "Метраж"],
.. _fabricRepository
.ReadFabrics()
.Select(x => new string[] { x.FabricType.ToString(), x.Color.ToString(), x.Metrage.ToString() }),
];
}
private List<string[]> GetModels()
{
// Заголовок таблицы
var result = new List<string[]>
{
new[] { "Тип модели", "Цена", "Ткань", "Количество" }
};
// Добавляем строки с данными
var models = _modelRepository.ReadModels().ToList();
_logger.LogDebug("Models: {Models}", JsonConvert.SerializeObject(models));
result.AddRange(
models.Select(x =>
{ {
// Формируем строки для каждой модели var builder = new WordBuilder(filePath)
var fabricTypes = string.Join(", ", x.FabricModel .AddHeader("Документ со справочниками");
.Select(y => _fabricRepository.ReadFabricById(y.FabricId)?.FabricType) if (includeClients)
.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(), builder.AddParagraph("Клиенты")
x.Price.ToString(), .AddTable(new[] { 2400, 2400, 2400 }, GetClients());
fabricTypes, }
fabricCounts 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<string[]> GetClients()
{
var clients = _clientRepository.ReadClients()
.Select(x => new string[] { x.FirstName, x.LastName, x.ContactInformation })
.ToList();
var result = new List<string[]>
{
new[] { "Имя", "Фамилия", "Контактные данные" }
};
result.AddRange(clients);
return result;
}
private List<string[]> GetFabrics()
{
var fabrics = _fabricRepository.ReadFabrics()
.Select(x => new string[] { x.FabricType.ToString(), x.Color.ToString(), x.Metrage.ToString() })
.ToList();
var result = new List<string[]>
{
new[] { "Тип ткани", "Цвет", "Метраж" }
};
result.AddRange(fabrics);
return result;
}
private List<string[]> GetModels()
{
// Заголовок таблицы
var result = new List<string[]>
{
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;
}
} }
} }

View File

@ -9,14 +9,14 @@ namespace Atelier.Reports
internal class TableReport internal class TableReport
{ {
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;
private readonly IStorageRepository _storageRepository; private readonly IModelRepository _modelRepository;
private readonly ILogger<TableReport> _logger; private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Клиент", "Дата", "Модель", "Количество"]; internal static readonly string[] item = ["Клиент", "Дата", "Модель", "Статус", "Новые заказы", "Заказы в работе", "Выполненные заказы"];
public TableReport(IOrderRepository orderRepository, IStorageRepository storageRepository, ILogger<TableReport> logger) public TableReport(IOrderRepository orderRepository, IModelRepository modelRepository, ILogger<TableReport> logger)
{ {
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); _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)); _logger = logger ?? throw new ArgumentNullException(nameof(logger));
} }
@ -27,7 +27,7 @@ namespace Atelier.Reports
new ExcelBuilder(filePath) new ExcelBuilder(filePath)
.AddHeader("Сводка по заказам", 0, 4) .AddHeader("Сводка по заказам", 0, 4)
.AddParagraph("за период", 0) .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(); .Build();
return true; return true;
} }
@ -40,27 +40,34 @@ namespace Atelier.Reports
private List<string[]> GetData(int modelId, DateTime startDate, DateTime endDate) private List<string[]> GetData(int modelId, DateTime startDate, DateTime endDate)
{ {
var orderData = _orderRepository var orders = _orderRepository
.ReadOrders() .ReadOrders(modelId, startDate, endDate)
.Where(x => x.Date >= startDate && x.Date <= endDate && x.ModelOrder.Any(y => y.ModelId == modelId)) .ToList();
.SelectMany(x => x.ModelOrder, (order, modelOrder) => new { order.ClientId, order.Date, modelOrder.ModelId, modelOrder.Count })
.OrderBy(x => x.Date);
var storageData = _storageRepository _logger.LogDebug("Orders: {Orders}", JsonConvert.SerializeObject(orders));
.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));
var result = new List<string[]>() { item }; var result = new List<string[]>() { item };
result.AddRange(orderData.Select(x => new string[] { x.ClientId.ToString(), x.Date.ToString("yyyy-MM-dd"), x.ModelId.ToString(), x.Count.ToString() })); var newOrdersCount = 0;
result.AddRange(storageData.Select(x => new string[] { "", x.DateStorage.ToString("yyyy-MM-dd"), x.FabricId.ToString(), x.StockMetrage.ToString() })); 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; return result;
} }

View File

@ -75,26 +75,69 @@ WHERE Id=@id";
} }
} }
public IEnumerable<Order> ReadOrders(int? id = null, DateTime?dateForm = null, DateTime? dateTo = null,
Status? status = null, int? clientId = null)
public IEnumerable<Order> ReadOrders(int? modelId = null, DateTime? startDate = null, DateTime? endDate = null, Status? status = null, int? clientId = null)
{ {
_logger.LogInformation("Получение всех объектов"); _logger.LogInformation("Получение всех объектов");
try try
{ {
using var connection = new using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
NpgsqlConnection(_connectionString.ConnectionString); var querySelect = @"
var querySelect = @"SELECT * FROM Orders"; SELECT o.Id, o.Date, o.Status, o.ClientId, m.ModelId, m.Count, m.OrderId
var orders = FROM Orders o
connection.Query<Order>(querySelect); LEFT JOIN ModelOrder m ON o.Id = m.OrderId";
_logger.LogDebug("Полученные объекты: {json}",
JsonConvert.SerializeObject(orders)); 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<Order, ModelOrder, Order>(
querySelect,
(order, modelOrder) =>
{
var newOrder = Order.CreateOperation(order.Id, order.Date, order.Status, order.ClientId, new List<ModelOrder>());
if (modelOrder != null)
{
var modelOrders = new List<ModelOrder>(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; return orders;
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка при чтении объектов"); _logger.LogError(ex, "Ошибка при чтении данных о заказах");
throw; throw;
} }
} }
} }