diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Entities/Itinerary.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Entities/Itinerary.cs index dcf4aac..279b4c9 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Entities/Itinerary.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Entities/Itinerary.cs @@ -27,4 +27,17 @@ public class Itinerary Description = description ?? string.Empty }; } + public static Itinerary CreateOpeartion(TempItineraryRoute tempItineraryRoute, IEnumerable itineraryRoutes) + { + return new Itinerary + { + Id = tempItineraryRoute.Id, + BusId = tempItineraryRoute.BusId, + DriverId = tempItineraryRoute.DriverId, + ConductorId = tempItineraryRoute.ConductorId, + ItineraryDate = tempItineraryRoute.ItineraryDate, + Description = tempItineraryRoute.Description, + ItineraryRoutes = itineraryRoutes + }; + } } \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Entities/TempItineraryRoute.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Entities/TempItineraryRoute.cs index f721af4..33d98f6 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Entities/TempItineraryRoute.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Entities/TempItineraryRoute.cs @@ -1,7 +1,15 @@ namespace ProjectAutoenterprise.Entities; -internal class TempItineraryRoute +public class TempItineraryRoute { + public int Id { get; private set; } + public int BusId { get; private set; } + public IEnumerable ItineraryRoutes { get; private set; } = []; + public int DriverId { get; private set; } + public int ConductorId { get; private set; } + public DateTime ItineraryDate { get; private set; } + public string Description { get; private set; } = string.Empty; + public int ItineraryId { get; private set; } public int RouteId { get; private set; } diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.Designer.cs b/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.Designer.cs index 2fbc1cc..e9c437d 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.Designer.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.Designer.cs @@ -39,6 +39,7 @@ ToolStripMenuItemReport = new ToolStripMenuItem(); ToolStripMenuItemDirectoryReport = new ToolStripMenuItem(); ExcelToolStripMenuItemExcel = new ToolStripMenuItem(); + PDFToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); SuspendLayout(); // @@ -102,7 +103,7 @@ // // ToolStripMenuItemReport // - ToolStripMenuItemReport.DropDownItems.AddRange(new ToolStripItem[] { ToolStripMenuItemDirectoryReport, ExcelToolStripMenuItemExcel }); + ToolStripMenuItemReport.DropDownItems.AddRange(new ToolStripItem[] { ToolStripMenuItemDirectoryReport, ExcelToolStripMenuItemExcel, PDFToolStripMenuItem }); ToolStripMenuItemReport.Name = "ToolStripMenuItemReport"; ToolStripMenuItemReport.Size = new Size(60, 20); ToolStripMenuItemReport.Text = "Отчеты"; @@ -118,10 +119,19 @@ // ExcelToolStripMenuItemExcel // ExcelToolStripMenuItemExcel.Name = "ExcelToolStripMenuItemExcel"; + ExcelToolStripMenuItemExcel.ShortcutKeys = Keys.Control | Keys.E; ExcelToolStripMenuItemExcel.Size = new Size(280, 22); ExcelToolStripMenuItemExcel.Text = "Документ Excel"; ExcelToolStripMenuItemExcel.Click += ExcelToolStripMenuItemExcel_Click; // + // PDFToolStripMenuItem + // + PDFToolStripMenuItem.Name = "PDFToolStripMenuItem"; + PDFToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.P; + PDFToolStripMenuItem.Size = new Size(280, 22); + PDFToolStripMenuItem.Text = "Документ PDF"; + PDFToolStripMenuItem.Click += PDFToolStripMenuItem_Click; + // // FormAutoenterprise // AutoScaleDimensions = new SizeF(7F, 15F); @@ -154,5 +164,6 @@ private ToolStripMenuItem ToolStripMenuItemCreatreItinerary; private ToolStripMenuItem ToolStripMenuItemDirectoryReport; private ToolStripMenuItem ExcelToolStripMenuItemExcel; + private ToolStripMenuItem PDFToolStripMenuItem; } } diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.cs b/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.cs index fd5d008..9f99211 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/FormAutoenterprise.cs @@ -109,4 +109,16 @@ public partial class FormAutoenterprise : Form MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + + private void PDFToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + _container.Resolve().ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, " ", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } } \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.Designer.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.Designer.cs new file mode 100644 index 0000000..5de61f0 --- /dev/null +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.Designer.cs @@ -0,0 +1,133 @@ +namespace ProjectAutoenterprise.Forms +{ + partial class FormBusRepairReport + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + buttonBuild = new Button(); + buttonSave = new Button(); + dateTimePickerDateBegin = new DateTimePicker(); + label4 = new Label(); + label3 = new Label(); + labelFileName = new Label(); + dateTimePickerDateEnd = new DateTimePicker(); + SuspendLayout(); + // + // buttonBuild + // + buttonBuild.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + buttonBuild.Location = new Point(63, 127); + buttonBuild.Name = "buttonBuild"; + buttonBuild.Size = new Size(134, 31); + buttonBuild.TabIndex = 19; + buttonBuild.Text = "Сформировать"; + buttonBuild.UseVisualStyleBackColor = true; + buttonBuild.Click += ButtonCreate_Click; + // + // buttonSave + // + buttonSave.Location = new Point(10, 7); + buttonSave.Name = "buttonSave"; + buttonSave.Size = new Size(68, 23); + buttonSave.TabIndex = 18; + buttonSave.Text = "Выбор"; + buttonSave.UseVisualStyleBackColor = false; + buttonSave.Click += ButtonSelectFileName_Click; + // + // dateTimePickerDateBegin + // + dateTimePickerDateBegin.Location = new Point(118, 48); + dateTimePickerDateBegin.Name = "dateTimePickerDateBegin"; + dateTimePickerDateBegin.Size = new Size(142, 23); + dateTimePickerDateBegin.TabIndex = 17; + // + // label4 + // + label4.AutoSize = true; + label4.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + label4.Location = new Point(10, 86); + label4.Name = "label4"; + label4.Size = new Size(95, 21); + label4.TabIndex = 15; + label4.Text = "Дата конца:"; + // + // label3 + // + label3.AutoSize = true; + label3.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + label3.Location = new Point(10, 48); + label3.Name = "label3"; + label3.Size = new Size(101, 21); + label3.TabIndex = 14; + label3.Text = "Дата начала:"; + // + // labelFileName + // + labelFileName.AutoSize = true; + labelFileName.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + labelFileName.Location = new Point(84, 9); + labelFileName.Name = "labelFileName"; + labelFileName.Size = new Size(50, 21); + labelFileName.TabIndex = 13; + labelFileName.Text = "Файл:"; + // + // dateTimePickerDateEnd + // + dateTimePickerDateEnd.Location = new Point(118, 85); + dateTimePickerDateEnd.Name = "dateTimePickerDateEnd"; + dateTimePickerDateEnd.Size = new Size(142, 23); + dateTimePickerDateEnd.TabIndex = 12; + // + // FormBusRepairReport + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(270, 170); + Controls.Add(buttonBuild); + Controls.Add(buttonSave); + Controls.Add(dateTimePickerDateBegin); + Controls.Add(label4); + Controls.Add(label3); + Controls.Add(labelFileName); + Controls.Add(dateTimePickerDateEnd); + Name = "FormBusRepairReport"; + Text = "FormBusRepairReport"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button buttonBuild; + private Button buttonSave; + private DateTimePicker dateTimePickerDateBegin; + private Label label4; + private Label label3; + private Label labelFileName; + private DateTimePicker dateTimePickerDateEnd; + } +} \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.cs new file mode 100644 index 0000000..20791a7 --- /dev/null +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.cs @@ -0,0 +1,56 @@ +using ProjectAutoenterprise.Reports; +using Unity; +namespace ProjectAutoenterprise.Forms; + +public partial class FormBusRepairReport : Form +{ + private string _fileName = string.Empty; + private readonly IUnityContainer _container; + public FormBusRepairReport(IUnityContainer container) + { + InitializeComponent(); + _container = container ?? + throw new ArgumentNullException(nameof(container)); + } + private void ButtonSelectFileName_Click(object sender, EventArgs e) + { + var sfd = new SaveFileDialog() + { + Filter = "Pdf Files | *.pdf" + }; + if (sfd.ShowDialog() == DialogResult.OK) + { + _fileName = sfd.FileName; + labelFileName.Text = Path.GetFileName(_fileName); + } + } + private void ButtonCreate_Click(object sender, EventArgs e) + { + try + { + if (string.IsNullOrWhiteSpace(_fileName)) + { + throw new Exception("Отсутствует имя файла для отчета"); + } + if (dateTimePickerDateEnd.Value <= dateTimePickerDateBegin.Value) + { + throw new Exception("Дата начала должна быть раньше даты окончания"); + } + if + (_container.Resolve().CreateChart(_fileName, dateTimePickerDateBegin.Value, dateTimePickerDateEnd.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); + } + } +} \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.resx b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormBusRepairReport.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormItinerary.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormItinerary.cs index 02105ef..b757a9c 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormItinerary.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormItinerary.cs @@ -66,6 +66,10 @@ public partial class FormItinerary : Form } list.Add(ItineraryRoute.CreateElement(0,Convert.ToInt32(row.Cells["ColumnRoute"].Value))); } - return list; + // DO + return list + .GroupBy(route => new { route.ItineraryId, route.RouteId }) + .Select(group => ItineraryRoute.CreateElement(group.Key.ItineraryId, group.Key.RouteId)) + .ToList(); } } \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.Designer.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.Designer.cs index 4244a58..93ff445 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.Designer.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.Designer.cs @@ -30,19 +30,19 @@ { dateTimePickerDateEnd = new DateTimePicker(); label1 = new Label(); - label2 = new Label(); label3 = new Label(); label4 = new Label(); textBoxFilePath = new TextBox(); - comboBoxRoute = new ComboBox(); dateTimePickerDateBegin = new DateTimePicker(); buttonSave = new Button(); buttonBuild = new Button(); + comboBoxBus = new ComboBox(); + label5 = new Label(); SuspendLayout(); // // dateTimePickerDateEnd // - dateTimePickerDateEnd.Location = new Point(136, 123); + dateTimePickerDateEnd.Location = new Point(135, 121); dateTimePickerDateEnd.Name = "dateTimePickerDateEnd"; dateTimePickerDateEnd.Size = new Size(142, 23); dateTimePickerDateEnd.TabIndex = 0; @@ -57,21 +57,11 @@ label1.TabIndex = 1; label1.Text = "Путь до файла:"; // - // label2 - // - label2.AutoSize = true; - label2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); - label2.Location = new Point(48, 47); - label2.Name = "label2"; - label2.Size = new Size(81, 21); - label2.TabIndex = 2; - label2.Text = "Маршрут:"; - // // label3 // label3.AutoSize = true; label3.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); - label3.Location = new Point(28, 85); + label3.Location = new Point(27, 84); label3.Name = "label3"; label3.Size = new Size(101, 21); label3.TabIndex = 3; @@ -81,7 +71,7 @@ // label4.AutoSize = true; label4.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); - label4.Location = new Point(28, 123); + label4.Location = new Point(27, 122); label4.Name = "label4"; label4.Size = new Size(95, 21); label4.TabIndex = 4; @@ -95,17 +85,9 @@ textBoxFilePath.Size = new Size(215, 23); textBoxFilePath.TabIndex = 5; // - // comboBoxRoute - // - comboBoxRoute.FormattingEnabled = true; - comboBoxRoute.Location = new Point(135, 49); - comboBoxRoute.Name = "comboBoxRoute"; - comboBoxRoute.Size = new Size(243, 23); - comboBoxRoute.TabIndex = 6; - // // dateTimePickerDateBegin // - dateTimePickerDateBegin.Location = new Point(136, 85); + dateTimePickerDateBegin.Location = new Point(135, 84); dateTimePickerDateBegin.Name = "dateTimePickerDateBegin"; dateTimePickerDateBegin.Size = new Size(142, 23); dateTimePickerDateBegin.TabIndex = 7; @@ -123,7 +105,7 @@ // buttonBuild // buttonBuild.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); - buttonBuild.Location = new Point(135, 164); + buttonBuild.Location = new Point(135, 163); buttonBuild.Name = "buttonBuild"; buttonBuild.Size = new Size(134, 31); buttonBuild.TabIndex = 9; @@ -131,22 +113,41 @@ buttonBuild.UseVisualStyleBackColor = true; buttonBuild.Click += ButtonMakeReport_Click; // + // comboBoxBus + // + comboBoxBus.FormattingEnabled = true; + comboBoxBus.Location = new Point(134, 47); + comboBoxBus.Name = "comboBoxBus"; + comboBoxBus.Size = new Size(243, 23); + comboBoxBus.TabIndex = 11; + // + // label5 + // + label5.AutoSize = true; + label5.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204); + label5.Location = new Point(32, 45); + label5.Name = "label5"; + label5.Size = new Size(96, 21); + label5.TabIndex = 10; + label5.Text = "ID автобуса:"; + // // FormRouteReport // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(396, 203); + ClientSize = new Size(396, 206); + Controls.Add(comboBoxBus); + Controls.Add(label5); Controls.Add(buttonBuild); Controls.Add(buttonSave); Controls.Add(dateTimePickerDateBegin); - Controls.Add(comboBoxRoute); Controls.Add(textBoxFilePath); Controls.Add(label4); Controls.Add(label3); - Controls.Add(label2); Controls.Add(label1); Controls.Add(dateTimePickerDateEnd); Name = "FormRouteReport"; + StartPosition = FormStartPosition.CenterParent; Text = "FormRouteReport"; ResumeLayout(false); PerformLayout(); @@ -156,13 +157,13 @@ private DateTimePicker dateTimePickerDateEnd; private Label label1; - private Label label2; private Label label3; private Label label4; private TextBox textBoxFilePath; - private ComboBox comboBoxRoute; private DateTimePicker dateTimePickerDateBegin; private Button buttonSave; private Button buttonBuild; + private ComboBox comboBoxBus; + private Label label5; } } \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.cs index 24a0805..6353ca5 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Forms/FormRouteReport.cs @@ -7,14 +7,14 @@ public partial class FormRouteReport : Form { private readonly IUnityContainer _container; public FormRouteReport(IUnityContainer container, IRouteRepository - routeRepository) + routeRepository, IBusRepository busRepository) { InitializeComponent(); _container = container ?? throw new ArgumentNullException(nameof(container)); - comboBoxRoute.DataSource = routeRepository.ReadRoutes(); - comboBoxRoute.DisplayMember = "Id"; - comboBoxRoute.ValueMember = "Id"; + comboBoxBus.DataSource = busRepository.ReadBuses(); + comboBoxBus.DisplayMember = "Id"; + comboBoxBus.ValueMember = "Id"; } private void ButtonSelectFilePath_Click(object sender, EventArgs e) { @@ -36,25 +36,25 @@ public partial class FormRouteReport : Form { throw new Exception("Отсутствует имя файла для отчета"); } - if (comboBoxRoute.SelectedIndex < 0) + if (comboBoxBus.SelectedIndex < 0) { - throw new Exception("Не выбран корм"); + throw new Exception("Не выбран маршрут"); } if (dateTimePickerDateEnd.Value <= dateTimePickerDateBegin.Value) { throw new Exception("Дата начала должна быть раньше даты окончания"); } if - (_container.Resolve().CreateTable(textBoxFilePath.Text, (int)comboBoxRoute.SelectedValue!, + (_container.Resolve().CreateTable(textBoxFilePath.Text, (int)comboBoxBus.SelectedValue!, dateTimePickerDateBegin.Value, dateTimePickerDateEnd.Value)) { MessageBox.Show("Документ сформирован", "Формирование документа", - MessageBoxButtons.OK, MessageBoxIcon.Information); + MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", - "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); + "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ChartReport.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ChartReport.cs new file mode 100644 index 0000000..b26fa01 --- /dev/null +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ChartReport.cs @@ -0,0 +1,42 @@ +using DocumentFormat.OpenXml.Wordprocessing; +using Microsoft.Extensions.Logging; +using ProjectAutoenterprise.Repositories; +namespace ProjectAutoenterprise.Reports; + +internal class ChartReport +{ + private readonly IBusRepairRepository _busRepairRepository; + private readonly ILogger _logger; + public ChartReport(IBusRepairRepository busRepairRepository, ILogger logger) + { + _busRepairRepository = busRepairRepository ?? + throw new ArgumentNullException(nameof(busRepairRepository)); + _logger = logger ?? + throw new ArgumentNullException(nameof(logger)); + } + public bool CreateChart(string filePath, DateTime startDate, DateTime endDate) + { + try + { + new PdfBuilder(filePath) + .AddHeader("Ремонт автобусов") + .AddPieChart("Отремонтированные автобусы", GetData(startDate, endDate)) + .Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + private List<(string Caption, double Value)> GetData(DateTime startDate, DateTime endDate) + { + return _busRepairRepository + .ReadBusRepairs() + .Where(x => x.RepairDate >= startDate && x.RepairDate <= endDate) + .GroupBy(x => x.BusId, (key, group) => new { Id = key, Count = group.Count() }) + .Select(x => (x.Id.ToString(), (double)x.Count)) + .ToList(); + } +} \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/DocReport.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/DocReport.cs index 98a6619..18328b5 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/DocReport.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/DocReport.cs @@ -27,6 +27,12 @@ internal class DocReport { var builder = new WordBuilder(filePath) .AddHeader("Документ со справочниками"); + if (includeBuses) + { + builder.AddParagraph("Автобусы") + .AddTable([2400, 2400, 2400], + GetBuses()); + } if (includeRoutes) { builder.AddParagraph("Маршруты") @@ -39,12 +45,7 @@ internal class DocReport .AddTable([2400, 2400, 2400, 2400], GetEmployees()); } - if (includeBuses) - { - builder.AddParagraph("Автобусы") - .AddTable([2400, 2400, 1200], - GetBuses()); - } + builder.AddParagraph(""); builder.Build(); return true; } @@ -66,7 +67,7 @@ internal class DocReport return [ ["Имя", "Фамилия", "Дата рождения", "Должность"], .. _employeeRepository.ReadEmployees().Select(x => new string[] - { x.FirstName, x.LastName, x.BirthDate.ToString(), x.EmployeePost.ToString()}), + { x.FirstName, x.LastName, x.BirthDate.ToString("dd-MM-yyyy"), x.EmployeePost.ToString()}), ]; } private List GetBuses() diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ExcelBuilder.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ExcelBuilder.cs index a282c81..8d0ed31 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ExcelBuilder.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/ExcelBuilder.cs @@ -57,7 +57,7 @@ internal class ExcelBuilder { throw new ArgumentNullException(nameof(data)); } - if (data.Any(x => x.Length != columnsWidths.Length)) + if (data.Any(x => x.Length > columnsWidths.Length)) { throw new InvalidOperationException("widths.Length != data.Length"); } diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/PdfBuilder.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/PdfBuilder.cs new file mode 100644 index 0000000..4556863 --- /dev/null +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/PdfBuilder.cs @@ -0,0 +1,72 @@ +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.Shapes.Charts; +using MigraDoc.Rendering; +using System.Text; +namespace ProjectAutoenterprise.Reports; + +internal class PdfBuilder +{ + private readonly string _filePath; + private readonly Document _document; + public PdfBuilder(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + _filePath = filePath; + _document = new Document(); + DefineStyles(); + } + public PdfBuilder AddHeader(string header) + { + _document.AddSection().AddParagraph(header, "NormalBold"); + return this; + } + public PdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data) + { + if (data == null || data.Count == 0) + { + return this; + } + var chart = new Chart(ChartType.Pie2D); + var series = chart.SeriesCollection.AddSeries(); + series.Add(data.Select(x => x.Value).ToArray()); + var xseries = chart.XValues.AddXSeries(); + xseries.Add(data.Select(x => x.Caption).ToArray()); + chart.DataLabel.Type = DataLabelType.Percent; + chart.DataLabel.Position = DataLabelPosition.OutsideEnd; + chart.Width = Unit.FromCentimeter(16); + chart.Height = Unit.FromCentimeter(12); + chart.TopArea.AddParagraph(title); + chart.XAxis.MajorTickMark = TickMarkType.Outside; + chart.YAxis.MajorTickMark = TickMarkType.Outside; + chart.YAxis.HasMajorGridlines = true; + chart.PlotArea.LineFormat.Width = 1; + chart.PlotArea.LineFormat.Visible = true; + chart.TopArea.AddLegend(); + _document.LastSection.Add(chart); + return this; + } + public void Build() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + var renderer = new PdfDocumentRenderer(true) + { + Document = _document + }; + renderer.RenderDocument(); + renderer.PdfDocument.Save(_filePath); + } + private void DefineStyles() + { + // DO задать стиль для заголовка (жирный) + var headerStyle = _document.Styles.AddStyle("NormalBold", "Normal"); + headerStyle.Font.Bold = true; + headerStyle.Font.Size = 14; + } +} \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/TableReport.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/TableReport.cs index d29278d..5c30e8e 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/TableReport.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/TableReport.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using DocumentFormat.OpenXml.Bibliography; +using Microsoft.Extensions.Logging; using ProjectAutoenterprise.Entities; using ProjectAutoenterprise.Repositories; using System.Linq; @@ -9,7 +10,8 @@ internal class TableReport private readonly IItineraryRepository _itineraryRepository; private readonly IBusRepository _busRepository; private readonly ILogger _logger; - internal static readonly string[] item = ["Дата", "Автобус", "Водитель", "Кондуктор"]; + internal static readonly string[] item = ["Дата", "Id Автобуса", "Id Водителя", "Id Кондуктора","Кол-во поездок по маршруту"]; + //internal static readonly string[] item = ["Автобус","Дата", "Кол-во мест"]; public TableReport(IItineraryRepository itineraryRepository, IBusRepository busRepository, ILogger logger) { @@ -21,14 +23,14 @@ internal class TableReport throw new ArgumentNullException(nameof(logger)); } - public bool CreateTable(string filePath, int routeId, DateTime startDate, DateTime endDate) + public bool CreateTable(string filePath, int busId, DateTime startDate, DateTime endDate) { try { new ExcelBuilder(filePath) - .AddHeader("Сводка по маршруту", 0, 4) + .AddHeader("Сводка по поездкам автобуса", 0, 5) .AddParagraph("за период", 0) - .AddTable([10, 10, 15, 15], GetData(routeId, startDate, endDate)) + .AddTable([10, 10, 10, 10, 15], GetData(busId, startDate, endDate)) .Build(); return true; } @@ -38,39 +40,28 @@ internal class TableReport return false; } } - private List GetData(int routeId, DateTime startDate, DateTime endDate) + private List GetData(int busId, DateTime startDate, DateTime endDate) { + var data = _itineraryRepository .ReadItinerary() - .Where(x => x.ItineraryDate >= startDate && x.ItineraryDate <= endDate && - x.ItineraryRoutes.Any(y => y.RouteId == routeId)) - .Select(x => new + .Where(x => x.ItineraryDate >= startDate && x.ItineraryDate <= endDate && x.BusId == busId) + .Select(x => new { Date = x.ItineraryDate, BusId = x.BusId, DriverId = x.DriverId, - ConductorId = x.ConductorId + ConductorId = x.ConductorId, + CountRoutes = (int?)x.ItineraryRoutes.Count() }) - - /*.Union( - _busRepository - .ReadBuses() - .Where(x => true) - .Select(x => new - { - Date = (int?)null, - BusId = (int?)null, - DriverId = (int?)null, - ConductorId = (int?)null - }))*/ - .OrderBy(x => x.Date); + .OrderBy(x => x.Date); return new List() { item } .Union( data - .Select(x => new string[] { x.Date.ToString(), x.BusId.ToString(), x.DriverId.ToString(), x.ConductorId.ToString()})) - //.Union( - // [["Всего", "", data.Sum(x => x.Capacity ?? 0).ToString()]]) + .Select(x => new string[] { x.Date.ToString("dd-MM-yyyy"), x.BusId.ToString(), x.DriverId.ToString(), x.ConductorId.ToString(), x.CountRoutes.ToString()})) + .Union( + [["Всего", "", data.Sum(x => x.CountRoutes ?? 0).ToString()]]) .ToList(); } } \ No newline at end of file diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/WordBuilder.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/WordBuilder.cs index 4e8fa71..d809c34 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Reports/WordBuilder.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Reports/WordBuilder.cs @@ -79,6 +79,7 @@ internal class WordBuilder table.Append(data.Skip(1).Select(x => new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y)))))))); _body.Append(table); + return this; } public void Build() diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/BusRepairRepository.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/BusRepairRepository.cs index f8facd2..6050083 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/BusRepairRepository.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/BusRepairRepository.cs @@ -35,8 +35,7 @@ VALUES (@BusId, @RepairDate, @Description)"; throw; } } - public IEnumerable ReadBusRepairs( - DateTime? dateForm = null, DateTime? dateTo = null, int? busId = null, string? description = null) + public IEnumerable ReadBusRepairs(DateTime? dateForm = null, DateTime? dateTo = null, int? busId = null, string? description = null) { _logger.LogInformation("Получение всех объектов"); try diff --git a/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/ItineraryRepository.cs b/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/ItineraryRepository.cs index e55b2db..bd72531 100644 --- a/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/ItineraryRepository.cs +++ b/ProjectAutoenterprise/ProjectAutoenterprise/Repositories/Implementations/ItineraryRepository.cs @@ -74,12 +74,13 @@ WHERE Id=@id"; { using var connection = new NpgsqlConnection(_connectionString.ConnectionString); var querySelect = @" -SELECT fr.*, ffr.FeedId, ffr.Count FROM FeedReplenishments fr -INNER JOIN FeedFeedReplenishments ffr ON ffr.FeedReplenishmentId = fr.Id"; - var itineraries = connection.Query(querySelect); - _logger.LogDebug("Полученные объекты: {json}", - JsonConvert.SerializeObject(itineraries)); - return itineraries; +SELECT it.*, itr.RouteId FROM Itineraries it +INNER JOIN ItineraryRoutes itr ON itr.ItineraryId = it.Id"; + var itineraries = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(itineraries)); + + return itineraries.GroupBy(x => x.Id, y => y, (key, value) => Itinerary.CreateOpeartion( + value.First(), value.Select(z => ItineraryRoute.CreateElement(0, z.RouteId)) ) ).ToList(); } catch (Exception ex) {