demo040225_version2/dmeo040225/ReportWindow.axaml.cs
2025-05-06 10:41:15 +03:00

237 lines
7.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}