237 lines
7.3 KiB
C#
237 lines
7.3 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Avalonia;
|
||
using Avalonia.Controls;
|
||
using Avalonia.Interactivity;
|
||
using Avalonia.Markup.Xaml;
|
||
using dmeo040225.Models;
|
||
using dmeo040225.Services;
|
||
using OxyPlot;
|
||
using OxyPlot.Avalonia;
|
||
using OxyPlot.Series;
|
||
using OxyPlot.Axes;
|
||
using PdfSharpCore.Drawing;
|
||
using PdfSharpCore.Pdf;
|
||
using LineSeries = OxyPlot.Series.LineSeries;
|
||
|
||
namespace dmeo040225;
|
||
|
||
public class ServicePerDay
|
||
{
|
||
public DateTime Date { get; set; }
|
||
public int CountServices {get; set; }
|
||
}
|
||
|
||
public class ServiceOrdersPerDay
|
||
{
|
||
public DateTime Date { get; set; }
|
||
public string ServiceName { get; set; }
|
||
public int OrderCount { get; set; }
|
||
}
|
||
|
||
public partial class ReportWindow : Window
|
||
{
|
||
public List<ServicePerDay> ServicesPerDayList { get; set; }
|
||
public List<ServiceOrdersPerDay> ServicesOrdersPerDayList { get; set; }
|
||
public List<ServicePerDay> OrdersPerDayList { get; set; }
|
||
|
||
public ReportWindow()
|
||
{
|
||
InitializeComponent();
|
||
|
||
TimerService.Instance.TimeUpdated += UpdateTimerText;
|
||
TimerService.Instance.TimerExpired += LogoutUser;
|
||
|
||
TimerService.Instance.Start();
|
||
}
|
||
|
||
private void GenerateReport(object? sender, RoutedEventArgs e)
|
||
{
|
||
if (StartPicker.SelectedDate == null || EndPicker.SelectedDate == null)
|
||
{
|
||
Console.WriteLine("Выберите начальную и конечную дату!");
|
||
return;
|
||
}
|
||
|
||
DateTime startDate = StartPicker.SelectedDate.Value.DateTime;
|
||
DateTime endDate = EndPicker.SelectedDate.Value.DateTime;
|
||
|
||
if (startDate > endDate)
|
||
{
|
||
Console.WriteLine("Начальная дата не может быть позже конечной!");
|
||
return;
|
||
}
|
||
|
||
using var context = new DatabaseContext();
|
||
|
||
ServicesPerDayList = GetServicesPerDay(context, startDate, endDate);
|
||
ServicesOrdersPerDayList = GetServiceOrdersPerDay(context, startDate, endDate);
|
||
OrdersPerDayList = GetOrdersPerDay(context, startDate, endDate);
|
||
|
||
CreatePdfWithTableAndGraph();
|
||
|
||
foreach (var service in ServicesOrdersPerDayList)
|
||
{
|
||
Console.WriteLine($"{service.Date.ToShortDateString()} | {service.ServiceName} | {service.OrderCount}");
|
||
}
|
||
}
|
||
|
||
private PlotModel CreateServiceGraph()
|
||
{
|
||
var plotModel = new PlotModel { Title = "График по сервисам" };
|
||
|
||
var series = new LineSeries
|
||
{
|
||
Title = "Количество сервисов",
|
||
MarkerType = MarkerType.Circle,
|
||
MarkerSize = 4,
|
||
Color = OxyColors.SkyBlue
|
||
};
|
||
|
||
foreach (var item in ServicesPerDayList)
|
||
{
|
||
series.Points.Add(new DataPoint(OxyPlot.Axes.DateTimeAxis.ToDouble(item.Date), item.CountServices));
|
||
|
||
}
|
||
|
||
plotModel.Series.Add(series);
|
||
return plotModel;
|
||
}
|
||
|
||
private void CreatePdfWithTableAndGraph()
|
||
{
|
||
// Создаем новый PDF документ
|
||
PdfDocument document = new PdfDocument();
|
||
document.Info.Title = "Отчет";
|
||
|
||
// Создаем страницу
|
||
PdfPage page = document.AddPage();
|
||
|
||
// Создаем XGraphics для рисования
|
||
XGraphics gfx = XGraphics.FromPdfPage(page);
|
||
XFont font = new XFont("Arial", 12, XFontStyle.Regular);
|
||
|
||
// Добавление таблицы в PDF
|
||
int yPos = 40;
|
||
// gfx.DrawString("Список сервисов:", font, XBrushes.Black, new XPoint(40, yPos));
|
||
// yPos += 20;
|
||
//
|
||
// foreach (var service in ServicesPerDayList)
|
||
// {
|
||
// gfx.DrawString($"{service.Date.ToShortDateString()} | {service.CountServices} сервисов", font, XBrushes.Black, new XPoint(40, yPos));
|
||
// yPos += 20;
|
||
// }
|
||
|
||
// Добавление графика в PDF
|
||
var plotModel = CreateServiceGraph();
|
||
var pngStream = new System.IO.MemoryStream();
|
||
var pngExporter = new OxyPlot.ImageSharp.PngExporter(400, 300);
|
||
|
||
try
|
||
{
|
||
pngExporter.Export(plotModel, pngStream);
|
||
pngStream.Seek(0, System.IO.SeekOrigin.Begin); // Убедитесь, что поток начнется с первого байта
|
||
|
||
var image = XImage.FromStream(() => pngStream);
|
||
|
||
gfx.DrawImage(image, 40, yPos);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"Ошибка при экспортировании изображения: {ex.Message}");
|
||
}
|
||
|
||
// Сохраняем PDF
|
||
string filename = "report.pdf";
|
||
document.Save(filename);
|
||
Console.WriteLine($"PDF сохранен в {filename}");
|
||
}
|
||
|
||
private List<ServicePerDay> GetServicesPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
||
{
|
||
return context.Orders
|
||
.Where(order => order.Orderdata.Date >= startDate && order.Orderdata.Date <= endDate)
|
||
.SelectMany(order => order.OrdersServices)
|
||
.GroupBy(os => os.Order.Orderdata.Date)
|
||
.Select(g => new ServicePerDay
|
||
{
|
||
Date = g.Key,
|
||
CountServices = g.Count()
|
||
})
|
||
.OrderBy(spd => spd.Date)
|
||
.ToList();
|
||
}
|
||
|
||
|
||
private List<ServiceOrdersPerDay> GetServiceOrdersPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
||
{
|
||
return context.Orders
|
||
.Where(order => order.Orderdata.Date >= startDate.Date && order.Orderdata.Date <= endDate.Date)
|
||
.SelectMany(order => order.OrdersServices, (order, os) => new { order.Orderdata, os.Service })
|
||
.GroupBy(o => new { o.Orderdata.Date, o.Service.Name })
|
||
.Select(g => new ServiceOrdersPerDay
|
||
{
|
||
Date = g.Key.Date,
|
||
ServiceName = g.Key.Name,
|
||
OrderCount = g.Count()
|
||
})
|
||
.OrderBy(spd => spd.Date)
|
||
.ThenBy(spd => spd.ServiceName)
|
||
.ToList();
|
||
}
|
||
|
||
private List<ServicePerDay> GetOrdersPerDay(DatabaseContext context, DateTime startDate, DateTime endDate)
|
||
{
|
||
return context.Orders
|
||
.Where(order => order.Orderdata.Date >= startDate.Date && order.Orderdata.Date <= endDate.Date)
|
||
.GroupBy(order => order.Orderdata.Date)
|
||
.Select(g => new ServicePerDay
|
||
{
|
||
Date = g.Key,
|
||
CountServices = g.Count()
|
||
})
|
||
.OrderBy(spd => spd.Date)
|
||
.ToList();
|
||
}
|
||
|
||
private void Graph_Pdf()
|
||
{
|
||
|
||
}
|
||
|
||
private void Table_Pdf()
|
||
{
|
||
|
||
}
|
||
|
||
private void GraphXTable_Pdf()
|
||
{
|
||
|
||
}
|
||
|
||
private void Back_OnClick(object? sender, RoutedEventArgs e)
|
||
{
|
||
TimerService.Instance.Reset();
|
||
Close();
|
||
}
|
||
|
||
private void UpdateTimerText(TimeSpan time)
|
||
{
|
||
TimerText.Text = $"Осталось: {time:mm\\:ss}";
|
||
}
|
||
|
||
private void LogoutUser()
|
||
{
|
||
Close();
|
||
var mainWindow = new MainWindow();
|
||
mainWindow.Show();
|
||
}
|
||
|
||
protected override void OnClosed(EventArgs e)
|
||
{
|
||
TimerService.Instance.TimeUpdated -= UpdateTimerText;
|
||
TimerService.Instance.TimerExpired -= LogoutUser;
|
||
base.OnClosed(e);
|
||
}
|
||
} |