Compare commits

...

35 Commits

Author SHA1 Message Date
2edfb98b6a fix excel report with sum 2024-12-24 14:16:39 -08:00
bce2e9612a final version, reports with names, loading many-to-many entity 2024-12-24 15:43:04 +04:00
c62dd35f93 add all except ContractRepository logic 2024-12-09 02:55:48 -08:00
8ff6da0fe1 set fullname instead of id, set not visible id and fullname 2024-12-09 01:13:23 -08:00
a2123b8840 fix Service property in Contract entity 2024-12-09 00:52:36 -08:00
4659147c9d Merge branch 'LabWork_3' into LabWork_4 2024-12-08 23:56:46 -08:00
ef90252bfa fix styles and add todo 2024-12-08 23:56:11 -08:00
9763ab2e40 add desplay names and set browsable for entities. have not touched other dirs 2024-12-09 04:20:44 +04:00
d644ef51a2 make possible to load services list 2024-12-08 15:14:59 -08:00
cf54488e71 add TODOs, bold font and solid borders 2024-12-08 13:48:29 -08:00
88902c09db fix label in FormServicesDistributionReport 2024-12-08 12:09:48 -08:00
f176ec85db add all, except work with many-to-may repository 2024-12-09 00:02:54 +04:00
e955c5cb6d the second fix of ReadContracts log message 2024-12-08 21:19:45 +04:00
d79c14c0ee fix ReadContracts log message 2024-12-08 21:18:16 +04:00
d446aae8eb fix ReadContracts log message 2024-12-08 21:16:46 +04:00
e6340b0a54 merge LabWork_1 to LabWork_2 for sync 2024-12-05 06:29:53 +04:00
a82cf75e14 last little fix (maybe not last) 2024-12-05 06:27:56 +04:00
413256e850 final changes 2024-12-05 06:23:35 +04:00
aeefa6ed40 merge some changes from lab 1 2024-11-30 16:38:23 +04:00
4e1acff83c clear code, rename russian names 2024-11-30 16:34:45 +04:00
ad6d1d1bcb clear code, rename russian names 2024-11-30 16:31:42 +04:00
89b3fd799c clear code, rename russian names 2024-11-30 16:15:44 +04:00
7d57c72997 final (yeeeaaah) 2024-11-25 02:45:43 -08:00
ca303c678b update with positive changes 2024-11-25 01:51:22 -08:00
8b6c4644c1 add REAL many-to-many relationship (come back) 2024-11-25 01:34:17 -08:00
dbe7980c2f fix customereditorreview issue 2024-11-25 00:29:54 -08:00
4a12f3b1e4 almost done, except customerexecutorreview... 2024-11-25 11:10:38 +04:00
1da0a7d90c fix forms, restruct entities 2024-11-25 08:36:10 +04:00
e2106e58e6 fix forms, restruct entities 2024-11-25 07:56:26 +04:00
1fc85814dc set connection string, work on repositories continues 2024-11-25 05:51:05 +04:00
912f547d32 add extensions, add logger, add example logic 2024-11-25 04:25:15 +04:00
a57d00ba3e rename function args 2024-11-25 03:12:16 +04:00
61792d9116 remove useless entity, make "review" entity "many-to-many", add DataGridView to contract form 2024-11-25 02:30:29 +04:00
780993b244 add all forms, fixed issues 2024-11-11 02:53:10 -08:00
e5f4eda60a add full logic, missed few forms 2024-11-11 11:02:06 +04:00
80 changed files with 6572 additions and 50 deletions

View File

@ -0,0 +1,68 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class Contract
{
public int Id { get; private set; }
[Browsable(false)]
public int CustomerID { get; private set; }
[Browsable(false)]
public int ExecutorID { get; private set; }
[DisplayName("Заказчик")]
public string CustomerName { get; private set; } = string.Empty;
[Browsable(false)]
public ExecutorPost ExecutorPost { get; private set; }
[Browsable(false)]
public string ExecutorName { get; private set; } = string.Empty;
[DisplayName("Исполнитель")]
public string ExecutorFullName => $"{ExecutorPost} {ExecutorName}";
[DisplayName("Тип контракта")]
public ContractCategory Category { get; private set; }
[DisplayName("Дата заключения")]
public DateTime ConclusionDate { get; private set; }
[DisplayName("Дата окончания")]
public DateTime Deadline { get; private set; }
[DisplayName("Сумма платежа")]
public int PaymentAmount { get; private set; }
[DisplayName("Услуги")]
public string Service => Services != null ? string.Join(", ", Services.Select(x => $"{x.Description}")) : string.Empty;
[Browsable(false)]
public IEnumerable<Service> Services { get; private set; } = [];
public static Contract CreateEntity(int id, int customerID, int executorID,
ContractCategory category, DateTime deadline,
int paymentAmount, IEnumerable<Service> services)
{
return new Contract
{
Id = id,
CustomerID = customerID,
ExecutorID = executorID,
Category = category,
ConclusionDate = DateTime.Now,
Deadline = deadline,
PaymentAmount = paymentAmount,
Services = services
};
}
public void SetServices(IEnumerable<Service> services)
{
if (services != null && services.Any())
Services = services;
}
}

View File

@ -0,0 +1,30 @@
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class Customer
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Контакты")]
public string Contact { get; private set; } = string.Empty;
public string FullName => $"{Name} {Contact}";
[DisplayName("Адрес")]
public string Address { get; private set; } = string.Empty;
public static Customer CreateEntity(int id, string name, string contact, string address)
{
return new Customer
{
Id = id,
Name = name ?? String.Empty,
Contact = contact ?? String.Empty,
Address = address ?? String.Empty
};
}
}

View File

@ -0,0 +1,45 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class CustomerExecutorReview
{
public int Id { get; private set; }
[Browsable(false)]
public int CustomerId { get; private set; }
[Browsable(false)]
public int ExecutorId { get; private set; }
[DisplayName("Заказчик")]
public string CustomerName { get; private set; } = string.Empty;
[Browsable(false)]
public ExecutorPost ExecutorPost { get; private set; }
[Browsable(false)]
public string ExecutorName { get; private set; } = string.Empty;
[DisplayName("Исполнитель")]
public string ExecutorFullName => $"{ExecutorPost} {ExecutorName}";
[DisplayName("Отзыв")]
public string Review { get; private set; } = string.Empty;
[DisplayName("Оценка")]
public int Grade { get; private set; }
public static CustomerExecutorReview CreateElement(int id, int customerId, int executorId, string review, int grade)
{
return new CustomerExecutorReview
{
Id = id,
CustomerId = customerId,
ExecutorId = executorId,
Review = review ?? String.Empty,
Grade = grade
};
}
}

View File

@ -0,0 +1,11 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
[Flags]
public enum ContractCategory
{
None = 0,
Support = 1,
Development = 2
}

View File

@ -0,0 +1,14 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
public enum ExecutorPost
{
None = 0,
Junior = 1,
Middle = 2,
Senior = 3,
TeamLead = 4
}

View File

@ -0,0 +1,27 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class Executor
{
public int Id { get; private set; }
[DisplayName("Имя")]
public string Name { get; private set; } = string.Empty;
[DisplayName("Должность")]
public ExecutorPost Post { get; private set; }
public string FullName => $"{Post} {Name}";
public static Executor CreateEntity(int id, string name, ExecutorPost post)
{
return new Executor
{
Id = id,
Name = name ?? String.Empty,
Post = post
};
}
}

View File

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class Service
{
public int Id { get; private set; }
[DisplayName("Описание услуги")]
public string Description { get; private set; } = string.Empty;
public static Service CreateEntity(int id, string description)
{
return new Service
{
Id = id,
Description = description
};
}
}

View File

@ -0,0 +1,27 @@
using System.ComponentModel;
namespace PIbd_23_Gutorov_I.A._IT_Company.Entities;
public class ServiceContract
{
public int Id { get; private set; }
[Browsable(false)]
public int ServiceId { get; private set; }
[Browsable(false)]
public int ContractId { get; private set; }
[DisplayName("Описание услуги")]
public string ServiceDescription { get; private set; } = string.Empty;
public static ServiceContract CreateElement(int id, int serviceId, int contractId)
{
return new ServiceContract
{
Id = id,
ContractId = contractId,
ServiceId = serviceId
};
}
}

View File

@ -1,39 +0,0 @@
namespace PIbd_23_Gutorov_I.A._IT_Company
{
partial class Form1
{
/// <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()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace PIbd_23_Gutorov_I.A._IT_Company
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,168 @@
namespace PIbd_23_Gutorov_I.A._IT_Company
{
partial class FormItCompany
{
/// <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()
{
menuStrip = new MenuStrip();
EntitiesToolStripMenuItem = new ToolStripMenuItem();
CustomersToolStripMenuItem = new ToolStripMenuItem();
ExecutorsToolStripMenuItem = new ToolStripMenuItem();
ServicesToolStripMenuItem = new ToolStripMenuItem();
OperationsToolStripMenuItem = new ToolStripMenuItem();
CustomerContractReviewsToolStripMenuItem = new ToolStripMenuItem();
ContractsToolStripMenuItem = new ToolStripMenuItem();
ReportsToolStripMenuItem = new ToolStripMenuItem();
DirectoryReportToolStripMenuItem = new ToolStripMenuItem();
ContractReportToolStripMenuItem = new ToolStripMenuItem();
ServiceDistributionToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout();
SuspendLayout();
//
// menuStrip
//
menuStrip.Items.AddRange(new ToolStripItem[] { EntitiesToolStripMenuItem, OperationsToolStripMenuItem, ReportsToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(734, 24);
menuStrip.TabIndex = 0;
menuStrip.Text = "menuStrip1";
//
// EntitiesToolStripMenuItem
//
EntitiesToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { CustomersToolStripMenuItem, ExecutorsToolStripMenuItem, ServicesToolStripMenuItem });
EntitiesToolStripMenuItem.Name = "EntitiesToolStripMenuItem";
EntitiesToolStripMenuItem.Size = new Size(94, 20);
EntitiesToolStripMenuItem.Text = "Справочники";
//
// CustomersToolStripMenuItem
//
CustomersToolStripMenuItem.Name = "CustomersToolStripMenuItem";
CustomersToolStripMenuItem.Size = new Size(149, 22);
CustomersToolStripMenuItem.Text = "Заказчики";
CustomersToolStripMenuItem.Click += CustomersToolStripMenuItem_Click;
//
// ExecutorsToolStripMenuItem
//
ExecutorsToolStripMenuItem.Name = "ExecutorsToolStripMenuItem";
ExecutorsToolStripMenuItem.Size = new Size(149, 22);
ExecutorsToolStripMenuItem.Text = "Исполнители";
ExecutorsToolStripMenuItem.Click += ExecutorsToolStripMenuItem_Click;
//
// ServicesToolStripMenuItem
//
ServicesToolStripMenuItem.Name = "ServicesToolStripMenuItem";
ServicesToolStripMenuItem.Size = new Size(149, 22);
ServicesToolStripMenuItem.Text = "Услуги";
ServicesToolStripMenuItem.Click += ServicesToolStripMenuItem_Click;
//
// OperationsToolStripMenuItem
//
OperationsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { CustomerContractReviewsToolStripMenuItem, ContractsToolStripMenuItem });
OperationsToolStripMenuItem.Name = "OperationsToolStripMenuItem";
OperationsToolStripMenuItem.Size = new Size(75, 20);
OperationsToolStripMenuItem.Text = "Операции";
//
// CustomerContractReviewsToolStripMenuItem
//
CustomerContractReviewsToolStripMenuItem.Name = "CustomerContractReviewsToolStripMenuItem";
CustomerContractReviewsToolStripMenuItem.Size = new Size(181, 22);
CustomerContractReviewsToolStripMenuItem.Text = "Отзывы заказчиков";
CustomerContractReviewsToolStripMenuItem.Click += CustomerContractReviewsToolStripMenuItem_Click;
//
// ContractsToolStripMenuItem
//
ContractsToolStripMenuItem.Name = "ContractsToolStripMenuItem";
ContractsToolStripMenuItem.Size = new Size(181, 22);
ContractsToolStripMenuItem.Text = "Контракты";
ContractsToolStripMenuItem.Click += ContractsToolStripMenuItem_Click;
//
// ReportsToolStripMenuItem
//
ReportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DirectoryReportToolStripMenuItem, ContractReportToolStripMenuItem, ServiceDistributionToolStripMenuItem });
ReportsToolStripMenuItem.Name = "ReportsToolStripMenuItem";
ReportsToolStripMenuItem.Size = new Size(60, 20);
ReportsToolStripMenuItem.Text = "Отчеты";
//
// DirectoryReportToolStripMenuItem
//
DirectoryReportToolStripMenuItem.Name = "DirectoryReportToolStripMenuItem";
DirectoryReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W;
DirectoryReportToolStripMenuItem.Size = new Size(328, 22);
DirectoryReportToolStripMenuItem.Text = "Документ со справочниками";
DirectoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click;
//
// ContractReportToolStripMenuItem
//
ContractReportToolStripMenuItem.Name = "ContractReportToolStripMenuItem";
ContractReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.E;
ContractReportToolStripMenuItem.Size = new Size(328, 22);
ContractReportToolStripMenuItem.Text = "Заключения и исполнения контрактов";
ContractReportToolStripMenuItem.Click += ContractReportToolStripMenuItem_Click;
//
// ServiceDistributionToolStripMenuItem
//
ServiceDistributionToolStripMenuItem.Name = "ServiceDistributionToolStripMenuItem";
ServiceDistributionToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.P;
ServiceDistributionToolStripMenuItem.Size = new Size(328, 22);
ServiceDistributionToolStripMenuItem.Text = "Распределение услуг";
ServiceDistributionToolStripMenuItem.Click += ServiceDistributionToolStripMenuItem_Click;
//
// FormItCompany
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
BackgroundImage = Properties.Resources.modern_equipped_computer_lab;
BackgroundImageLayout = ImageLayout.Stretch;
ClientSize = new Size(734, 461);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormItCompany";
StartPosition = FormStartPosition.CenterScreen;
Text = "IT-компания";
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem EntitiesToolStripMenuItem;
private ToolStripMenuItem CustomersToolStripMenuItem;
private ToolStripMenuItem ExecutorsToolStripMenuItem;
private ToolStripMenuItem OperationsToolStripMenuItem;
private ToolStripMenuItem ReportsToolStripMenuItem;
private ToolStripMenuItem CustomerContractReviewsToolStripMenuItem;
private ToolStripMenuItem ContractsToolStripMenuItem;
private ToolStripMenuItem ServicesToolStripMenuItem;
private ToolStripMenuItem DirectoryReportToolStripMenuItem;
private ToolStripMenuItem ContractReportToolStripMenuItem;
private ToolStripMenuItem ServiceDistributionToolStripMenuItem;
}
}

View File

@ -0,0 +1,112 @@
using PIbd_23_Gutorov_I.A._IT_Company.Forms;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company
{
public partial class FormItCompany : Form
{
private readonly IUnityContainer _container;
public FormItCompany(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void CustomersToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormCustomers>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ExecutorsToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormExecutors>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ContractsToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormContracts>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CustomerContractReviewsToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormCustomerExecutorReviews>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ServicesToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormServices>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DirectoryReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormDirectoryReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ContractReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormContractReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ServiceDistributionToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormServiceDistributionReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,123 @@
<?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>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,240 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormContract
{
/// <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()
{
checkedListBoxContractCategory = new CheckedListBox();
dateTimePickerContractDeadline = new DateTimePicker();
numericUpDownContractPaymentAmount = new NumericUpDown();
buttonCancel = new Button();
buttonSave = new Button();
labelContractCustomerId = new Label();
labelContractExecutorId = new Label();
labelContractCategory = new Label();
comboBoxContractCustomerId = new ComboBox();
comboBoxContractExecutorId = new ComboBox();
labelContractDeadline = new Label();
labelContractPaymentAmount = new Label();
dataGridViewServices = new DataGridView();
ColumnServiceDescription = new DataGridViewComboBoxColumn();
groupBox = new GroupBox();
((System.ComponentModel.ISupportInitialize)numericUpDownContractPaymentAmount).BeginInit();
((System.ComponentModel.ISupportInitialize)dataGridViewServices).BeginInit();
groupBox.SuspendLayout();
SuspendLayout();
//
// checkedListBoxContractCategory
//
checkedListBoxContractCategory.FormattingEnabled = true;
checkedListBoxContractCategory.Location = new Point(169, 64);
checkedListBoxContractCategory.Name = "checkedListBoxContractCategory";
checkedListBoxContractCategory.Size = new Size(202, 40);
checkedListBoxContractCategory.TabIndex = 0;
//
// dateTimePickerContractDeadline
//
dateTimePickerContractDeadline.Location = new Point(169, 110);
dateTimePickerContractDeadline.Name = "dateTimePickerContractDeadline";
dateTimePickerContractDeadline.Size = new Size(202, 23);
dateTimePickerContractDeadline.TabIndex = 1;
//
// numericUpDownContractPaymentAmount
//
numericUpDownContractPaymentAmount.Increment = new decimal(new int[] { 100000, 0, 0, 0 });
numericUpDownContractPaymentAmount.Location = new Point(169, 139);
numericUpDownContractPaymentAmount.Maximum = new decimal(new int[] { 1000000000, 0, 0, 0 });
numericUpDownContractPaymentAmount.Name = "numericUpDownContractPaymentAmount";
numericUpDownContractPaymentAmount.Size = new Size(202, 23);
numericUpDownContractPaymentAmount.TabIndex = 2;
//
// buttonCancel
//
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
buttonCancel.Location = new Point(12, 469);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(358, 23);
buttonCancel.TabIndex = 9;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonSave
//
buttonSave.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
buttonSave.Location = new Point(12, 440);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(358, 23);
buttonSave.TabIndex = 8;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// labelContractCustomerId
//
labelContractCustomerId.AutoSize = true;
labelContractCustomerId.Location = new Point(12, 9);
labelContractCustomerId.Name = "labelContractCustomerId";
labelContractCustomerId.Size = new Size(60, 15);
labelContractCustomerId.TabIndex = 10;
labelContractCustomerId.Text = "Заказчик:";
//
// labelContractExecutorId
//
labelContractExecutorId.AutoSize = true;
labelContractExecutorId.Location = new Point(12, 38);
labelContractExecutorId.Name = "labelContractExecutorId";
labelContractExecutorId.Size = new Size(84, 15);
labelContractExecutorId.TabIndex = 11;
labelContractExecutorId.Text = "Исполнитель:";
//
// labelContractCategory
//
labelContractCategory.AutoSize = true;
labelContractCategory.Location = new Point(12, 64);
labelContractCategory.Name = "labelContractCategory";
labelContractCategory.Size = new Size(66, 15);
labelContractCategory.TabIndex = 12;
labelContractCategory.Text = "Категория:";
//
// comboBoxContractCustomerId
//
comboBoxContractCustomerId.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxContractCustomerId.FormattingEnabled = true;
comboBoxContractCustomerId.Location = new Point(169, 6);
comboBoxContractCustomerId.Name = "comboBoxContractCustomerId";
comboBoxContractCustomerId.Size = new Size(202, 23);
comboBoxContractCustomerId.TabIndex = 13;
//
// comboBoxContractExecutorId
//
comboBoxContractExecutorId.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxContractExecutorId.FormattingEnabled = true;
comboBoxContractExecutorId.Location = new Point(169, 35);
comboBoxContractExecutorId.Name = "comboBoxContractExecutorId";
comboBoxContractExecutorId.Size = new Size(202, 23);
comboBoxContractExecutorId.TabIndex = 14;
//
// labelContractDeadline
//
labelContractDeadline.AutoSize = true;
labelContractDeadline.Location = new Point(12, 116);
labelContractDeadline.Name = "labelContractDeadline";
labelContractDeadline.Size = new Size(110, 15);
labelContractDeadline.TabIndex = 15;
labelContractDeadline.Text = "Срок выполнения:";
//
// labelContractPaymentAmount
//
labelContractPaymentAmount.AutoSize = true;
labelContractPaymentAmount.Location = new Point(12, 141);
labelContractPaymentAmount.Name = "labelContractPaymentAmount";
labelContractPaymentAmount.Size = new Size(97, 15);
labelContractPaymentAmount.TabIndex = 16;
labelContractPaymentAmount.Text = "Сумма платежа:";
//
// dataGridViewServices
//
dataGridViewServices.AllowUserToResizeColumns = false;
dataGridViewServices.AllowUserToResizeRows = false;
dataGridViewServices.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewServices.Columns.AddRange(new DataGridViewColumn[] { ColumnServiceDescription });
dataGridViewServices.Dock = DockStyle.Fill;
dataGridViewServices.Location = new Point(3, 19);
dataGridViewServices.MultiSelect = false;
dataGridViewServices.Name = "dataGridViewServices";
dataGridViewServices.RowHeadersVisible = false;
dataGridViewServices.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewServices.Size = new Size(352, 244);
dataGridViewServices.TabIndex = 17;
//
// ColumnServiceDescription
//
ColumnServiceDescription.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
ColumnServiceDescription.HeaderText = "Услуга";
ColumnServiceDescription.Name = "ColumnServiceDescription";
ColumnServiceDescription.Resizable = DataGridViewTriState.True;
ColumnServiceDescription.SortMode = DataGridViewColumnSortMode.Automatic;
//
// groupBox
//
groupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
groupBox.Controls.Add(dataGridViewServices);
groupBox.Location = new Point(12, 168);
groupBox.Name = "groupBox";
groupBox.Size = new Size(358, 266);
groupBox.TabIndex = 18;
groupBox.TabStop = false;
groupBox.Text = "Услуги:";
//
// FormContract
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(382, 502);
Controls.Add(groupBox);
Controls.Add(labelContractPaymentAmount);
Controls.Add(labelContractDeadline);
Controls.Add(comboBoxContractExecutorId);
Controls.Add(comboBoxContractCustomerId);
Controls.Add(labelContractCategory);
Controls.Add(labelContractExecutorId);
Controls.Add(labelContractCustomerId);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(numericUpDownContractPaymentAmount);
Controls.Add(dateTimePickerContractDeadline);
Controls.Add(checkedListBoxContractCategory);
Name = "FormContract";
StartPosition = FormStartPosition.CenterParent;
Text = "Контракт";
((System.ComponentModel.ISupportInitialize)numericUpDownContractPaymentAmount).EndInit();
((System.ComponentModel.ISupportInitialize)dataGridViewServices).EndInit();
groupBox.ResumeLayout(false);
ResumeLayout(false);
PerformLayout();
}
#endregion
private CheckedListBox checkedListBoxContractCategory;
private DateTimePicker dateTimePickerContractDeadline;
private NumericUpDown numericUpDownContractPaymentAmount;
private Button buttonCancel;
private Button buttonSave;
private Label labelContractCustomerId;
private Label labelContractExecutorId;
private Label labelContractCategory;
private ComboBox comboBoxContractCustomerId;
private ComboBox comboBoxContractExecutorId;
private Label labelContractDeadline;
private Label labelContractPaymentAmount;
private DataGridView dataGridViewServices;
private GroupBox groupBox;
private DataGridViewComboBoxColumn ColumnServiceDescription;
}
}

View File

@ -0,0 +1,86 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormContract : Form
{
private readonly IContractRepository _contractRepository;
public FormContract(IContractRepository contractRepository, ICustomerRepository customerRepository,
IExecutorRepository executorRepository, IServiceRepository serviceRepository)
{
InitializeComponent();
_contractRepository = contractRepository ?? throw new ArgumentNullException(nameof(contractRepository));
comboBoxContractCustomerId.DataSource = customerRepository.ReadCustomers();
comboBoxContractCustomerId.DisplayMember = "FullName";
comboBoxContractCustomerId.ValueMember = "Id";
comboBoxContractExecutorId.DataSource = executorRepository.ReadExecutors();
comboBoxContractExecutorId.DisplayMember = "FullName";
comboBoxContractExecutorId.ValueMember = "Id";
ColumnServiceDescription.DataSource = serviceRepository.ReadServices();
ColumnServiceDescription.DisplayMember = "Description";
ColumnServiceDescription.ValueMember = "Id";
foreach (var elem in Enum.GetValues(typeof(ContractCategory)))
{
checkedListBoxContractCategory.Items.Add(elem);
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (checkedListBoxContractCategory.CheckedItems.Count == 0 ||
comboBoxContractCustomerId.SelectedIndex < 0 ||
comboBoxContractExecutorId.SelectedIndex < 0)
{
throw new Exception("Имеются незаполненные поля");
}
_contractRepository.CreateContract(CreateContract(0));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Contract CreateContract(int id)
{
ContractCategory contractCategory = ContractCategory.None;
foreach (var elem in checkedListBoxContractCategory.CheckedItems)
{
contractCategory |= (ContractCategory)elem;
}
return Contract.CreateEntity(id, (int)comboBoxContractCustomerId.SelectedValue!,
(int)comboBoxContractExecutorId.SelectedValue!, contractCategory,
dateTimePickerContractDeadline.Value, Convert.ToInt32(numericUpDownContractPaymentAmount.Value),
CreateListServicesFromDataGrid());
}
private List<Service> CreateListServicesFromDataGrid()
{
var list = new List<Service>();
foreach (DataGridViewRow row in dataGridViewServices.Rows)
if (row.Cells["ColumnServiceDescription"].Value != null)
list.Add(Service.CreateEntity(Convert.ToInt32(row.Cells["ColumnServiceDescription"].Value),
Convert.ToString(row.Cells["ColumnServiceDescription"])!));
return list.GroupBy(x => x.Id)
.Select(x => x.First())
.ToList();
}
}
}

View File

@ -0,0 +1,123 @@
<?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>
<metadata name="ColumnServiceDescription.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,164 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormContractReport
{
/// <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();
labelCustomerId = new Label();
labelStartDate = new Label();
labelEndDate = new Label();
dateTimePickerStartDate = new DateTimePicker();
dateTimePickerEndDate = new DateTimePicker();
comboBoxCutomerId = new ComboBox();
textBoxFilePath = new TextBox();
buttonSelectFilePath = new Button();
buttonMakeReport = new Button();
SuspendLayout();
//
// labelFilePath
//
labelFilePath.AutoSize = true;
labelFilePath.Location = new Point(12, 15);
labelFilePath.Name = "labelFilePath";
labelFilePath.Size = new Size(90, 15);
labelFilePath.TabIndex = 0;
labelFilePath.Text = "Путь до файла:";
//
// labelCustomerId
//
labelCustomerId.AutoSize = true;
labelCustomerId.Location = new Point(12, 44);
labelCustomerId.Name = "labelCustomerId";
labelCustomerId.Size = new Size(60, 15);
labelCustomerId.TabIndex = 1;
labelCustomerId.Text = "Заказчик:";
//
// labelStartDate
//
labelStartDate.AutoSize = true;
labelStartDate.Location = new Point(12, 70);
labelStartDate.Name = "labelStartDate";
labelStartDate.Size = new Size(77, 15);
labelStartDate.TabIndex = 2;
labelStartDate.Text = "Дата начала:";
//
// labelEndDate
//
labelEndDate.AutoSize = true;
labelEndDate.Location = new Point(12, 99);
labelEndDate.Name = "labelEndDate";
labelEndDate.Size = new Size(71, 15);
labelEndDate.TabIndex = 3;
labelEndDate.Text = "Дата конца:";
//
// dateTimePickerStartDate
//
dateTimePickerStartDate.Location = new Point(131, 70);
dateTimePickerStartDate.Name = "dateTimePickerStartDate";
dateTimePickerStartDate.Size = new Size(200, 23);
dateTimePickerStartDate.TabIndex = 4;
//
// dateTimePickerEndDate
//
dateTimePickerEndDate.Location = new Point(131, 99);
dateTimePickerEndDate.Name = "dateTimePickerEndDate";
dateTimePickerEndDate.Size = new Size(200, 23);
dateTimePickerEndDate.TabIndex = 5;
//
// comboBoxCutomerId
//
comboBoxCutomerId.FormattingEnabled = true;
comboBoxCutomerId.Location = new Point(131, 41);
comboBoxCutomerId.Name = "comboBoxCutomerId";
comboBoxCutomerId.Size = new Size(200, 23);
comboBoxCutomerId.TabIndex = 6;
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(131, 12);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.ReadOnly = true;
textBoxFilePath.Size = new Size(171, 23);
textBoxFilePath.TabIndex = 7;
//
// buttonSelectFilePath
//
buttonSelectFilePath.Location = new Point(308, 12);
buttonSelectFilePath.Name = "buttonSelectFilePath";
buttonSelectFilePath.Size = new Size(23, 23);
buttonSelectFilePath.TabIndex = 8;
buttonSelectFilePath.Text = "..";
buttonSelectFilePath.UseVisualStyleBackColor = true;
buttonSelectFilePath.Click += ButtonSelectFilePath_Click;
//
// buttonMakeReport
//
buttonMakeReport.Location = new Point(12, 128);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(319, 23);
buttonMakeReport.TabIndex = 9;
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = true;
buttonMakeReport.Click += ButtonMakeReport_Click;
//
// FormContractReport
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(347, 165);
Controls.Add(buttonMakeReport);
Controls.Add(buttonSelectFilePath);
Controls.Add(textBoxFilePath);
Controls.Add(comboBoxCutomerId);
Controls.Add(dateTimePickerEndDate);
Controls.Add(dateTimePickerStartDate);
Controls.Add(labelEndDate);
Controls.Add(labelStartDate);
Controls.Add(labelCustomerId);
Controls.Add(labelFilePath);
Name = "FormContractReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Отчет по контрактам";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelFilePath;
private Label labelCustomerId;
private Label labelStartDate;
private Label labelEndDate;
private DateTimePicker dateTimePickerStartDate;
private DateTimePicker dateTimePickerEndDate;
private ComboBox comboBoxCutomerId;
private TextBox textBoxFilePath;
private Button buttonSelectFilePath;
private Button buttonMakeReport;
}
}

View File

@ -0,0 +1,64 @@
using PIbd_23_Gutorov_I.A._IT_Company.Reports;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormContractReport : Form
{
private readonly IUnityContainer _container;
public FormContractReport(IUnityContainer container, ICustomerRepository customerRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
comboBoxCutomerId.DataSource = customerRepository.ReadCustomers();
comboBoxCutomerId.DisplayMember = "FullName";
comboBoxCutomerId.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 (comboBoxCutomerId.SelectedIndex < 0)
throw new Exception("Не выбран корм");
if (dateTimePickerEndDate.Value <= dateTimePickerStartDate.Value)
throw new Exception("Дата начала должна быть раньше даты окончания");
if (_container.Resolve<TableReport>().CreateTable(textBoxFilePath.Text,
(int)comboBoxCutomerId.SelectedValue!,
dateTimePickerStartDate.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

@ -0,0 +1,112 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormContracts
{
/// <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()
{
dataGridViewData = new DataGridView();
panel = new Panel();
buttonDel = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
panel.SuspendLayout();
SuspendLayout();
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(677, 450);
dataGridViewData.TabIndex = 5;
//
// panel
//
panel.Controls.Add(buttonDel);
panel.Controls.Add(buttonAdd);
panel.Dock = DockStyle.Right;
panel.Location = new Point(677, 0);
panel.Name = "panel";
panel.Size = new Size(123, 450);
panel.TabIndex = 4;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.icon_remove_button;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(16, 108);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(90, 90);
buttonDel.TabIndex = 2;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.icon_add_button;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(16, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(90, 90);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormContracts
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panel);
Name = "FormContracts";
StartPosition = FormStartPosition.CenterParent;
Text = "Контракты";
Load += FormContracts_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
panel.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewData;
private Panel panel;
private Button buttonDel;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,84 @@
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormContracts : Form
{
private readonly IUnityContainer _container;
private readonly IContractRepository _contractRepository;
public FormContracts(IUnityContainer container, IContractRepository contractRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentException(nameof(container));
_contractRepository = contractRepository ?? throw new ArgumentException(nameof(contractRepository));
}
private void FormContracts_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormContract>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
return;
try
{
_contractRepository.DeleteContract(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _contractRepository.ReadContracts();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["ConclusionDate"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
dataGridViewData.Columns["Deadline"].DefaultCellStyle.Format = "dd MMMM yyyy hh:mm";
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

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

@ -0,0 +1,140 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormCustomer
{
/// <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()
{
labelCustomerName = new Label();
labelCustomerContact = new Label();
labelCustomerAddress = new Label();
textBoxCustomerName = new TextBox();
textBoxCustomerContact = new TextBox();
textBoxCustomerAddress = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelCustomerName
//
labelCustomerName.AutoSize = true;
labelCustomerName.Location = new Point(12, 9);
labelCustomerName.Name = "labelCustomerName";
labelCustomerName.Size = new Size(34, 15);
labelCustomerName.TabIndex = 0;
labelCustomerName.Text = "Имя:";
//
// labelCustomerContact
//
labelCustomerContact.AutoSize = true;
labelCustomerContact.Location = new Point(12, 38);
labelCustomerContact.Name = "labelCustomerContact";
labelCustomerContact.Size = new Size(107, 15);
labelCustomerContact.TabIndex = 1;
labelCustomerContact.Text = "Контактная почта:";
//
// labelCustomerAddress
//
labelCustomerAddress.AutoSize = true;
labelCustomerAddress.Location = new Point(12, 67);
labelCustomerAddress.Name = "labelCustomerAddress";
labelCustomerAddress.Size = new Size(43, 15);
labelCustomerAddress.TabIndex = 2;
labelCustomerAddress.Text = "Адрес:";
//
// textBoxCustomerName
//
textBoxCustomerName.Location = new Point(125, 6);
textBoxCustomerName.Name = "textBoxCustomerName";
textBoxCustomerName.Size = new Size(168, 23);
textBoxCustomerName.TabIndex = 3;
//
// textBoxCustomerContact
//
textBoxCustomerContact.Location = new Point(125, 35);
textBoxCustomerContact.Name = "textBoxCustomerContact";
textBoxCustomerContact.Size = new Size(168, 23);
textBoxCustomerContact.TabIndex = 4;
//
// textBoxCustomerAddress
//
textBoxCustomerAddress.Location = new Point(125, 64);
textBoxCustomerAddress.Name = "textBoxCustomerAddress";
textBoxCustomerAddress.Size = new Size(168, 23);
textBoxCustomerAddress.TabIndex = 5;
//
// buttonSave
//
buttonSave.Location = new Point(12, 93);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(281, 23);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(12, 122);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(281, 23);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormCustomer
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(309, 159);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxCustomerAddress);
Controls.Add(textBoxCustomerContact);
Controls.Add(textBoxCustomerName);
Controls.Add(labelCustomerAddress);
Controls.Add(labelCustomerContact);
Controls.Add(labelCustomerName);
Name = "FormCustomer";
StartPosition = FormStartPosition.CenterParent;
Text = "Заказчик";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelCustomerName;
private Label labelCustomerContact;
private Label labelCustomerAddress;
private TextBox textBoxCustomerName;
private TextBox textBoxCustomerContact;
private TextBox textBoxCustomerAddress;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,68 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormCustomer : Form
{
private readonly ICustomerRepository _customerRepository;
private int? _customerId;
public int Id
{
set
{
try
{
var customer = _customerRepository.ReadCustomerById(value);
if (customer == null) throw new InvalidDataException(nameof(customer));
textBoxCustomerName.Text = customer.Name;
textBoxCustomerContact.Text = customer.Contact;
textBoxCustomerAddress.Text = customer.Address;
_customerId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormCustomer(ICustomerRepository customerRepository)
{
InitializeComponent();
_customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(textBoxCustomerName.Text) ||
string.IsNullOrEmpty(textBoxCustomerContact.Text) ||
string.IsNullOrEmpty(textBoxCustomerAddress.Text))
{
throw new Exception("Имеются незаполненные поля");
}
if (_customerId.HasValue) _customerRepository.UpdateCustomer(CreateCustomer(_customerId.Value));
else _customerRepository.CreateCustomer(CreateCustomer(0));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Customer CreateCustomer(int id) => Customer.CreateEntity(
id, textBoxCustomerName.Text, textBoxCustomerContact.Text,
textBoxCustomerAddress.Text);
}
}

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

@ -0,0 +1,172 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormCustomerExecutorReview
{
/// <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()
{
labelCustomerExecutorReviewCustomerId = new Label();
buttonCancel = new Button();
buttonSave = new Button();
richTextBoxCustomerExecutorReviewReview = new RichTextBox();
labelCustomerExecutorReviewReview = new Label();
numericUpDownCustomerExecutorReviewGrade = new NumericUpDown();
comboBoxCustomerExecutorReviewCustomerId = new ComboBox();
comboBoxCustomerExecutorReviewExecutorId = new ComboBox();
labelCustomerExecutorReviewExecutorId = new Label();
labelCustomerExecutorReviewGrade = new Label();
((System.ComponentModel.ISupportInitialize)numericUpDownCustomerExecutorReviewGrade).BeginInit();
SuspendLayout();
//
// labelCustomerExecutorReviewCustomerId
//
labelCustomerExecutorReviewCustomerId.AutoSize = true;
labelCustomerExecutorReviewCustomerId.Location = new Point(12, 9);
labelCustomerExecutorReviewCustomerId.Name = "labelCustomerExecutorReviewCustomerId";
labelCustomerExecutorReviewCustomerId.Size = new Size(60, 15);
labelCustomerExecutorReviewCustomerId.TabIndex = 22;
labelCustomerExecutorReviewCustomerId.Text = "Заказчик:";
//
// buttonCancel
//
buttonCancel.Location = new Point(12, 224);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(358, 23);
buttonCancel.TabIndex = 21;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(12, 195);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(358, 23);
buttonSave.TabIndex = 20;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// richTextBoxCustomerExecutorReviewReview
//
richTextBoxCustomerExecutorReviewReview.Location = new Point(169, 64);
richTextBoxCustomerExecutorReviewReview.Name = "richTextBoxCustomerExecutorReviewReview";
richTextBoxCustomerExecutorReviewReview.Size = new Size(202, 96);
richTextBoxCustomerExecutorReviewReview.TabIndex = 27;
richTextBoxCustomerExecutorReviewReview.Text = "";
//
// labelCustomerExecutorReviewReview
//
labelCustomerExecutorReviewReview.AutoSize = true;
labelCustomerExecutorReviewReview.Location = new Point(12, 67);
labelCustomerExecutorReviewReview.Name = "labelCustomerExecutorReviewReview";
labelCustomerExecutorReviewReview.Size = new Size(44, 15);
labelCustomerExecutorReviewReview.TabIndex = 28;
labelCustomerExecutorReviewReview.Text = "Отзыв:";
//
// numericUpDownCustomerExecutorReviewGrade
//
numericUpDownCustomerExecutorReviewGrade.Location = new Point(169, 166);
numericUpDownCustomerExecutorReviewGrade.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
numericUpDownCustomerExecutorReviewGrade.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownCustomerExecutorReviewGrade.Name = "numericUpDownCustomerExecutorReviewGrade";
numericUpDownCustomerExecutorReviewGrade.Size = new Size(201, 23);
numericUpDownCustomerExecutorReviewGrade.TabIndex = 29;
numericUpDownCustomerExecutorReviewGrade.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// comboBoxCustomerExecutorReviewCustomerId
//
comboBoxCustomerExecutorReviewCustomerId.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxCustomerExecutorReviewCustomerId.FormattingEnabled = true;
comboBoxCustomerExecutorReviewCustomerId.Location = new Point(169, 6);
comboBoxCustomerExecutorReviewCustomerId.Name = "comboBoxCustomerExecutorReviewCustomerId";
comboBoxCustomerExecutorReviewCustomerId.Size = new Size(202, 23);
comboBoxCustomerExecutorReviewCustomerId.TabIndex = 30;
//
// comboBoxCustomerExecutorReviewExecutorId
//
comboBoxCustomerExecutorReviewExecutorId.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxCustomerExecutorReviewExecutorId.FormattingEnabled = true;
comboBoxCustomerExecutorReviewExecutorId.Location = new Point(169, 35);
comboBoxCustomerExecutorReviewExecutorId.Name = "comboBoxCustomerExecutorReviewExecutorId";
comboBoxCustomerExecutorReviewExecutorId.Size = new Size(202, 23);
comboBoxCustomerExecutorReviewExecutorId.TabIndex = 31;
//
// labelCustomerExecutorReviewExecutorId
//
labelCustomerExecutorReviewExecutorId.AutoSize = true;
labelCustomerExecutorReviewExecutorId.Location = new Point(12, 38);
labelCustomerExecutorReviewExecutorId.Name = "labelCustomerExecutorReviewExecutorId";
labelCustomerExecutorReviewExecutorId.Size = new Size(84, 15);
labelCustomerExecutorReviewExecutorId.TabIndex = 32;
labelCustomerExecutorReviewExecutorId.Text = "Исполнитель:";
//
// labelCustomerExecutorReviewGrade
//
labelCustomerExecutorReviewGrade.AutoSize = true;
labelCustomerExecutorReviewGrade.Location = new Point(12, 168);
labelCustomerExecutorReviewGrade.Name = "labelCustomerExecutorReviewGrade";
labelCustomerExecutorReviewGrade.Size = new Size(51, 15);
labelCustomerExecutorReviewGrade.TabIndex = 33;
labelCustomerExecutorReviewGrade.Text = "Оценка:";
//
// FormCustomerExecutorReview
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(381, 260);
Controls.Add(labelCustomerExecutorReviewGrade);
Controls.Add(labelCustomerExecutorReviewExecutorId);
Controls.Add(comboBoxCustomerExecutorReviewExecutorId);
Controls.Add(comboBoxCustomerExecutorReviewCustomerId);
Controls.Add(numericUpDownCustomerExecutorReviewGrade);
Controls.Add(labelCustomerExecutorReviewReview);
Controls.Add(richTextBoxCustomerExecutorReviewReview);
Controls.Add(labelCustomerExecutorReviewCustomerId);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Name = "FormCustomerExecutorReview";
StartPosition = FormStartPosition.CenterParent;
Text = "Отзыв заказчика";
((System.ComponentModel.ISupportInitialize)numericUpDownCustomerExecutorReviewGrade).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxCustomerExecutorReviewCustomerId;
private Label labelCustomerExecutorReviewCustomerId;
private Button buttonCancel;
private Button buttonSave;
private RichTextBox richTextBoxCustomerExecutorReviewReview;
private Label labelCustomerExecutorReviewReview;
private NumericUpDown numericUpDownCustomerExecutorReviewGrade;
private ComboBox comboBoxCustomerExecutorReviewExecutorId;
private Label labelCustomerExecutorReviewExecutorId;
private Label labelCustomerExecutorReviewGrade;
}
}

View File

@ -0,0 +1,58 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormCustomerExecutorReview : Form
{
private readonly ICustomerExecutorReviewRepository _customerExecutorReviewRepository;
public FormCustomerExecutorReview(ICustomerExecutorReviewRepository customerExecutorReviewRepository,
ICustomerRepository customerRepository, IExecutorRepository executorRepository)
{
InitializeComponent();
_customerExecutorReviewRepository = customerExecutorReviewRepository ??
throw new ArgumentNullException(nameof(customerExecutorReviewRepository));
comboBoxCustomerExecutorReviewCustomerId.DataSource = customerRepository.ReadCustomers();
comboBoxCustomerExecutorReviewCustomerId.DisplayMember = "FullName";
comboBoxCustomerExecutorReviewCustomerId.ValueMember = "Id";
comboBoxCustomerExecutorReviewExecutorId.DataSource = executorRepository.ReadExecutors();
comboBoxCustomerExecutorReviewExecutorId.DisplayMember = "FullName";
comboBoxCustomerExecutorReviewExecutorId.ValueMember = "Id";
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (comboBoxCustomerExecutorReviewExecutorId.SelectedIndex < 0 ||
comboBoxCustomerExecutorReviewCustomerId.SelectedIndex < 0 ||
string.IsNullOrEmpty(richTextBoxCustomerExecutorReviewReview.Text))
{
throw new Exception("Имеются незаполненные поля");
}
_customerExecutorReviewRepository.CreateCustomerExecutorReview(CreateCustomerExecutorReview(0));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private CustomerExecutorReview CreateCustomerExecutorReview(int id)
{
return CustomerExecutorReview.CreateElement(
id, (int)comboBoxCustomerExecutorReviewCustomerId.SelectedValue!,
(int)comboBoxCustomerExecutorReviewExecutorId.SelectedValue!,
richTextBoxCustomerExecutorReviewReview.Text,
Convert.ToInt32(numericUpDownCustomerExecutorReviewGrade.Value));
}
}
}

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

@ -0,0 +1,98 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormCustomerExecutorReviews
{
/// <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()
{
dataGridViewData = new DataGridView();
panel = new Panel();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
panel.SuspendLayout();
SuspendLayout();
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(677, 450);
dataGridViewData.TabIndex = 5;
//
// panel
//
panel.Controls.Add(buttonAdd);
panel.Dock = DockStyle.Right;
panel.Location = new Point(677, 0);
panel.Name = "panel";
panel.Size = new Size(123, 450);
panel.TabIndex = 4;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.icon_add_button;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(16, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(90, 90);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormCustomerContractReviews
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panel);
Name = "FormCustomerContractReviews";
StartPosition = FormStartPosition.CenterParent;
Text = "Отзывы заказчиков";
Load += FormCustomerExecutorReviews_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
panel.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewData;
private Panel panel;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,50 @@
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormCustomerExecutorReviews : Form
{
private readonly IUnityContainer _container;
private readonly ICustomerExecutorReviewRepository _customerExecutorReviewRepository;
public FormCustomerExecutorReviews(IUnityContainer container, ICustomerExecutorReviewRepository customerExecutorReviewRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentException(nameof(container));
_customerExecutorReviewRepository = customerExecutorReviewRepository ?? throw new ArgumentException(nameof(customerExecutorReviewRepository));
}
private void FormCustomerExecutorReviews_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormCustomerExecutorReview>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _customerExecutorReviewRepository.ReadCustomerExecutorReviews();
dataGridViewData.Columns["Id"].Visible = false;
}
}
}

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

@ -0,0 +1,126 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormCustomers
{
/// <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()
{
panel = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridViewData = new DataGridView();
panel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
SuspendLayout();
//
// panel
//
panel.Controls.Add(buttonDel);
panel.Controls.Add(buttonUpd);
panel.Controls.Add(buttonAdd);
panel.Dock = DockStyle.Right;
panel.Location = new Point(677, 0);
panel.Name = "panel";
panel.Size = new Size(123, 450);
panel.TabIndex = 0;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.icon_remove_button;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(16, 204);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(90, 90);
buttonDel.TabIndex = 2;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.icon_edit_button;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(16, 108);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(90, 90);
buttonUpd.TabIndex = 1;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.icon_add_button;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(16, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(90, 90);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(677, 450);
dataGridViewData.TabIndex = 1;
//
// FormCustomers
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panel);
Name = "FormCustomers";
StartPosition = FormStartPosition.CenterParent;
Text = "Заказчики";
Load += FormCustomers_Load;
panel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panel;
private Button buttonAdd;
private Button buttonDel;
private Button buttonUpd;
private DataGridView dataGridViewData;
}
}

View File

@ -0,0 +1,101 @@
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormCustomers : Form
{
private readonly IUnityContainer _container;
private readonly ICustomerRepository _customerRepository;
public FormCustomers(IUnityContainer container, ICustomerRepository customerRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentException(nameof(container));
_customerRepository = customerRepository ?? throw new ArgumentException(nameof(customerRepository));
}
private void FormCustomers_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormCustomer>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
try
{
var form = _container.Resolve<FormCustomer>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
return;
try
{
_customerRepository.DeleteCustomer(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _customerRepository.ReadCustomers();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

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

@ -0,0 +1,100 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.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()
{
checkBoxCustomers = new CheckBox();
checkBoxExecutors = new CheckBox();
checkBoxServices = new CheckBox();
buttonBuild = new Button();
SuspendLayout();
//
// checkBoxCustomers
//
checkBoxCustomers.AutoSize = true;
checkBoxCustomers.Location = new Point(12, 12);
checkBoxCustomers.Name = "checkBoxCustomers";
checkBoxCustomers.Size = new Size(83, 19);
checkBoxCustomers.TabIndex = 0;
checkBoxCustomers.Text = "Заказчики";
checkBoxCustomers.UseVisualStyleBackColor = true;
//
// checkBoxExecutors
//
checkBoxExecutors.AutoSize = true;
checkBoxExecutors.Location = new Point(12, 37);
checkBoxExecutors.Name = "checkBoxExecutors";
checkBoxExecutors.Size = new Size(94, 19);
checkBoxExecutors.TabIndex = 1;
checkBoxExecutors.Text = "Исполители";
checkBoxExecutors.UseVisualStyleBackColor = true;
//
// checkBoxServices
//
checkBoxServices.AutoSize = true;
checkBoxServices.Location = new Point(12, 62);
checkBoxServices.Name = "checkBoxServices";
checkBoxServices.Size = new Size(64, 19);
checkBoxServices.TabIndex = 2;
checkBoxServices.Text = "Услуги";
checkBoxServices.UseVisualStyleBackColor = true;
//
// buttonBuild
//
buttonBuild.Location = new Point(141, 34);
buttonBuild.Name = "buttonBuild";
buttonBuild.Size = new Size(117, 23);
buttonBuild.TabIndex = 3;
buttonBuild.Text = "Сформировать";
buttonBuild.UseVisualStyleBackColor = true;
buttonBuild.Click += ButtonBuild_Click;
//
// FormDirectoryReport
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(270, 94);
Controls.Add(buttonBuild);
Controls.Add(checkBoxServices);
Controls.Add(checkBoxExecutors);
Controls.Add(checkBoxCustomers);
Name = "FormDirectoryReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Выгрузка справочников";
ResumeLayout(false);
PerformLayout();
}
#endregion
private CheckBox checkBoxCustomers;
private CheckBox checkBoxExecutors;
private CheckBox checkBoxServices;
private Button buttonBuild;
}
}

View File

@ -0,0 +1,45 @@
using PIbd_23_Gutorov_I.A._IT_Company.Reports;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.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 (!checkBoxCustomers.Checked && !checkBoxExecutors.Checked && !checkBoxServices.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, checkBoxCustomers.Checked,
checkBoxExecutors.Checked, checkBoxServices.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

@ -0,0 +1,120 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormExecutor
{
/// <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()
{
comboBoxExecutorPost = new ComboBox();
LabelExecutorName = new Label();
labelExecutorPost = new Label();
textBoxExecutorName = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// comboBoxExecutorPost
//
comboBoxExecutorPost.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxExecutorPost.FormattingEnabled = true;
comboBoxExecutorPost.Location = new Point(101, 41);
comboBoxExecutorPost.Name = "comboBoxExecutorPost";
comboBoxExecutorPost.Size = new Size(168, 23);
comboBoxExecutorPost.TabIndex = 0;
//
// LabelExecutorName
//
LabelExecutorName.AutoSize = true;
LabelExecutorName.Location = new Point(12, 15);
LabelExecutorName.Name = "LabelExecutorName";
LabelExecutorName.Size = new Size(34, 15);
LabelExecutorName.TabIndex = 1;
LabelExecutorName.Text = "Имя:";
//
// labelExecutorPost
//
labelExecutorPost.AutoSize = true;
labelExecutorPost.Location = new Point(12, 44);
labelExecutorPost.Name = "labelExecutorPost";
labelExecutorPost.Size = new Size(72, 15);
labelExecutorPost.TabIndex = 2;
labelExecutorPost.Text = "Должность:";
//
// textBoxExecutorName
//
textBoxExecutorName.Location = new Point(101, 12);
textBoxExecutorName.Name = "textBoxExecutorName";
textBoxExecutorName.Size = new Size(168, 23);
textBoxExecutorName.TabIndex = 4;
//
// buttonSave
//
buttonSave.Location = new Point(12, 70);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(257, 23);
buttonSave.TabIndex = 7;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(12, 99);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(257, 23);
buttonCancel.TabIndex = 8;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormExecutor
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(281, 133);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(textBoxExecutorName);
Controls.Add(labelExecutorPost);
Controls.Add(LabelExecutorName);
Controls.Add(comboBoxExecutorPost);
Name = "FormExecutor";
StartPosition = FormStartPosition.CenterParent;
Text = "Исполнитель";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxExecutorPost;
private Label LabelExecutorName;
private Label labelExecutorPost;
private TextBox textBoxExecutorName;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,68 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using PIbd_23_Gutorov_I.A._IT_Company.Entities.Enums;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormExecutor : Form
{
private readonly IExecutorRepository _executorRepository;
private int? _executorId;
public int Id
{
set
{
try
{
var executor = _executorRepository.ReadExecutorById(value);
if (executor == null) throw new InvalidDataException(nameof(executor));
textBoxExecutorName.Text = executor.Name;
comboBoxExecutorPost.SelectedItem = executor.Post;
_executorId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormExecutor(IExecutorRepository executorRepository)
{
InitializeComponent();
_executorRepository = executorRepository ?? throw new ArgumentNullException(nameof(executorRepository));
comboBoxExecutorPost.DataSource = Enum.GetValues(typeof(ExecutorPost));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(textBoxExecutorName.Text) ||
comboBoxExecutorPost.SelectedIndex < 1)
{
throw new Exception("Имеются незаполненные поля");
}
if (_executorId.HasValue) _executorRepository.UpdateExecutor(CreateExecutor(_executorId.Value));
else _executorRepository.CreateExecutor(CreateExecutor(0));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
private Executor CreateExecutor(int id) =>
Executor.CreateEntity(id, textBoxExecutorName.Text, (ExecutorPost)comboBoxExecutorPost.SelectedItem!);
}
}

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

@ -0,0 +1,126 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormExecutors
{
/// <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()
{
dataGridViewData = new DataGridView();
panel = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
panel.SuspendLayout();
SuspendLayout();
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(677, 450);
dataGridViewData.TabIndex = 3;
//
// panel
//
panel.Controls.Add(buttonDel);
panel.Controls.Add(buttonUpd);
panel.Controls.Add(buttonAdd);
panel.Dock = DockStyle.Right;
panel.Location = new Point(677, 0);
panel.Name = "panel";
panel.Size = new Size(123, 450);
panel.TabIndex = 2;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.icon_remove_button;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(16, 204);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(90, 90);
buttonDel.TabIndex = 2;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.icon_edit_button;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(16, 108);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(90, 90);
buttonUpd.TabIndex = 1;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.icon_add_button;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(16, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(90, 90);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormExecutors
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panel);
Name = "FormExecutors";
StartPosition = FormStartPosition.CenterParent;
Text = "Исполнители";
Load += FormExecutors_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
panel.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewData;
private Panel panel;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,101 @@
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormExecutors : Form
{
private readonly IUnityContainer _container;
private readonly IExecutorRepository _executorRepository;
public FormExecutors(IUnityContainer container, IExecutorRepository executorRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentException(nameof(container));
_executorRepository = executorRepository ?? throw new ArgumentException(nameof(executorRepository));
}
private void FormExecutors_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormExecutor>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
try
{
var form = _container.Resolve<FormExecutor>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
return;
try
{
_executorRepository.DeleteExecutor(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _executorRepository.ReadExecutors();
dataGridViewData.Columns["Id"].Visible = false;
dataGridViewData.Columns["FullName"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

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

@ -0,0 +1,96 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormService
{
/// <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()
{
labelServiceDescription = new Label();
richTextBoxServiceDescription = new RichTextBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// labelServiceDescription
//
labelServiceDescription.AutoSize = true;
labelServiceDescription.Location = new Point(16, 15);
labelServiceDescription.Name = "labelServiceDescription";
labelServiceDescription.Size = new Size(65, 15);
labelServiceDescription.TabIndex = 30;
labelServiceDescription.Text = "Описание:";
//
// richTextBoxServiceDescription
//
richTextBoxServiceDescription.Location = new Point(173, 12);
richTextBoxServiceDescription.Name = "richTextBoxServiceDescription";
richTextBoxServiceDescription.Size = new Size(202, 96);
richTextBoxServiceDescription.TabIndex = 29;
richTextBoxServiceDescription.Text = "";
//
// buttonCancel
//
buttonCancel.Location = new Point(16, 143);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(359, 23);
buttonCancel.TabIndex = 32;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(16, 114);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(359, 23);
buttonSave.TabIndex = 31;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// FormService
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(387, 181);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(labelServiceDescription);
Controls.Add(richTextBoxServiceDescription);
Name = "FormService";
StartPosition = FormStartPosition.CenterParent;
Text = "Услуга";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelServiceDescription;
private RichTextBox richTextBoxServiceDescription;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,58 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormService : Form
{
private readonly IServiceRepository _serviceRepository;
private int? _serviceId;
public int Id
{
set
{
try
{
var service = _serviceRepository.ReadServiceById(value);
if (service == null) throw new InvalidDataException(nameof(service));
richTextBoxServiceDescription.Text = service.Description;
_serviceId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormService(IServiceRepository serviceRepository)
{
InitializeComponent();
_serviceRepository = serviceRepository ?? throw new ArgumentNullException(nameof(serviceRepository));
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(richTextBoxServiceDescription.Text))
throw new Exception("Имеются незаполненные поля");
if (_serviceId.HasValue) _serviceRepository.UpdateService(Service.CreateEntity(_serviceId.Value, richTextBoxServiceDescription.Text));
else _serviceRepository.CreateService(Service.CreateEntity(0, richTextBoxServiceDescription.Text));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e) => Close();
}
}

View File

@ -0,0 +1,130 @@
using static System.Net.Mime.MediaTypeNames;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormServices
{
/// <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()
{
dataGridViewData = new DataGridView();
panel = new Panel();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewData).BeginInit();
panel.SuspendLayout();
SuspendLayout();
//
// dataGridViewData
//
dataGridViewData.AllowUserToAddRows = false;
dataGridViewData.AllowUserToDeleteRows = false;
dataGridViewData.AllowUserToResizeColumns = false;
dataGridViewData.AllowUserToResizeRows = false;
dataGridViewData.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridViewData.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewData.Dock = DockStyle.Fill;
dataGridViewData.Location = new Point(0, 0);
dataGridViewData.MultiSelect = false;
dataGridViewData.Name = "dataGridViewData";
dataGridViewData.ReadOnly = true;
dataGridViewData.RowHeadersVisible = false;
dataGridViewData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewData.Size = new Size(677, 450);
dataGridViewData.TabIndex = 5;
//
// panel
//
panel.Controls.Add(buttonDel);
panel.Controls.Add(buttonUpd);
panel.Controls.Add(buttonAdd);
panel.Dock = DockStyle.Right;
panel.Location = new Point(677, 0);
panel.Name = "panel";
panel.Size = new Size(123, 450);
panel.TabIndex = 4;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.icon_remove_button;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(16, 204);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(90, 90);
buttonDel.TabIndex = 2;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonUpd
//
buttonUpd.BackgroundImage = Properties.Resources.icon_edit_button;
buttonUpd.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpd.Location = new Point(16, 108);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(90, 90);
buttonUpd.TabIndex = 1;
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.icon_add_button;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(16, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(90, 90);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormServices
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridViewData);
Controls.Add(panel);
Name = "FormServices";
StartPosition = FormStartPosition.CenterParent;
Text = "Услуги";
Load += FormServices_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewData).EndInit();
panel.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewData;
private Panel panel;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,100 @@
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormServices : Form
{
private readonly IUnityContainer _container;
private readonly IServiceRepository _serviceRepository;
public FormServices(IUnityContainer container, IServiceRepository serviceRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentException(nameof(container));
_serviceRepository = serviceRepository ?? throw new ArgumentException(nameof(serviceRepository));
}
private void FormServices_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormService>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
try
{
var form = _container.Resolve<FormService>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
return;
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
return;
try
{
_serviceRepository.DeleteService(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewData.DataSource = _serviceRepository.ReadServices();
dataGridViewData.Columns["Id"].Visible = false;
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewData.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewData.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

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

@ -0,0 +1,108 @@
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
partial class FormServiceDistributionReport
{
/// <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()
{
buttonSelectFileName = new Button();
labelFileName = new Label();
labelDate = new Label();
dateTimePickerDate = new DateTimePicker();
buttonBuild = new Button();
SuspendLayout();
//
// buttonSelectFileName
//
buttonSelectFileName.Location = new Point(12, 12);
buttonSelectFileName.Name = "buttonSelectFileName";
buttonSelectFileName.Size = new Size(75, 23);
buttonSelectFileName.TabIndex = 0;
buttonSelectFileName.Text = "Выбрать";
buttonSelectFileName.UseVisualStyleBackColor = true;
buttonSelectFileName.Click += ButtonSelectFileName_Click;
//
// labelFileName
//
labelFileName.AutoSize = true;
labelFileName.Location = new Point(93, 16);
labelFileName.Name = "labelFileName";
labelFileName.Size = new Size(36, 15);
labelFileName.TabIndex = 1;
labelFileName.Text = "Файл";
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(12, 41);
labelDate.Name = "labelDate";
labelDate.Size = new Size(35, 15);
labelDate.TabIndex = 2;
labelDate.Text = "Дата:";
//
// dateTimePickerDate
//
dateTimePickerDate.Location = new Point(93, 41);
dateTimePickerDate.Name = "dateTimePickerDate";
dateTimePickerDate.Size = new Size(200, 23);
dateTimePickerDate.TabIndex = 3;
//
// buttonBuild
//
buttonBuild.Location = new Point(14, 70);
buttonBuild.Name = "buttonBuild";
buttonBuild.Size = new Size(279, 23);
buttonBuild.TabIndex = 4;
buttonBuild.Text = "Сформировать";
buttonBuild.UseVisualStyleBackColor = true;
buttonBuild.Click += ButtonBuild_Click;
//
// FormServiceDistributionReport
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(309, 105);
Controls.Add(buttonBuild);
Controls.Add(dateTimePickerDate);
Controls.Add(labelDate);
Controls.Add(labelFileName);
Controls.Add(buttonSelectFileName);
Name = "FormServiceDistributionReport";
StartPosition = FormStartPosition.CenterParent;
Text = "Распределение услуг";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSelectFileName;
private Label labelFileName;
private Label labelDate;
private DateTimePicker dateTimePickerDate;
private Button buttonBuild;
}
}

View File

@ -0,0 +1,53 @@
using PIbd_23_Gutorov_I.A._IT_Company.Reports;
using Unity;
namespace PIbd_23_Gutorov_I.A._IT_Company.Forms
{
public partial class FormServiceDistributionReport : Form
{
private string _fileName = string.Empty;
private readonly IUnityContainer _container;
public FormServiceDistributionReport(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 ButtonBuild_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(_fileName))
throw new Exception("Отсутствует имя файла для отчета");
if (_container.Resolve<ChartReport>().CreateChart(_fileName, dateTimePickerDate.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

@ -9,4 +9,43 @@
<ImplicitUsings>enable</ImplicitUsings>
</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.1" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Serilog" Version="4.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.4" />
<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>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,3 +1,11 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
using Serilog;
using Unity;
using Unity.Microsoft.Logging;
namespace PIbd_23_Gutorov_I.A._IT_Company
{
internal static class Program
@ -11,7 +19,35 @@ namespace PIbd_23_Gutorov_I.A._IT_Company
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
Application.Run(CreateContainer().Resolve<FormItCompany>());
}
private static IUnityContainer CreateContainer()
{
var container = new UnityContainer();
container.AddExtension(new LoggingExtension(CreateLoggerFactory()));
container.RegisterType<IContractRepository, ContractRepository>();
container.RegisterType<ICustomerExecutorReviewRepository, CustomerExecutorReviewRepository>();
container.RegisterType<ICustomerRepository, CustomerRepository>();
container.RegisterType<IExecutorRepository, ExecutorRepository>();
container.RegisterType<IServiceRepository, ServiceRepository>();
container.RegisterType<IConnectionString, ConnectionString>();
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

@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PIbd_23_Gutorov_I.A._IT_Company.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PIbd_23_Gutorov_I.A._IT_Company.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap icon_add_button {
get {
object obj = ResourceManager.GetObject("icon-add-button", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap icon_edit_button {
get {
object obj = ResourceManager.GetObject("icon-edit-button", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap icon_remove_button {
get {
object obj = ResourceManager.GetObject("icon-remove-button", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap modern_equipped_computer_lab {
get {
object obj = ResourceManager.GetObject("modern-equipped-computer-lab", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,133 @@
<?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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="modern-equipped-computer-lab" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\modern-equipped-computer-lab.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-add-button" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-add-button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-edit-button" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-edit-button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-remove-button" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-remove-button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,50 @@
using Microsoft.Extensions.Logging;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Reports;
internal class ChartReport
{
private readonly IContractRepository _contractRepository;
private readonly ILogger<ChartReport> _logger;
public ChartReport(IContractRepository contractRepository,
ILogger<ChartReport> logger)
{
_contractRepository = contractRepository ??
throw new ArgumentNullException(nameof(contractRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateChart(string filePath, DateTime dateTime)
{
try
{
new PdfBuilder(filePath)
.AddHeader("Заключение контрактов")
.AddPieChart($"Оказанные услуги на {dateTime: dd MMMM yyyy}", GetData(dateTime))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _contractRepository
.ReadContracts(dateFrom: dateTime.Date, dateTo: dateTime.Date.AddDays(1))
.GroupBy(x => x.CustomerName, (key, group) => new
{
Id = key,
Count = group.Sum(x => x.Services.Count())
})
.Select(x => (x.Id.ToString(), (double)x.Count))
.ToList();
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.Extensions.Logging;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Reports;
internal class DocReport
{
private readonly ICustomerRepository _customerRepository;
private readonly IExecutorRepository _executorRepository;
private readonly IServiceRepository _serviceRepository;
private readonly ILogger<DocReport> _logger;
public DocReport(ICustomerRepository customerRepository,
IExecutorRepository executorRepository, IServiceRepository serviceRepository,
ILogger<DocReport> logger)
{
_customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
_executorRepository = executorRepository ?? throw new ArgumentNullException(nameof(executorRepository));
_serviceRepository = serviceRepository ?? throw new ArgumentNullException(nameof(serviceRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateDoc(string filePath, bool includeCustomers, bool includeExecutors, bool includeServices)
{
var wordBuilder = new WordBuilder(filePath);
try
{
var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками");
if (includeCustomers)
builder.AddParagraph("Заказчики").AddTable([2400, 2400, 2400], GetCustomers());
if (includeExecutors)
builder.AddParagraph("Работники").AddTable([2400, 2400], GetExecutors());
if (includeServices)
builder.AddParagraph("Услуги").AddTable([2400], GetServices());
builder.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetCustomers()
{
return [
["Имя", "Контакты", "Адрес"],
.. _customerRepository
.ReadCustomers()
.Select(x => new string[] { x.Name, x.Contact, x.Address })];
}
private List<string[]> GetExecutors()
{
return [
["Имя", "Должность"],
.. _executorRepository
.ReadExecutors()
.Select(x => new string[] { x.Name, x.Post.ToString() })];
}
private List<string[]> GetServices()
{
return [
["Описание услуги"],
.. _serviceRepository
.ReadServices()
.Select(x => new string[] { x.Description })];
}
}

View File

@ -0,0 +1,315 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace PIbd_23_Gutorov_I.A._IT_Company.Reports;
internal 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 = 1,
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.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
BoldTextWithoutBorder = 1,
SimpleTextWithBorder = 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,87 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
using System.Text;
namespace PIbd_23_Gutorov_I.A._IT_Company.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()
{
var headerStyle = _document.Styles.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@ -0,0 +1,80 @@
using Microsoft.Extensions.Logging;
using PIbd_23_Gutorov_I.A._IT_Company.Repositories;
namespace PIbd_23_Gutorov_I.A._IT_Company.Reports;
internal class TableReport
{
private readonly IContractRepository _contractRepository;
private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Сотрудник", "Дата", "Заключено контрактов", "Истекло контрактов"];
public TableReport(IContractRepository contractRepository, ICustomerExecutorReviewRepository
customerExecutorReviewRepository, ILogger<TableReport> logger)
{
_contractRepository = contractRepository ??
throw new ArgumentNullException(nameof(contractRepository));
_logger = logger ?? throw
new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, int customerId, DateTime startDate, DateTime endDate)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по заключениям контрактов", 0, 4)
.AddParagraph($"за период с {startDate:dd.MM.yyyy} по {endDate:dd.MM.yyyy}", 0)
.AddTable([10, 10, 15, 15], GetData(customerId, startDate, endDate))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetData(int customerId, DateTime startDate, DateTime endDate)
{
var data = _contractRepository
.ReadContracts(customerId: customerId, dateFrom: startDate, dateTo: endDate)
.GroupBy(x => x.ExecutorFullName)
.Select(x => new
{
x.First().ExecutorFullName,
Date = x.First().ConclusionDate,
CountIn = (int?)x.Count(),
CountOut = (int?)null
})
.Union(
_contractRepository
.ReadContracts(customerId: customerId, dateFrom: startDate, dateTo: endDate)
.GroupBy(x => x.ExecutorFullName)
.Select(x => new
{
x.First().ExecutorFullName,
Date = x.First().Deadline,
CountIn = (int?)null,
CountOut = (int?)x.Count()
})
)
.OrderBy(x => x.Date);
return new List<string[]>() { item }
.Union(data.Select(x => new string[] {
x.ExecutorFullName,
x.Date.ToString("dd.MM.yyyy"),
x.CountIn?.ToString("N0") ?? string.Empty,
x.CountOut?.ToString("N0") ?? string.Empty
}))
.Union(
[["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString("N0"), data.Sum(x => x.CountOut ?? 0).ToString("N0")]])
.ToList();
}
}

View File

@ -0,0 +1,124 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace PIbd_23_Gutorov_I.A._IT_Company.Reports;
internal 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,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface IConnectionString
{
public string ConnectionString { get; }
}

View File

@ -0,0 +1,12 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface IContractRepository
{
IEnumerable<Contract> ReadContracts(DateTime? dateFrom = null, DateTime? dateTo = null, int? customerId = null, int? executorId = null);
void CreateContract(Contract contract);
void DeleteContract(int id);
}

View File

@ -0,0 +1,12 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface ICustomerExecutorReviewRepository
{
IEnumerable<CustomerExecutorReview> ReadCustomerExecutorReviews(int? customerId = null, int? executorId = null);
CustomerExecutorReview ReadCustomerExecutorReviewById(int id);
void CreateCustomerExecutorReview(CustomerExecutorReview customerContractReview);
}

View File

@ -0,0 +1,16 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface ICustomerRepository
{
IEnumerable<Customer> ReadCustomers();
Customer ReadCustomerById(int id);
void CreateCustomer(Customer customer);
void UpdateCustomer(Customer customer);
void DeleteCustomer(int id);
}

View File

@ -0,0 +1,16 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface IExecutorRepository
{
IEnumerable<Executor> ReadExecutors();
Executor ReadExecutorById(int id);
void CreateExecutor(Executor executor);
void UpdateExecutor(Executor executor);
void DeleteExecutor(int id);
}

View File

@ -0,0 +1,16 @@
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories;
public interface IServiceRepository
{
IEnumerable<Service> ReadServices();
Service ReadServiceById(int id);
void CreateService(Service service);
void UpdateService(Service service);
void DeleteService(int id);
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class ConnectionString : IConnectionString
{
string IConnectionString.ConnectionString => "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=OTP";
}

View File

@ -0,0 +1,152 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class ContractRepository : IContractRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ContractRepository> _logger;
public ContractRepository(IConnectionString connectionString, ILogger<ContractRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateContract(Entities.Contract contract)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(contract));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryInsert = @"
INSERT INTO Contracts (CustomerId, ExecutorId, Category,
ConclusionDate, Deadline, PaymentAmount)
VALUES (@CustomerId, @ExecutorId, @Category,
@ConclusionDate, @Deadline, @PaymentAmount);
SELECT MAX(Id) FROM Contracts;
";
var contractId = connection.QueryFirst<int>(queryInsert, contract, transaction);
var querySubInsert = @"
INSERT INTO ServiceContract (ServiceId, ContractId)
VALUES (@ServiceId, @ContractId);
";
foreach (var elem in contract.Services)
{
var serviceId = elem.Id;
connection.Execute(querySubInsert, new { serviceId, contractId }, transaction);
}
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteContract(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Contracts
WHERE Id = @id
";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public IEnumerable<Contract> ReadContracts(DateTime? dateFrom = null, DateTime? dateTo = null, int? customerId = null, int? executorId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (dateFrom.HasValue)
{
builder.AddCondition("c.ConclusionDate >= @dateFrom");
builder.AddCondition("c.Deadline >= @dateFrom");
}
if (dateTo.HasValue)
{
builder.AddCondition("c.ConclusionDate <= @dateTo");
builder.AddCondition("c.Deadline <= @dateTo");
}
if (customerId.HasValue)
builder.AddCondition("c.CustomerId >= @customerId");
if (executorId.HasValue)
builder.AddCondition("c.ExecutorId >= @executorId");
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @$"
SELECT c.*,
CONCAT(cu.Name, ' ', cu.Contact) as CustomerName,
e.Post as ExecutorPost,
e.Name as ExecutorName,
sc.ServiceId,
s.Description as ServiceDescription
FROM Contracts c
INNER JOIN ServiceContract sc ON sc.ContractId = c.Id
LEFT JOIN Services s ON sc.ServiceId = s.Id
LEFT JOIN Customers cu ON cu.Id = c.CustomerId
LEFT JOIN Executors e ON e.Id = c.ExecutorId
{builder.Build()};
";
var contractsDict = new Dictionary<int, List<ServiceContract>>();
var contracts = connection.Query<Contract, ServiceContract, Contract>(querySelect, (contract, serviceContract) =>
{
if (!contractsDict.TryGetValue(contract.Id, out var sc))
{
sc = [];
contractsDict.Add(contract.Id, sc);
}
sc.Add(serviceContract);
return contract;
}, splitOn: "ServiceId", param: new
{
dateFrom,
dateTo,
customerId,
executorId
});
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(contracts));
return contractsDict.Select(x =>
{
var c = contracts.First(y => y.Id == x.Key);
c.SetServices(x.Value.Select(x => Service.CreateEntity(x.ServiceId, x.ServiceDescription)));
return c;
}).ToArray();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,96 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class CustomerExecutorReviewRepository : ICustomerExecutorReviewRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<CustomerExecutorReviewRepository> _logger;
public CustomerExecutorReviewRepository(IConnectionString connectionString, ILogger<CustomerExecutorReviewRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateCustomerExecutorReview(CustomerExecutorReview customerContractReview)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customerContractReview));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO CustomerExecutorReviews (CustomerId, ExecutorId, Review, Grade)
VALUES (@CustomerId, @ExecutorId, @Review, @Grade);
";
connection.Execute(queryInsert, customerContractReview);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public CustomerExecutorReview ReadCustomerExecutorReviewById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM CustomerExecutorReviews WHERE Id = @Id;
";
var customerEexcutorReview = connection.QueryFirst<CustomerExecutorReview>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(customerEexcutorReview));
return customerEexcutorReview;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<CustomerExecutorReview> ReadCustomerExecutorReviews(int? customerId = null, int? executorId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
var builder = new QueryBuilder();
if (customerId.HasValue)
builder.AddCondition("cer.CustomerId = @customerId");
if (executorId.HasValue)
builder.AddCondition("cer.ExecutorId = @executorId");
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @$"
SELECT cer.*,
CONCAT(c.Name, ' ', c.Contact) as CustomerName,
e.Post as ExecutorPost,
e.Name as ExecutorName
FROM CustomerExecutorReviews cer
LEFT JOIN Customers c ON c.Id = cer.CustomerId
LEFT JOIN Executors e ON e.Id = cer.ExecutorId
{builder.Build()};
";
var customerExecutorReviews = connection.Query<CustomerExecutorReview>(querySelect, new { customerId, executorId });
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(customerExecutorReviews));
return customerExecutorReviews;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,125 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class CustomerRepository : ICustomerRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<CustomerRepository> _logger;
public CustomerRepository(IConnectionString connectionString, ILogger<CustomerRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateCustomer(Customer customer)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customer));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Customers (Name, Contact, Address)
VALUES (@Name, @Contact, @Address);
";
connection.Execute(queryInsert, customer);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteCustomer(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Customers WHERE Id = @Id;
";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Customer ReadCustomerById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Customers WHERE Id = @Id;
";
var customer = connection.QueryFirst<Customer>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(customer));
return customer;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Customer> ReadCustomers()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Customers;
";
var customers = connection.Query<Customer>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(customers));
return customers;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdateCustomer(Customer customer)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(customer));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Customers
SET Name = @Name, Contact = @Contact, Address = @Address
WHERE Id = @Id;
";
connection.Execute(queryUpdate, customer);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
}

View File

@ -0,0 +1,125 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class ExecutorRepository : IExecutorRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ExecutorRepository> _logger;
public ExecutorRepository(IConnectionString connectionString, ILogger<ExecutorRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateExecutor(Executor executor)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(executor));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Executors (Name, Post)
VALUES (@Name, @Post);
";
connection.Execute(queryInsert, executor);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteExecutor(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Executors WHERE Id = @Id;
";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Executor ReadExecutorById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Executors WHERE Id = @Id;
";
var executor = connection.QueryFirst<Executor>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(executor));
return executor;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Executor> ReadExecutors()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Executors;
";
var executors = connection.Query<Executor>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(executors));
return executors;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdateExecutor(Executor executor)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(executor));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Executors
SET Name = @Name, Post = @Post
WHERE Id = @Id;
";
connection.Execute(queryUpdate, executor);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
}

View File

@ -0,0 +1,33 @@
using System.Text;
internal class QueryBuilder
{
private readonly StringBuilder _builder;
public QueryBuilder()
{
_builder = new();
}
public QueryBuilder AddCondition(string condition)
{
if (_builder.Length > 0)
{
_builder.Append(" AND ");
}
_builder.Append(condition);
return this;
}
public string Build()
{
if (_builder.Length == 0)
{
return string.Empty;
}
return $"WHERE {_builder}";
}
}

View File

@ -0,0 +1,127 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using PIbd_23_Gutorov_I.A._IT_Company.Entities;
using System.CodeDom.Compiler;
namespace PIbd_23_Gutorov_I.A._IT_Company.Repositories.Implementations;
public class ServiceRepository : IServiceRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ServiceRepository> _logger;
public ServiceRepository(IConnectionString connectionString, ILogger<ServiceRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateService(Service service)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(service));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Services (Description)
VALUES (@Description);
";
connection.Execute(queryInsert, service);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteService(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Services WHERE Id = @Id;
";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Service ReadServiceById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Services WHERE Id = @Id;
";
var service = connection.QueryFirst<Service>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(service));
return service;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Service> ReadServices()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Services;
";
var services = connection.Query<Service>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(services));
return services;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdateService(Service service)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(service));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Services
SET Description = @Description
WHERE Id = @Id;
";
connection.Execute(queryUpdate, service);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

View File

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