правки

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 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("Отсутствует имя файла для отчета");
}
if (comboBoxModel.SelectedIndex < 0)
Filter = "Excel Files | *.xlsx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
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);
return;
}
textBoxFile.Text = sfd.FileName;
}
catch (Exception ex)
private void ButtonBuild_Click(object sender, EventArgs e)
{
MessageBox.Show(ex.Message, "Ошибка при создании очета",
MessageBoxButtons.OK, MessageBoxIcon.Error);
try
{
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);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -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<DocReport> _logger;
public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger<DocReport> 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<DocReport> _logger;
public DocReport(IClientRepository clientRepository, IFabricRepository fabricRepository, IModelRepository modelRepository, ILogger<DocReport> 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<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 =>
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<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
{
private readonly IOrderRepository _orderRepository;
private readonly IStorageRepository _storageRepository;
private readonly IModelRepository _modelRepository;
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));
_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<string[]> 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<string[]>() { 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;
}

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("Получение всех объектов");
try
{
using var connection = new
NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM Orders";
var orders =
connection.Query<Order>(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<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;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
_logger.LogError(ex, "Ошибка при чтении данных о заказах");
throw;
}
}
}