10 Commits

46 changed files with 2375 additions and 135 deletions

8
.gitignore vendored
View File

@@ -402,3 +402,11 @@ FodyWeavers.xsd
/edit.png
/minus.jpg
/plus.jpg
/docAll1.docx
/docBus1.docx
/docBuses1.docx
/excel1.xlsx
/pdf1.pdf
*.docx
*.xlsx
*.pdf

View File

@@ -6,16 +6,16 @@ public class Bus
{
public int Id { get; private set; }
public string LicensePlate { get; private set; } = string.Empty;
public string Licence_plate { get; private set; } = string.Empty;
public string Model { get; private set; } = string.Empty;
public static Bus CreateEntity(int id, string licensePlate, string model)
public static Bus CreateEntity(int id, string licencePlate, string model)
{
return new Bus
{
Id = id,
LicensePlate = licensePlate,
Licence_plate = licencePlate,
Model = model
};
}

View File

@@ -6,9 +6,9 @@ public class Employee
{
public int Id { get; private set; }
public string FirstName { get; private set; } = string.Empty;
public string First_name { get; private set; } = string.Empty;
public string LastName { get; private set; } = string.Empty;
public string Last_name { get; private set; } = string.Empty;
public EmployeePost Post { get; private set; }
@@ -17,8 +17,8 @@ public class Employee
return new Employee
{
Id = id,
FirstName = first ?? string.Empty,
LastName = last ?? string.Empty,
First_name = first ?? string.Empty,
Last_name = last ?? string.Empty,
Post = post
};
}

View File

@@ -8,11 +8,11 @@ public class GoToService
public DateTime Date { get; private set; }
public BrokenElements BrokenElements { get; private set; }
public BrokenElements Broken_elements { get; private set; }
public int Price { get; private set; }
public int BusId { get; private set; }
public int Bus_id { get; private set; }
public static GoToService CreateOperation(int id, BrokenElements brokenElements, int price, int busId)
{
@@ -20,9 +20,9 @@ public class GoToService
{
Id = id,
Date = DateTime.Now,
BrokenElements = brokenElements,
Broken_elements = brokenElements,
Price = price,
BusId = busId
Bus_id = busId
};
}
}

View File

@@ -4,17 +4,17 @@ public class RouteList
{
public int Id { get; private set; }
public TimeOnly Start { get; private set; }
public TimeSpan Route_start { get; private set; }
public TimeOnly Finish { get; private set; }
public TimeSpan Route_finish { get; private set; }
public static RouteList CreateEntity(int id, TimeOnly start, TimeOnly finish)
public static RouteList CreateEntity(int id, TimeSpan start, TimeSpan finish)
{
return new RouteList
{
Id = id,
Start = start,
Finish = finish
Route_start = start,
Route_finish = finish
};
}
}

View File

@@ -6,11 +6,11 @@ public class StartingShift
public DateTime Date { get; private set; }
public int RouteListId { get; private set; }
public int Route_list_id { get; private set; }
public int BusId { get; private set; }
public int Bus_id { get; private set; }
public IEnumerable<StartingShiftEmployee> StartingShiftEmployees { get; private set; } = [];
public IEnumerable<StartingShiftEmployee> Starting_shift_employees { get; private set; } = [];
public static StartingShift CreateOperation(int id, int routeListId, int busId,
IEnumerable<StartingShiftEmployee> startingShiftEmployees)
@@ -19,9 +19,22 @@ public class StartingShift
{
Id = id,
Date = DateTime.Now,
RouteListId = routeListId,
BusId = busId,
StartingShiftEmployees = startingShiftEmployees
Route_list_id = routeListId,
Bus_id = busId,
Starting_shift_employees = startingShiftEmployees
};
}
public static StartingShift CreateOperation(TempStartingShiftEmployee tempStartingShiftEmployee,
IEnumerable<StartingShiftEmployee> startingShiftEmployee)
{
return new StartingShift
{
Id = tempStartingShiftEmployee.Starting_shift_id,
Date = tempStartingShiftEmployee.Date,
Route_list_id = tempStartingShiftEmployee.Route_list_id,
Bus_id = tempStartingShiftEmployee.Bus_id,
Starting_shift_employees = startingShiftEmployee
};
}
}

View File

@@ -2,19 +2,19 @@
public class StartingShiftEmployee
{
public int StartingShiftId { get; private set; }
public int Starting_shift_id { get; private set; }
public int EmployeeId { get; private set; }
public int Employee_id { get; private set; }
public int WorkHours { get; private set; }
public int Work_time { get; private set; }
public static StartingShiftEmployee CreateElement(int startingShiftId, int employeeId, int workHours)
public static StartingShiftEmployee CreateElement(int startingShiftId, int employeeId, int workTime)
{
return new StartingShiftEmployee
{
StartingShiftId = startingShiftId,
EmployeeId = employeeId,
WorkHours = workHours
Starting_shift_id = startingShiftId,
Employee_id = employeeId,
Work_time = workTime
};
}
}

View File

@@ -0,0 +1,16 @@
namespace ProjectPassengerTransportation.Entities;
public class TempStartingShiftEmployee
{
public int Starting_shift_id { get; private set; }
public int Employee_id { get; private set; }
public int Route_list_id { get; private set; }
public int Bus_id { get; private set; }
public DateTime Date { get; private set; }
public int Work_time { get; private set; }
}

View File

@@ -37,6 +37,9 @@
StartingShiftsToolStripMenuItem = new ToolStripMenuItem();
GoToServicesToolStripMenuItem = new ToolStripMenuItem();
отчётыToolStripMenuItem = new ToolStripMenuItem();
directoryReportToolStripMenuItem = new ToolStripMenuItem();
busesReportToolStripMenuItem = new ToolStripMenuItem();
serviceReportToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
@@ -88,23 +91,48 @@
// StartingShiftsToolStripMenuItem
//
StartingShiftsToolStripMenuItem.Name = "StartingShiftsToolStripMenuItem";
StartingShiftsToolStripMenuItem.Size = new Size(315, 40);
StartingShiftsToolStripMenuItem.Size = new Size(314, 40);
StartingShiftsToolStripMenuItem.Text = "Начало смены";
StartingShiftsToolStripMenuItem.Click += StartingShiftsToolStripMenuItem_Click;
//
// GoToServicesToolStripMenuItem
//
GoToServicesToolStripMenuItem.Name = "GoToServicesToolStripMenuItem";
GoToServicesToolStripMenuItem.Size = new Size(315, 40);
GoToServicesToolStripMenuItem.Size = new Size(314, 40);
GoToServicesToolStripMenuItem.Text = "Тех. обслуживание";
GoToServicesToolStripMenuItem.Click += GoToServicesToolStripMenuItem_Click;
//
// отчётыToolStripMenuItem
//
отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { directoryReportToolStripMenuItem, busesReportToolStripMenuItem, serviceReportToolStripMenuItem });
отчётыToolStripMenuItem.Name = "отчётыToolStripMenuItem";
отчётыToolStripMenuItem.Size = new Size(103, 34);
отчётыToolStripMenuItem.Text = "Отчёты";
//
// directoryReportToolStripMenuItem
//
directoryReportToolStripMenuItem.Name = "directoryReportToolStripMenuItem";
directoryReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W;
directoryReportToolStripMenuItem.Size = new Size(517, 40);
directoryReportToolStripMenuItem.Text = "Документ со справочниками";
directoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click;
//
// busesReportToolStripMenuItem
//
busesReportToolStripMenuItem.Name = "busesReportToolStripMenuItem";
busesReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.E;
busesReportToolStripMenuItem.Size = new Size(517, 40);
busesReportToolStripMenuItem.Text = "Работа сотрудников и автобусов";
busesReportToolStripMenuItem.Click += BusesReportToolStripMenuItem_Click;
//
// serviceReportToolStripMenuItem
//
serviceReportToolStripMenuItem.Name = "serviceReportToolStripMenuItem";
serviceReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.P;
serviceReportToolStripMenuItem.Size = new Size(517, 40);
serviceReportToolStripMenuItem.Text = "Сломанные элементы";
serviceReportToolStripMenuItem.Click += ServiceReportToolStripMenuItem_Click;
//
// FormPassengerTransportation
//
AutoScaleDimensions = new SizeF(12F, 30F);
@@ -134,5 +162,8 @@
private ToolStripMenuItem отчётыToolStripMenuItem;
private ToolStripMenuItem StartingShiftsToolStripMenuItem;
private ToolStripMenuItem GoToServicesToolStripMenuItem;
private ToolStripMenuItem directoryReportToolStripMenuItem;
private ToolStripMenuItem busesReportToolStripMenuItem;
private ToolStripMenuItem serviceReportToolStripMenuItem;
}
}

View File

@@ -72,5 +72,41 @@ namespace ProjectPassengerTransportation
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DirectoryReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDirectoryReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BusesReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormWorkReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ServiceReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormServiceReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@@ -28,30 +28,30 @@
/// </summary>
private void InitializeComponent()
{
labelLicensePlate = new Label();
textBoxLicensePlate = new TextBox();
labelLicencePlate = new Label();
textBoxLicencePlate = new TextBox();
labelBusTypeName = new Label();
buttonSave = new Button();
buttonCancel = new Button();
textBoxModel = new TextBox();
SuspendLayout();
//
// labelLicensePlate
// labelLicencePlate
//
labelLicensePlate.AutoSize = true;
labelLicensePlate.Location = new Point(27, 34);
labelLicensePlate.Name = "labelLicensePlate";
labelLicensePlate.Size = new Size(107, 30);
labelLicensePlate.TabIndex = 0;
labelLicensePlate.Text = "Госномер";
labelLicencePlate.AutoSize = true;
labelLicencePlate.Location = new Point(27, 34);
labelLicencePlate.Name = "labelLicencePlate";
labelLicencePlate.Size = new Size(107, 30);
labelLicencePlate.TabIndex = 0;
labelLicencePlate.Text = "Госномер";
//
// textBoxLicensePlate
// textBoxLicencePlate
//
textBoxLicensePlate.Location = new Point(231, 31);
textBoxLicensePlate.MaxLength = 10;
textBoxLicensePlate.Name = "textBoxLicensePlate";
textBoxLicensePlate.Size = new Size(240, 35);
textBoxLicensePlate.TabIndex = 1;
textBoxLicencePlate.Location = new Point(231, 31);
textBoxLicencePlate.MaxLength = 10;
textBoxLicencePlate.Name = "textBoxLicencePlate";
textBoxLicencePlate.Size = new Size(240, 35);
textBoxLicencePlate.TabIndex = 1;
//
// labelBusTypeName
//
@@ -101,8 +101,8 @@
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelBusTypeName);
Controls.Add(textBoxLicensePlate);
Controls.Add(labelLicensePlate);
Controls.Add(textBoxLicencePlate);
Controls.Add(labelLicencePlate);
Name = "FormBus";
StartPosition = FormStartPosition.CenterParent;
Text = "Автобус";
@@ -112,8 +112,8 @@
#endregion
private Label labelLicensePlate;
private TextBox textBoxLicensePlate;
private Label labelLicencePlate;
private TextBox textBoxLicencePlate;
private Label labelBusTypeName;
private Button buttonSave;
private Button buttonCancel;

View File

@@ -1,5 +1,4 @@
using ProjectPassengerTransportation.Entities;
using ProjectPassengerTransportation.Entities.Enums;
using ProjectPassengerTransportation.Repositories;
namespace ProjectPassengerTransportation.Forms
@@ -22,7 +21,7 @@ namespace ProjectPassengerTransportation.Forms
throw new InvalidDataException(nameof(bus));
}
textBoxLicensePlate.Text = bus.LicensePlate;
textBoxLicencePlate.Text = bus.Licence_plate;
textBoxModel.Text = bus.Model;
_busId = value;
}
@@ -44,7 +43,7 @@ namespace ProjectPassengerTransportation.Forms
{
try
{
if (string.IsNullOrWhiteSpace(textBoxLicensePlate.Text) || string.IsNullOrWhiteSpace(textBoxModel.Text))
if (string.IsNullOrWhiteSpace(textBoxLicencePlate.Text) || string.IsNullOrWhiteSpace(textBoxModel.Text))
{
throw new Exception("Имеются незаполненные поля");
}
@@ -68,6 +67,6 @@ namespace ProjectPassengerTransportation.Forms
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Bus CreateBus(int id) => Bus.CreateEntity(id, textBoxLicensePlate.Text, textBoxModel.Text);
private Bus CreateBus(int id) => Bus.CreateEntity(id, textBoxLicencePlate.Text, textBoxModel.Text);
}
}

View File

@@ -0,0 +1,99 @@
namespace ProjectPassengerTransportation.Forms
{
partial class FormDirectoryReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
checkBoxBuses = new CheckBox();
checkBoxEmployees = new CheckBox();
checkBoxRouteLists = new CheckBox();
buttonBuild = new Button();
SuspendLayout();
//
// checkBoxBuses
//
checkBoxBuses.AutoSize = true;
checkBoxBuses.Location = new Point(69, 43);
checkBoxBuses.Name = "checkBoxBuses";
checkBoxBuses.Size = new Size(132, 34);
checkBoxBuses.TabIndex = 0;
checkBoxBuses.Text = "Автобусы";
checkBoxBuses.UseVisualStyleBackColor = true;
//
// checkBoxEmployees
//
checkBoxEmployees.AutoSize = true;
checkBoxEmployees.Location = new Point(69, 109);
checkBoxEmployees.Name = "checkBoxEmployees";
checkBoxEmployees.Size = new Size(141, 34);
checkBoxEmployees.TabIndex = 1;
checkBoxEmployees.Text = "Работники";
checkBoxEmployees.UseVisualStyleBackColor = true;
//
// checkBoxRouteLists
//
checkBoxRouteLists.AutoSize = true;
checkBoxRouteLists.Location = new Point(69, 176);
checkBoxRouteLists.Name = "checkBoxRouteLists";
checkBoxRouteLists.Size = new Size(230, 34);
checkBoxRouteLists.TabIndex = 2;
checkBoxRouteLists.Text = "Маршрутные листы";
checkBoxRouteLists.UseVisualStyleBackColor = true;
//
// buttonBuild
//
buttonBuild.Location = new Point(369, 99);
buttonBuild.Name = "buttonBuild";
buttonBuild.Size = new Size(181, 53);
buttonBuild.TabIndex = 3;
buttonBuild.Text = "Сформировать";
buttonBuild.UseVisualStyleBackColor = true;
buttonBuild.Click += ButtonBuild_Click;
//
// FormDirectoryReport
//
AutoScaleDimensions = new SizeF(12F, 30F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(616, 256);
Controls.Add(buttonBuild);
Controls.Add(checkBoxRouteLists);
Controls.Add(checkBoxEmployees);
Controls.Add(checkBoxBuses);
Name = "FormDirectoryReport";
Text = "Выгрузка справочников";
ResumeLayout(false);
PerformLayout();
}
#endregion
private CheckBox checkBoxBuses;
private CheckBox checkBoxEmployees;
private CheckBox checkBoxRouteLists;
private Button buttonBuild;
}
}

View File

@@ -0,0 +1,53 @@
using ProjectPassengerTransportation.Reports;
using Unity;
namespace ProjectPassengerTransportation.Forms
{
public partial class FormDirectoryReport : Form
{
private readonly IUnityContainer _container;
public FormDirectoryReport(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ButtonBuild_Click(object sender, EventArgs e)
{
try
{
if (!checkBoxBuses.Checked && !checkBoxEmployees.Checked && !checkBoxRouteLists.Checked)
{
throw new Exception("Не выбран ни один справочник для выгрузки");
}
var sfd = new SaveFileDialog()
{
Filter = "Docx Files | *.docx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
throw new Exception("Не выбран файла для отчета");
}
if (_container.Resolve<DocReport>().CreateDoc(sfd.FileName, checkBoxBuses.Checked,
checkBoxEmployees.Checked, checkBoxRouteLists.Checked))
{
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

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -126,7 +126,7 @@
Controls.Add(comboBoxPost);
Name = "FormEmployee";
StartPosition = FormStartPosition.CenterParent;
Text = "FormEmployee";
Text = "Сотрудник";
ResumeLayout(false);
PerformLayout();
}

View File

@@ -23,8 +23,8 @@ namespace ProjectPassengerTransportation.Forms
throw new InvalidDataException(nameof(employee));
}
textBoxFirstName.Text = employee.FirstName;
textBoxLastName.Text = employee.LastName;
textBoxFirstName.Text = employee.First_name;
textBoxLastName.Text = employee.Last_name;
comboBoxPost.SelectedItem = employee.Post;
_employeeId = value;
}

View File

@@ -93,6 +93,7 @@
// numericUpDownPrice
//
numericUpDownPrice.Location = new Point(168, 310);
numericUpDownPrice.Maximum = new decimal(new int[] { 1000000, 0, 0, 0 });
numericUpDownPrice.Name = "numericUpDownPrice";
numericUpDownPrice.Size = new Size(245, 35);
numericUpDownPrice.TabIndex = 21;

View File

@@ -13,7 +13,7 @@ namespace ProjectPassengerTransportation.Forms
InitializeComponent();
_goToServiceRepository = goToServiceRepository ?? throw new ArgumentNullException(nameof(goToServiceRepository));
comboBoxBus.DataSource = busRepository.ReadBuses();
comboBoxBus.DisplayMember = "LicensePlate";
comboBoxBus.DisplayMember = "Licence_plate";
comboBoxBus.ValueMember = "Id";
foreach (var elem in Enum.GetValues(typeof(BrokenElements)))
{

View File

@@ -21,10 +21,10 @@ namespace ProjectPassengerTransportation.Forms
throw new InvalidDataException(nameof(routeList));
}
numericUpDownStartHour.Value = routeList.Start.Hour;
numericUpDownStartMin.Value = routeList.Start.Minute;
numericUpDownFinishHour.Value = routeList.Finish.Hour;
numericUpDownFinishMin.Value = routeList.Finish.Minute;
numericUpDownStartHour.Value = (decimal)routeList.Route_start.Hours;
numericUpDownStartMin.Value = (decimal)routeList.Route_start.Minutes;
numericUpDownFinishHour.Value = (decimal)routeList.Route_finish.Hours;
numericUpDownFinishMin.Value = (decimal)routeList.Route_finish.Minutes;
_routeListId = value;
}
catch (Exception ex)
@@ -65,7 +65,7 @@ namespace ProjectPassengerTransportation.Forms
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private RouteList CreateRouteList(int id) => RouteList.CreateEntity(id,
new TimeOnly(Convert.ToInt32(numericUpDownStartHour.Value), Convert.ToInt32(numericUpDownStartMin.Value)),
new TimeOnly(Convert.ToInt32(numericUpDownFinishHour.Value), Convert.ToInt32(numericUpDownFinishMin.Value)));
new TimeSpan(Convert.ToInt32(numericUpDownStartHour.Value), Convert.ToInt32(numericUpDownStartMin.Value), 0),
new TimeSpan(Convert.ToInt32(numericUpDownFinishHour.Value), Convert.ToInt32(numericUpDownFinishMin.Value), 0));
}
}

View File

@@ -0,0 +1,107 @@
namespace ProjectPassengerTransportation.Forms
{
partial class FormServiceReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
buttonSelectFile = new Button();
labelFileName = new Label();
dateTimePicker = new DateTimePicker();
labelDate = new Label();
buttonMakeReport = new Button();
SuspendLayout();
//
// buttonSelectFile
//
buttonSelectFile.Location = new Point(36, 36);
buttonSelectFile.Name = "buttonSelectFile";
buttonSelectFile.Size = new Size(131, 40);
buttonSelectFile.TabIndex = 0;
buttonSelectFile.Text = "Выбрать";
buttonSelectFile.UseVisualStyleBackColor = true;
buttonSelectFile.Click += ButtonSelectFile_Click;
//
// labelFileName
//
labelFileName.AutoSize = true;
labelFileName.Location = new Point(195, 41);
labelFileName.Name = "labelFileName";
labelFileName.Size = new Size(62, 30);
labelFileName.TabIndex = 1;
labelFileName.Text = "Файл";
//
// dateTimePicker
//
dateTimePicker.Location = new Point(144, 127);
dateTimePicker.Name = "dateTimePicker";
dateTimePicker.Size = new Size(311, 35);
dateTimePicker.TabIndex = 2;
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(49, 131);
labelDate.Name = "labelDate";
labelDate.Size = new Size(64, 30);
labelDate.TabIndex = 3;
labelDate.Text = "Дата:";
//
// buttonMakeReport
//
buttonMakeReport.Location = new Point(168, 205);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(178, 46);
buttonMakeReport.TabIndex = 4;
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = true;
buttonMakeReport.Click += ButtonMakeReport_Click;
//
// FormServiceReport
//
AutoScaleDimensions = new SizeF(12F, 30F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(511, 276);
Controls.Add(buttonMakeReport);
Controls.Add(labelDate);
Controls.Add(dateTimePicker);
Controls.Add(labelFileName);
Controls.Add(buttonSelectFile);
Name = "FormServiceReport";
Text = "Отчет по тех обслуживанию";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSelectFile;
private Label labelFileName;
private DateTimePicker dateTimePicker;
private Label labelDate;
private Button buttonMakeReport;
}
}

View File

@@ -0,0 +1,60 @@
using ProjectPassengerTransportation.Reports;
using Unity;
namespace ProjectPassengerTransportation.Forms
{
public partial class FormServiceReport : Form
{
private string _fileName = string.Empty;
private readonly IUnityContainer _container;
public FormServiceReport(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ButtonSelectFile_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 ButtonMakeReport_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(_fileName))
{
throw new Exception("Отсутствует имя файла отчета");
}
if
(_container.Resolve<ChartReport>().CreateChart(_fileName, dateTimePicker.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

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -17,10 +17,10 @@ namespace ProjectPassengerTransportation.Forms
comboBoxRouteList.DisplayMember = "Id";
comboBoxRouteList.ValueMember = "Id";
comboBoxBus.DataSource = busRepository.ReadBuses();
comboBoxBus.DisplayMember = "LicensePlate";
comboBoxBus.DisplayMember = "Licence_plate";
comboBoxBus.ValueMember = "Id";
ColumnEmployees.DataSource = employeeRepository.ReadEmployees();
ColumnEmployees.DisplayMember = "FirstName";
ColumnEmployees.DisplayMember = "First_name";
ColumnEmployees.ValueMember = "Id";
}
@@ -55,8 +55,8 @@ namespace ProjectPassengerTransportation.Forms
var list = new List<StartingShiftEmployee>();
foreach (DataGridViewRow row in dataGridViewEmployees.Rows)
{
if (row.Cells["ColumnFeed"].Value == null ||
row.Cells["ColumnCount"].Value == null)
if (row.Cells["ColumnEmployees"].Value == null ||
row.Cells["ColumnWorkHours"].Value == null)
{
continue;
}
@@ -64,7 +64,8 @@ namespace ProjectPassengerTransportation.Forms
Convert.ToInt32(row.Cells["ColumnEmployees"].Value),
Convert.ToInt32(row.Cells["ColumnWorkHours"].Value)));
}
return list;
return list.GroupBy(x => x.Employee_id, x => x.Work_time, (employeeId, workTime) =>
StartingShiftEmployee.CreateElement(0, employeeId, workTime.Sum())).ToList();
}
}
}

View File

@@ -51,16 +51,16 @@
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.RowHeadersWidth = 72;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(845, 481);
dataGridViewData.Size = new Size(1280, 636);
dataGridViewData.TabIndex = 5;
//
// panelButtons
//
panelButtons.Controls.Add(buttonAdd);
panelButtons.Dock = DockStyle.Right;
panelButtons.Location = new Point(845, 0);
panelButtons.Location = new Point(1280, 0);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(196, 481);
panelButtons.Size = new Size(196, 636);
panelButtons.TabIndex = 4;
//
// buttonAdd
@@ -78,7 +78,7 @@
//
AutoScaleDimensions = new SizeF(12F, 30F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1041, 481);
ClientSize = new Size(1476, 636);
Controls.Add(dataGridViewData);
Controls.Add(panelButtons);
Name = "FormStartingShifts";

View File

@@ -0,0 +1,186 @@
namespace ProjectPassengerTransportation.Forms
{
partial class FormWorkReport
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelFilePath = new Label();
textBoxFilePath = new TextBox();
buttonSelectFilePath = new Button();
dateTimePickerBeginDate = new DateTimePicker();
dateTimePickerEndDate = new DateTimePicker();
labelEmployee = new Label();
labelBeginDate = new Label();
labelEndDate = new Label();
buttonMakeReport = new Button();
comboBoxEmployee = new ComboBox();
comboBoxBus = new ComboBox();
labelBus = new Label();
SuspendLayout();
//
// labelFilePath
//
labelFilePath.AutoSize = true;
labelFilePath.Location = new Point(23, 37);
labelFilePath.Name = "labelFilePath";
labelFilePath.Size = new Size(157, 30);
labelFilePath.TabIndex = 0;
labelFilePath.Text = "Путь до файла:";
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(203, 37);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.ReadOnly = true;
textBoxFilePath.Size = new Size(361, 35);
textBoxFilePath.TabIndex = 1;
//
// buttonSelectFilePath
//
buttonSelectFilePath.Location = new Point(570, 32);
buttonSelectFilePath.Name = "buttonSelectFilePath";
buttonSelectFilePath.Size = new Size(40, 40);
buttonSelectFilePath.TabIndex = 2;
buttonSelectFilePath.Text = "...";
buttonSelectFilePath.UseVisualStyleBackColor = true;
buttonSelectFilePath.Click += ButtonSelectFilePath_Click;
//
// dateTimePickerBeginDate
//
dateTimePickerBeginDate.Location = new Point(203, 271);
dateTimePickerBeginDate.Name = "dateTimePickerBeginDate";
dateTimePickerBeginDate.Size = new Size(407, 35);
dateTimePickerBeginDate.TabIndex = 4;
//
// dateTimePickerEndDate
//
dateTimePickerEndDate.Location = new Point(203, 343);
dateTimePickerEndDate.Name = "dateTimePickerEndDate";
dateTimePickerEndDate.Size = new Size(407, 35);
dateTimePickerEndDate.TabIndex = 5;
//
// labelEmployee
//
labelEmployee.AutoSize = true;
labelEmployee.Location = new Point(23, 117);
labelEmployee.Name = "labelEmployee";
labelEmployee.Size = new Size(103, 30);
labelEmployee.TabIndex = 6;
labelEmployee.Text = "Работник";
//
// labelBeginDate
//
labelBeginDate.AutoSize = true;
labelBeginDate.Location = new Point(23, 275);
labelBeginDate.Name = "labelBeginDate";
labelBeginDate.Size = new Size(133, 30);
labelBeginDate.TabIndex = 7;
labelBeginDate.Text = "Дата начала";
//
// labelEndDate
//
labelEndDate.AutoSize = true;
labelEndDate.Location = new Point(23, 347);
labelEndDate.Name = "labelEndDate";
labelEndDate.Size = new Size(123, 30);
labelEndDate.TabIndex = 8;
labelEndDate.Text = "Дата конца";
//
// buttonMakeReport
//
buttonMakeReport.Location = new Point(203, 410);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(177, 40);
buttonMakeReport.TabIndex = 9;
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = true;
buttonMakeReport.Click += ButtonMakeReport_Click;
//
// comboBoxEmployee
//
comboBoxEmployee.FormattingEnabled = true;
comboBoxEmployee.Location = new Point(203, 114);
comboBoxEmployee.Name = "comboBoxEmployee";
comboBoxEmployee.Size = new Size(407, 38);
comboBoxEmployee.TabIndex = 10;
//
// comboBoxBus
//
comboBoxBus.FormattingEnabled = true;
comboBoxBus.Location = new Point(203, 191);
comboBoxBus.Name = "comboBoxBus";
comboBoxBus.Size = new Size(407, 38);
comboBoxBus.TabIndex = 12;
//
// labelBus
//
labelBus.AutoSize = true;
labelBus.Location = new Point(23, 194);
labelBus.Name = "labelBus";
labelBus.Size = new Size(91, 30);
labelBus.TabIndex = 11;
labelBus.Text = "Автобус";
//
// FormWorkReport
//
AutoScaleDimensions = new SizeF(12F, 30F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(646, 466);
Controls.Add(comboBoxBus);
Controls.Add(labelBus);
Controls.Add(comboBoxEmployee);
Controls.Add(buttonMakeReport);
Controls.Add(labelEndDate);
Controls.Add(labelBeginDate);
Controls.Add(labelEmployee);
Controls.Add(dateTimePickerEndDate);
Controls.Add(dateTimePickerBeginDate);
Controls.Add(buttonSelectFilePath);
Controls.Add(textBoxFilePath);
Controls.Add(labelFilePath);
Name = "FormWorkReport";
Text = "Отчёт по работе сотрудников и автобусов";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelFilePath;
private TextBox textBoxFilePath;
private Button buttonSelectFilePath;
private DateTimePicker dateTimePickerBeginDate;
private DateTimePicker dateTimePickerEndDate;
private Label labelEmployee;
private Label labelBeginDate;
private Label labelEndDate;
private Button buttonMakeReport;
private ComboBox comboBoxEmployee;
private ComboBox comboBoxBus;
private Label labelBus;
}
}

View File

@@ -0,0 +1,73 @@
using ProjectPassengerTransportation.Reports;
using ProjectPassengerTransportation.Repositories;
using Unity;
namespace ProjectPassengerTransportation.Forms
{
public partial class FormWorkReport : Form
{
private readonly IUnityContainer _container;
public FormWorkReport(IUnityContainer container, IEmployeeRepository employeeRepository,
IBusRepository busRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
comboBoxEmployee.DataSource = employeeRepository.ReadEmployees();
comboBoxEmployee.DisplayMember = "First_name";
comboBoxEmployee.ValueMember = "Id";
comboBoxBus.DataSource = busRepository.ReadBuses();
comboBoxBus.DisplayMember = "Licence_plate";
comboBoxBus.ValueMember = "Id";
}
private void ButtonSelectFilePath_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
Filter = "Excel Files | *.xlsx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
return;
}
textBoxFilePath.Text = sfd.FileName;
}
private void ButtonMakeReport_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxFilePath.Text))
{
throw new Exception("Отсутствует имя файла для отчета");
}
if (comboBoxEmployee.SelectedIndex < 0 || comboBoxBus.SelectedIndex < 0)
{
throw new Exception("Не выбран сотрудник или автобус");
}
if (dateTimePickerEndDate.Value <= dateTimePickerBeginDate.Value)
{
throw new Exception("Дата начала должна быть раньше даты окончания");
}
if (_container.Resolve<TableReport>().CreateTable(textBoxFilePath.Text,
(int)comboBoxEmployee.SelectedValue!, (int)comboBoxBus.SelectedValue!,
dateTimePickerBeginDate.Value, dateTimePickerEndDate.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

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -2,6 +2,10 @@ using ProjectPassengerTransportation.Repositories.Implementations;
using ProjectPassengerTransportation.Repositories;
using Unity.Lifetime;
using Unity;
using Unity.Microsoft.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Serilog;
namespace ProjectPassengerTransportation
{
@@ -23,13 +27,30 @@ namespace ProjectPassengerTransportation
{
var container = new UnityContainer();
container.AddExtension(new LoggingExtension(CreateLoggerFactory()));
container.RegisterType<IBusRepository, BusRepository>(new TransientLifetimeManager());
container.RegisterType<IEmployeeRepository, EmployeeRepository>(new TransientLifetimeManager());
container.RegisterType<IRouteListRepository, RouteListRepository>(new TransientLifetimeManager());
container.RegisterType<IGoToServiceRepository, GoToServiceRepository>(new TransientLifetimeManager());
container.RegisterType<IStartingShiftRepository, StartingShiftRepository>(new TransientLifetimeManager());
container.RegisterType<IConnectionString, ConnectionString>(new TransientLifetimeManager());
return container;
}
private static LoggerFactory CreateLoggerFactory()
{
var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
return loggerFactory;
}
}
}

View File

@@ -9,7 +9,21 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
@@ -27,4 +41,10 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,48 @@
using Microsoft.Extensions.Logging;
using ProjectPassengerTransportation.Repositories;
namespace ProjectPassengerTransportation.Reports;
public class ChartReport
{
private readonly IGoToServiceRepository _goToServiceRepository;
private readonly ILogger<ChartReport> _logger;
public ChartReport(IGoToServiceRepository goToServiceRepository, ILogger<ChartReport> logger)
{
_goToServiceRepository = goToServiceRepository ?? throw new ArgumentNullException(nameof(goToServiceRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateChart(string filePath, DateTime dateTime)
{
try
{
new PdfBuilder(filePath)
.AddHeader("Тех обслуживание")
.AddPieChart("Количество неисправных элементов", GetData(dateTime))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _goToServiceRepository
.ReadServices()
.Where(x => x.Date.Date == dateTime.Date)
.GroupBy(x => x.Bus_id, (key, group) => new {
Id = key,
Elements = group.Sum(x => (double)x.Broken_elements)
})
.Select(x => (x.Id.ToString(), (double)x.Elements))
.ToList();
}
}

View File

@@ -0,0 +1,90 @@
using Microsoft.Extensions.Logging;
using ProjectPassengerTransportation.Repositories;
namespace ProjectPassengerTransportation.Reports;
public class DocReport
{
private readonly IBusRepository _busRepository;
private readonly IEmployeeRepository _employeeRepository;
private readonly IRouteListRepository _routeListRepository;
private readonly ILogger<DocReport> _logger;
public DocReport(IBusRepository busRepository, IEmployeeRepository employeeRepository,
IRouteListRepository routeListRepository, ILogger<DocReport> logger)
{
_busRepository = busRepository ?? throw new ArgumentNullException(nameof(busRepository));
_employeeRepository = employeeRepository ?? throw new ArgumentNullException(nameof(employeeRepository));
_routeListRepository = routeListRepository ?? throw new ArgumentNullException(nameof(routeListRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateDoc(string filePath, bool includeBuses, bool includeEmployees, bool includeRouteLists)
{
try
{
var builder = new WordBuilder(filePath)
.AddHeader("Документ со справочниками");
if (includeBuses)
{
builder.AddParagraph("Автобусы")
.AddTable([2400, 2400], GetBuses());
}
if (includeEmployees)
{
builder.AddParagraph("Работники")
.AddTable([2400, 2400, 2400], GetEmployess());
}
if (includeRouteLists)
{
builder.AddParagraph("Маршрутные листы")
.AddTable([1200, 1200], GetRouteLists());
}
builder.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetBuses()
{
return [
["Госномер", "Модель"],
.. _busRepository
.ReadBuses()
.Select(x => new string[] { x.Licence_plate, x.Model }),
];
}
private List<string[]> GetEmployess()
{
return [
["Имя", "Фамилия", "Должность"],
.. _employeeRepository
.ReadEmployees()
.Select(x => new string[] { x.First_name, x.Last_name, x.Post.ToString() }),
];
}
private List<string[]> GetRouteLists()
{
return [
["Начало работы", "Конец работы"],
.. _routeListRepository
.ReadRouteLists()
.Select(x => new string[] { x.Route_start.ToString(), x.Route_finish.ToString() }),
];
}
}

View File

@@ -0,0 +1,322 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace ProjectPassengerTransportation.Reports;
public class ExcelBuilder
{
private readonly string _filePath;
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public ExcelBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public ExcelBuilder AddHeader(string header, int startIndex, int count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference =
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public ExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public ExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
{
if (columnsWidths == null || columnsWidths.Length == 0)
{
throw new ArgumentNullException(nameof(columnsWidths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != columnsWidths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
uint counter = 1;
int coef = 2;
_columns.Append(columnsWidths.Select(x => new Column
{
Min = counter,
Max = counter++,
Width = x * coef,
CustomWidth = true
}));
for (var j = 0; j < data.First().Length; ++j)
{
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
for (var i = 1; i < data.Count - 1; ++i)
{
for (var j = 0; j < data[i].Length; ++j)
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public void Build()
{
using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
GenerateStyle(workbookpart);
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
if (_columns.HasChildren)
{
worksheetPart.Worksheet.Append(_columns);
}
worksheetPart.Worksheet.Append(_sheetData);
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист 1"
};
sheets.Append(sheet);
if (_mergeCells.HasChildren)
{
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
}
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2, KnownFonts = BooleanValue.FromBoolean(true) };
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) }
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme()
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
},
Bold = new Bold() { Val = true }
});
workbookStylesPart.Stylesheet.Append(fonts);
// Default Fill
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill()
{
PatternType = new EnumValue<PatternValues>(PatternValues.None)
}
});
workbookStylesPart.Stylesheet.Append(fills);
// Default Border
var borders = new Borders() { Count = 2 };
borders.Append(new Border
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
borders.Append(new Border
{
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin },
RightBorder = new RightBorder() { Style = BorderStyleValues.Thin },
TopBorder = new TopBorder() { Style = BorderStyleValues.Thin },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin },
DiagonalBorder = new DiagonalBorder()
});
workbookStylesPart.Stylesheet.Append(borders);
// Default cell format and a date cell format
var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Right,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorder = 1,
BoldTextWithoutBorder = 2,
BoldTextWithBorder = 3
}
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
{
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex;
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>()
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
private static string GetExcelColumnName(int columnNumber)
{
columnNumber += 1;
int dividend = columnNumber;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
}

View File

@@ -0,0 +1,92 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace ProjectPassengerTransportation.Reports;
public 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()
{
var headerStyle = _document.Styles.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@@ -0,0 +1,76 @@
using Microsoft.Extensions.Logging;
using ProjectPassengerTransportation.Repositories;
namespace ProjectPassengerTransportation.Reports;
public class TableReport
{
private readonly IStartingShiftRepository _startingShiftRepository;
private readonly IGoToServiceRepository _goToServiceRepository;
private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Работник", "Автобус", "Дата", "Отработано часов", "Потрачено на тех обслуживание"];
public TableReport(IStartingShiftRepository startingShiftRepository,
IGoToServiceRepository goToServiceRepository, ILogger<TableReport> logger)
{
_startingShiftRepository = startingShiftRepository ?? throw new ArgumentNullException(nameof(startingShiftRepository));
_goToServiceRepository = goToServiceRepository ?? throw new ArgumentNullException(nameof(goToServiceRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, int employeeId, int busId, DateTime startDate, DateTime endDate)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по работникам и автобусам", 0, 5)
.AddParagraph("за период", 0)
.AddTable([10, 10, 10, 15, 15], GetData(employeeId, busId, startDate, endDate))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetData(int employeeId, int busId, DateTime startDate, DateTime endDate)
{
var data = _startingShiftRepository
.ReadShifts()
.Where(x => x.Date >= startDate && x.Date <= endDate && x.Starting_shift_employees.Any(y => y.Employee_id == employeeId))
.Select(x => new {
EmployeeId = (int?)employeeId,
BusId = (int?)null,
x.Date,
WorkHours = x.Starting_shift_employees.FirstOrDefault(y => y.Employee_id == employeeId)?.Work_time,
Price = (int?)null
})
.Union(_goToServiceRepository
.ReadServices()
.Where(x => x.Date >= startDate && x.Date <= endDate && x.Bus_id == busId)
.Select(x => new {
EmployeeId = (int?)null,
BusId = (int?)busId,
x.Date,
WorkHours = (int?)null,
Price = (int?)x.Price
}))
.OrderBy(x => x.Date);
return new List<string[]>() { item }
.Union(data
.Select(x => new string[] {
x.EmployeeId.ToString() ?? string.Empty,
x.BusId.ToString() ?? string.Empty,
x.Date.ToString(),
x.WorkHours?.ToString() ?? string.Empty,
x.Price?.ToString() ?? string.Empty}))
.Union([["Всего", "", "", data.Sum(x => x.WorkHours ?? 0).ToString(), data.Sum(x => x.Price ?? 0).ToString()]])
.ToList();
}
}

View File

@@ -0,0 +1,107 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
namespace ProjectPassengerTransportation.Reports;
public class WordBuilder
{
private readonly string _filePath;
private readonly Document _document;
private readonly Body _body;
public WordBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_document = new Document();
_body = _document.AppendChild(new Body());
}
public WordBuilder AddHeader(string header)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
var runProperties = run.AppendChild(new RunProperties());
runProperties.AppendChild(new Bold());
run.AppendChild(new Text(header));
return this;
}
public WordBuilder AddParagraph(string text)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text(text));
return this;
}
public WordBuilder AddTable(int[] widths, List<string[]> data)
{
if (widths == null || widths.Length == 0)
{
throw new ArgumentNullException(nameof(widths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != widths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
var table = new Table();
table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 }
)
));
// Заголовок
var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j)
{
tr.Append(new TableCell(
new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
}
table.Append(tr);
// Данные
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()
{
using var wordDocument = WordprocessingDocument.Create(_filePath, WordprocessingDocumentType.Document);
var mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = _document;
}
}

View File

@@ -0,0 +1,6 @@
namespace ProjectPassengerTransportation.Repositories;
public interface IConnectionString
{
public string ConnectionString { get; }
}

View File

@@ -1,32 +1,124 @@
using ProjectPassengerTransportation.Entities;
using ProjectPassengerTransportation.Entities.Enums;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectPassengerTransportation.Entities;
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class BusRepository : IBusRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<BusRepository> _logger;
public BusRepository(IConnectionString connectionString, ILogger<BusRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateBus(Bus bus)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(bus));
}
public void DeleteBus(int id)
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO bus (licence_plate, model)
VALUES (@Licence_plate, @Model)";
connection.Execute(queryInsert, bus);
}
public Bus ReadBusById(int busId)
catch (Exception ex)
{
return Bus.CreateEntity(0, string.Empty, string.Empty);
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
public IEnumerable<Bus> ReadBuses()
{
return [];
}
public void UpdateBus(Bus bus)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(bus));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE bus
SET
licence_plate=@Licence_plate,
model=@Model
WHERE id=@Id";
connection.Execute(queryUpdate, bus);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteBus(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM bus
WHERE id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Bus ReadBusById(int busId)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", busId);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM bus
WHERE id=@busId";
var bus = connection.QueryFirst<Bus>(querySelect, new { busId });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(bus));
return bus;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Bus> ReadBuses()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM bus";
var buses = connection.Query<Bus>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(buses));
return buses;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@@ -0,0 +1,6 @@
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class ConnectionString : IConnectionString
{
string IConnectionString.ConnectionString => "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=passanger_transportation";
}

View File

@@ -1,32 +1,125 @@
using ProjectPassengerTransportation.Entities;
using ProjectPassengerTransportation.Entities.Enums;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectPassengerTransportation.Entities;
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class EmployeeRepository : IEmployeeRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<EmployeeRepository> _logger;
public EmployeeRepository(IConnectionString connectionString, ILogger<EmployeeRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateEmployee(Employee employee)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(employee));
}
public void DeleteEmployee(int id)
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO employee (first_name, last_name, post)
VALUES (@First_name, @Last_name, @Post)";
connection.Execute(queryInsert, employee);
}
public Employee ReadEmployeeById(int employeeId)
catch (Exception ex)
{
return Employee.CreateEntity(0, string.Empty, string.Empty, EmployeePost.None);
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
public IEnumerable<Employee> ReadEmployees()
{
return [];
}
public void UpdateEmployee(Employee employee)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(employee));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE employee
SET
first_name=@First_name,
last_name=@Last_name,
post=@Post
WHERE id=@Id";
connection.Execute(queryUpdate, employee);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteEmployee(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM employee
WHERE id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Employee ReadEmployeeById(int employeeId)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", employeeId);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM employee
WHERE id=@employeeId";
var employee = connection.QueryFirst<Employee>(querySelect, new { employeeId });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(employee));
return employee;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Employee> ReadEmployees()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM employee";
var employees = connection.Query<Employee>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(employees));
return employees;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@@ -1,22 +1,80 @@
using ProjectPassengerTransportation.Entities;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectPassengerTransportation.Entities;
using ProjectPassengerTransportation.Entities.Enums;
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class GoToServiceRepository : IGoToServiceRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<GoToServiceRepository> _logger;
public GoToServiceRepository(IConnectionString connectionString, ILogger<GoToServiceRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateGoToService(GoToService goToService)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(goToService));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO go_to_service (date, price, bus_id, broken_elements)
VALUES (@Date, @Price, @Bus_id, @Broken_elements)";
connection.Execute(queryInsert, goToService);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteGoToService(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
}
public IEnumerable<GoToService> ReadServices(DateTime? dateFrom = null, DateTime? dateTo = null, BrokenElements BrokenElements = BrokenElements.None, int? price = null, int? busId = null)
try
{
return [];
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM go_to_service
WHERE id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public IEnumerable<GoToService> ReadServices(DateTime? dateFrom = null, DateTime? dateTo = null,
BrokenElements BrokenElements = BrokenElements.None, int? price = null, int? busId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM go_to_service";
var services = connection.Query<GoToService>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(services));
return services;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@@ -1,31 +1,125 @@
using ProjectPassengerTransportation.Entities;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectPassengerTransportation.Entities;
using System;
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class RouteListRepository : IRouteListRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<RouteListRepository> _logger;
public RouteListRepository(IConnectionString connectionString, ILogger<RouteListRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateRouteList(RouteList routeList)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(routeList));
}
public void DeleteRouteList(int id)
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO route_list (route_start, route_finish)
VALUES (@Route_start, @Route_finish)";
connection.Execute(queryInsert, routeList);
}
public RouteList ReadRouteListById(int routeListId)
catch (Exception ex)
{
return RouteList.CreateEntity(0, new TimeOnly(0, 0), new TimeOnly(0, 0));
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
public IEnumerable<RouteList> ReadRouteLists()
{
return [];
}
public void UpdateRouteList(RouteList routeList)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(routeList));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE route_list
SET
route_start=@Route_start,
route_finish=@Route_finish
WHERE id=@Id";
connection.Execute(queryUpdate, routeList);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteRouteList(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM route_list
WHERE id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public RouteList ReadRouteListById(int routeListId)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", routeListId);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM route_list
WHERE id=@routeListId";
var routeList = connection.QueryFirst<RouteList>(querySelect, new { routeListId });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(routeList));
return routeList;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<RouteList> ReadRouteLists()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM route_list";
var routeLists = connection.Query<RouteList>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(routeLists));
return routeLists;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@@ -1,17 +1,74 @@
using ProjectPassengerTransportation.Entities;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectPassengerTransportation.Entities;
namespace ProjectPassengerTransportation.Repositories.Implementations;
public class StartingShiftRepository : IStartingShiftRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<StartingShiftRepository> _logger;
public StartingShiftRepository(IConnectionString connectionString, ILogger<StartingShiftRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateStartingShift(StartingShift startingShift)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(startingShift));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryInsert = @"
INSERT INTO starting_shift (date, route_list_id, bus_id)
VALUES (@Date, @Route_list_id, @Bus_id);
SELECT MAX(Id) FROM starting_shift";
var starting_shift_id = connection.QueryFirst<int>(queryInsert, startingShift, transaction);
var querySubInsert = @"
INSERT INTO starting_shift_employee (starting_shift_id, employee_id, work_time)
VALUES (@Starting_shift_id, @Employee_id, @Work_time)";
foreach (var elem in startingShift.Starting_shift_employees)
{
connection.Execute(querySubInsert, new { starting_shift_id, elem.Employee_id, elem.Work_time }, transaction);
}
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public IEnumerable<StartingShift> ReadShifts(DateTime? dateFrom = null, DateTime? dateTo = null,
int? routeListId = null, int? employeeId = null, int? busId = null)
{
return [];
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT sse.starting_shift_id, ss.date, ss.route_list_id, ss.bus_id, sse.employee_id, sse.work_time FROM starting_shift ss
INNER JOIN starting_shift_employee sse ON sse.starting_shift_id = ss.id";
var startingShifts = connection.Query<TempStartingShiftEmployee>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(startingShifts));
return startingShifts.GroupBy(x => x.Starting_shift_id, y => y,
(key, value) => StartingShift.CreateOperation(value.First(),
value.Select(z => StartingShiftEmployee.CreateElement(0, z.Employee_id, z.Work_time)))).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@@ -0,0 +1,15 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/passenger_transportation_log.txt",
"rollingInterval": "Day"
}
}
]
}
}

BIN
docAll1.docx Normal file

Binary file not shown.

BIN
docBuses1.docx Normal file

Binary file not shown.