Compare commits

...

12 Commits

64 changed files with 4963 additions and 76 deletions

View File

@ -0,0 +1,22 @@
using ProjectGasStation.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class Employee
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public EmployeePost EmployeePost { get; private set; }
public static Employee CreateEntity(int id, string name, EmployeePost employeePost)
{
return new Employee { Id = id, Name = name ?? string.Empty, EmployeePost = employeePost };
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities.Enums;
[Flags]
public enum EmployeePost
{
None = 0,
Cashier = 1,
Fueler = 2,
Manager = 4,
Programmer = 8,
Mechanic = 16
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities.Enums;
public enum ProductType
{
None = 0,
Fuel = 1,
MotorOil = 2,
AutoChemicals = 3,
AutoParts = 4,
Tires = 5,
}

View File

@ -0,0 +1,24 @@
using ProjectGasStation.Entities.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class Product
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public double Price { get; private set; }
public ProductType ProductType { get; private set; }
public static Product CreateEntity(int id, string name, double price, ProductType productType)
{
return new Product { Id = id, Name = name ?? string.Empty, Price = price, ProductType = productType };
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class Purchase
{
public int Id { get; private set; }
public int ProductId { get; private set; }
public int SupplierId { get; private set; }
public double Quantity { get; private set; }
public DateTime PurchaseDate { get; private set; }
public double Price { get; private set; }
public static Purchase CreateOperation(int id, int productId, int supplierId, double quantity, DateTime purchaseDate, double price)
{
return new Purchase { Id = id, ProductId = productId, SupplierId = supplierId, Quantity = quantity, PurchaseDate = purchaseDate, Price = price };
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class Sale
{
public int Id { get; private set; }
public int EmployeeId { get; private set; }
public DateTime SaleDate { get; private set;}
public IEnumerable<SaleProduct> SaleProducts { get; private set; } = [];
public static Sale CreateOperation(int id, int employeeId, DateTime saleDate, IEnumerable<SaleProduct> saleProducts)
{
return new Sale
{
Id = id,
EmployeeId = employeeId,
SaleDate = saleDate,
SaleProducts = saleProducts
};
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class SaleProduct
{
public int Id { get; private set; }
public int SaleId { get; private set; }
public int ProductId { get; private set;}
public double Quantity { get; private set; }
public static SaleProduct CreateOperation(int id, int productID, double quantity)
{
return new SaleProduct() { Id = id, ProductId = productID, Quantity = quantity };
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Entities;
public class Supplier
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public string INN { get; private set; } = string.Empty;
public static Supplier CreateEntity(int id, string name, string INN)
{
return new Supplier { Id = id, Name = name, INN = INN };
}
}

View File

@ -1,39 +0,0 @@
namespace ProjectGasStation
{
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 ProjectGasStation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,148 @@
namespace ProjectGasStation
{
partial class FormGasStation
{
/// <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()
{
components = new System.ComponentModel.Container();
contextMenuStrip = new ContextMenuStrip(components);
menuStrip1 = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
EmployeeToolStripMenuItem = new ToolStripMenuItem();
ProductToolStripMenuItem = new ToolStripMenuItem();
SupplierToolStripMenuItem = new ToolStripMenuItem();
операцииToolStripMenuItem = new ToolStripMenuItem();
SaleToolStripMenuItem = new ToolStripMenuItem();
PurchaseToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// contextMenuStrip
//
contextMenuStrip.ImageScalingSize = new Size(18, 18);
contextMenuStrip.Name = "contextMenuStrip";
contextMenuStrip.Size = new Size(61, 4);
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(18, 18);
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, операцииToolStripMenuItem, отчетыToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(784, 25);
menuStrip1.TabIndex = 1;
menuStrip1.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { EmployeeToolStripMenuItem, ProductToolStripMenuItem, SupplierToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(99, 21);
справочникиToolStripMenuItem.Text = "Справочники";
//
// EmployeeToolStripMenuItem
//
EmployeeToolStripMenuItem.Name = "EmployeeToolStripMenuItem";
EmployeeToolStripMenuItem.Size = new Size(198, 24);
EmployeeToolStripMenuItem.Text = "Сотрудники";
EmployeeToolStripMenuItem.Click += EmployeeToolStripMenuItem_Click;
//
// ProductToolStripMenuItem
//
ProductToolStripMenuItem.Name = "ProductToolStripMenuItem";
ProductToolStripMenuItem.Size = new Size(198, 24);
ProductToolStripMenuItem.Text = "Товары";
ProductToolStripMenuItem.Click += ProductToolStripMenuItem_Click;
//
// SupplierToolStripMenuItem
//
SupplierToolStripMenuItem.Name = "SupplierToolStripMenuItem";
SupplierToolStripMenuItem.Size = new Size(198, 24);
SupplierToolStripMenuItem.Text = "Поставщики";
SupplierToolStripMenuItem.Click += SupplierToolStripMenuItem_Click;
//
// операцииToolStripMenuItem
//
операцииToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { SaleToolStripMenuItem, PurchaseToolStripMenuItem });
операцииToolStripMenuItem.Name = "операцииToolStripMenuItem";
операцииToolStripMenuItem.Size = new Size(80, 21);
операцииToolStripMenuItem.Text = "Операции";
//
// SaleToolStripMenuItem
//
SaleToolStripMenuItem.Name = "SaleToolStripMenuItem";
SaleToolStripMenuItem.Size = new Size(198, 24);
SaleToolStripMenuItem.Text = "Продажа";
SaleToolStripMenuItem.Click += SaleToolStripMenuItem_Click;
//
// PurchaseToolStripMenuItem
//
PurchaseToolStripMenuItem.Name = "PurchaseToolStripMenuItem";
PurchaseToolStripMenuItem.Size = new Size(198, 24);
PurchaseToolStripMenuItem.Text = "Закупка";
PurchaseToolStripMenuItem.Click += PurchaseToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(63, 21);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// FormGasStation
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
BackgroundImage = Properties.Resources.Union_76_Gas_Station;
BackgroundImageLayout = ImageLayout.Stretch;
ClientSize = new Size(784, 409);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "FormGasStation";
StartPosition = FormStartPosition.CenterScreen;
Text = "Заправочная станция";
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ContextMenuStrip contextMenuStrip;
private MenuStrip menuStrip1;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem операцииToolStripMenuItem;
private ToolStripMenuItem отчетыToolStripMenuItem;
private ToolStripMenuItem EmployeeToolStripMenuItem;
private ToolStripMenuItem ProductToolStripMenuItem;
private ToolStripMenuItem сменыToolStripMenuItem;
private ToolStripMenuItem SupplierToolStripMenuItem;
private ToolStripMenuItem SaleToolStripMenuItem;
private ToolStripMenuItem PurchaseToolStripMenuItem;
}
}

View File

@ -0,0 +1,74 @@
using ProjectGasStation.Forms;
using Unity;
namespace ProjectGasStation;
public partial class FormGasStation : Form
{
private readonly IUnityContainer _container;
public FormGasStation(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void EmployeeToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormEmployees>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ProductToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormProducts>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SupplierToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormSuppliers>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void PurchaseToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormPurchases>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SaleToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormSales>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà ïðè çàãðóçêå", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

View File

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

View File

@ -0,0 +1,117 @@
namespace ProjectGasStation.Forms
{
partial class FormEmployee
{
/// <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()
{
labelName = new Label();
label2 = new Label();
textBoxName = new TextBox();
checkedListBoxType = new CheckedListBox();
buttonAdd = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(52, 65);
labelName.Name = "labelName";
labelName.Size = new Size(34, 17);
labelName.TabIndex = 0;
labelName.Text = "Имя";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(21, 155);
label2.Name = "label2";
label2.Size = new Size(74, 17);
label2.TabIndex = 1;
label2.Text = "Должность";
//
// textBoxName
//
textBoxName.Location = new Point(110, 62);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(150, 25);
textBoxName.TabIndex = 2;
//
// checkedListBoxType
//
checkedListBoxType.FormattingEnabled = true;
checkedListBoxType.Location = new Point(110, 155);
checkedListBoxType.Name = "checkedListBoxType";
checkedListBoxType.Size = new Size(150, 104);
checkedListBoxType.TabIndex = 3;
//
// buttonAdd
//
buttonAdd.Location = new Point(52, 336);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(114, 40);
buttonAdd.TabIndex = 4;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += this.buttonAdd_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(227, 336);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(112, 40);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// FormEmployee
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(415, 408);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(checkedListBoxType);
Controls.Add(textBoxName);
Controls.Add(label2);
Controls.Add(labelName);
Name = "FormEmployee";
Text = "Employee";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label label2;
private TextBox textBoxName;
private CheckedListBox checkedListBoxType;
private Button buttonAdd;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,101 @@
using ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectGasStation.Forms
{
public partial class FormEmployee : Form
{
private readonly IEmployeeRepository _employeeRepository;
private int? _employeeId;
public int Id
{
set
{
try
{
var employee = _employeeRepository.ReadEmployeeById(value);
if (employee == null)
{
throw new
InvalidDataException(nameof(employee));
}
foreach (EmployeePost elem in Enum.GetValues(typeof(EmployeePost)))
{
if ((elem & employee.EmployeePost) != 0)
{
checkedListBoxType.SetItemChecked(checkedListBoxType.Items.IndexOf(elem), true);
}
}
textBoxName.Text = employee.Name;
_employeeId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormEmployee(IEmployeeRepository employeeRepository)
{
InitializeComponent();
_employeeRepository = employeeRepository ?? throw new ArgumentNullException(nameof(employeeRepository));
foreach(var elem in Enum.GetValues(typeof(EmployeePost)))
{
checkedListBoxType.Items.Add(elem);
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
if (checkedListBoxType.CheckedItems.Count == 0 ||
string.IsNullOrWhiteSpace(textBoxName.Text))
{
throw new Exception("Имеются незаполненные поля");
}
if (_employeeId.HasValue)
{
_employeeRepository.UpdateEmployee(CreateEmployee(_employeeId.Value));
}
else
{
_employeeRepository.CreateEmployee(CreateEmployee(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e) => Close();
private Employee CreateEmployee(int id)
{
EmployeePost employeePost = EmployeePost.None;
foreach (var elem in checkedListBoxType.CheckedItems)
{
employeePost |= (EmployeePost)elem;
}
return Employee.CreateEntity(id, textBoxName.Text, employeePost);
}
}
}

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->

View File

@ -0,0 +1,117 @@
namespace ProjectGasStation.Forms
{
partial class FormEmployees
{
/// <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()
{
dataGridView = new DataGridView();
panel1 = new Panel();
buttonUpdate = new Button();
buttonRemove = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
panel1.SuspendLayout();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 45;
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
//
// panel1
//
panel1.Controls.Add(buttonUpdate);
panel1.Controls.Add(buttonRemove);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(645, 0);
panel1.Name = "panel1";
panel1.Size = new Size(155, 450);
panel1.TabIndex = 1;
//
// buttonUpdate
//
buttonUpdate.BackgroundImage = Properties.Resources.edit;
buttonUpdate.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpdate.Location = new Point(35, 300);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(83, 75);
buttonUpdate.TabIndex = 2;
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.BackgroundImage = Properties.Resources.minus;
buttonRemove.BackgroundImageLayout = ImageLayout.Stretch;
buttonRemove.Location = new Point(35, 171);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(83, 75);
buttonRemove.TabIndex = 1;
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.plus1;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(35, 47);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(83, 75);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// FormEmployees
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(panel1);
Controls.Add(dataGridView);
Name = "FormEmployees";
Text = "FormEmployees";
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
panel1.ResumeLayout(false);
ResumeLayout(false);
Load += FormEmployees_Load;
}
#endregion
private DataGridView dataGridView;
private Panel panel1;
private Button buttonUpdate;
private Button buttonRemove;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,118 @@
using ProjectGasStation.Entities.Enums;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
namespace ProjectGasStation.Forms
{
public partial class FormEmployees : Form
{
private readonly IUnityContainer _container;
private readonly IEmployeeRepository _employeeRepository;
public FormEmployees(IUnityContainer container, IEmployeeRepository employeeRepository)
{
InitializeComponent();
_container = container ??
throw new
ArgumentNullException(nameof(container));
_employeeRepository = employeeRepository ??
throw new ArgumentNullException(nameof(employeeRepository));
}
private void FormEmployees_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource =
_employeeRepository.ReadEmployees();
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
return true;
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormEmployee>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление",
MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_employeeRepository.DeleteEmployee(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormEmployee>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
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,146 @@
namespace ProjectGasStation.Forms
{
partial class FormProduct
{
/// <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()
{
labelName = new Label();
labelPrice = new Label();
labelProductType = new Label();
textBoxProductName = new TextBox();
numericUpDownProductPrice = new NumericUpDown();
buttonSave = new Button();
buttonCancel = new Button();
comboBoxProductType = new ComboBox();
((System.ComponentModel.ISupportInitialize)numericUpDownProductPrice).BeginInit();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(26, 35);
labelName.Name = "labelName";
labelName.Size = new Size(111, 17);
labelName.TabIndex = 0;
labelName.Text = "Название товара";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(26, 88);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(108, 17);
labelPrice.TabIndex = 1;
labelPrice.Text = "Цена за единицу";
//
// labelProductType
//
labelProductType.AutoSize = true;
labelProductType.Location = new Point(26, 139);
labelProductType.Name = "labelProductType";
labelProductType.Size = new Size(75, 17);
labelProductType.TabIndex = 2;
labelProductType.Text = "Тип товара";
//
// textBoxProductName
//
textBoxProductName.Location = new Point(140, 35);
textBoxProductName.Name = "textBoxProductName";
textBoxProductName.Size = new Size(100, 25);
textBoxProductName.TabIndex = 3;
//
// numericUpDownProductPrice
//
numericUpDownProductPrice.DecimalPlaces = 3;
numericUpDownProductPrice.Location = new Point(140, 88);
numericUpDownProductPrice.Minimum = new decimal(new int[] { 1, 0, 0, 196608 });
numericUpDownProductPrice.Name = "numericUpDownProductPrice";
numericUpDownProductPrice.Size = new Size(120, 25);
numericUpDownProductPrice.TabIndex = 5;
numericUpDownProductPrice.Value = new decimal(new int[] { 1, 0, 0, 196608 });
//
// buttonSave
//
buttonSave.Location = new Point(41, 258);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(108, 41);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(203, 258);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(116, 41);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// comboBoxProductType
//
comboBoxProductType.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxProductType.FormattingEnabled = true;
comboBoxProductType.Location = new Point(139, 136);
comboBoxProductType.Name = "comboBoxProductType";
comboBoxProductType.Size = new Size(121, 25);
comboBoxProductType.TabIndex = 8;
//
// FormProduct
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(358, 335);
Controls.Add(comboBoxProductType);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(numericUpDownProductPrice);
Controls.Add(textBoxProductName);
Controls.Add(labelProductType);
Controls.Add(labelPrice);
Controls.Add(labelName);
Name = "FormProduct";
Text = "Товар";
((System.ComponentModel.ISupportInitialize)numericUpDownProductPrice).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelPrice;
private Label labelProductType;
private TextBox textBoxProductName;
private NumericUpDown numericUpDownProductPrice;
private Button buttonSave;
private Button buttonCancel;
private ComboBox comboBoxProductType;
}
}

View File

@ -0,0 +1,94 @@
using ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectGasStation.Forms
{
public partial class FormProduct : Form
{
private readonly IProductRepository _productRepository;
private int? _productId;
public int Id
{
set
{
try
{
var product = _productRepository.ReadProductById(value);
if (product == null)
{
throw new InvalidDataException(nameof(product));
}
textBoxProductName.Text = product.Name;
numericUpDownProductPrice.Value = (decimal)product.Price;
comboBoxProductType.SelectedItem = product.ProductType;
_productId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormProduct(IProductRepository productRepository)
{
InitializeComponent();
_productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
comboBoxProductType.DataSource = Enum.GetValues(typeof(ProductType));
}
private void buttonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxProductName.Text) || comboBoxProductType.SelectedIndex < 1)
{
throw new Exception("Имеются незаполненные поля");
}
if (_productId.HasValue)
{
_productRepository.UpdateProduct(CreateProduct(_productId.Value));
}
else
{
_productRepository.CreateProduct(CreateProduct(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e) => Close();
private Product CreateProduct(int id) => Product.CreateEntity(id, textBoxProductName.Text, (double)numericUpDownProductPrice.Value, (ProductType)comboBoxProductType.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,117 @@
namespace ProjectGasStation.Forms
{
partial class FormProducts
{
/// <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()
{
panel1 = new Panel();
buttonUpdate = new Button();
buttonDel = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(buttonUpdate);
panel1.Controls.Add(buttonDel);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(630, 0);
panel1.Name = "panel1";
panel1.Size = new Size(170, 450);
panel1.TabIndex = 0;
//
// buttonUpdate
//
buttonUpdate.BackgroundImage = Properties.Resources.edit;
buttonUpdate.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpdate.Location = new Point(40, 309);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(83, 73);
buttonUpdate.TabIndex = 2;
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonDel
//
buttonDel.BackgroundImage = Properties.Resources.minus;
buttonDel.BackgroundImageLayout = ImageLayout.Stretch;
buttonDel.Location = new Point(40, 186);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(83, 73);
buttonDel.TabIndex = 1;
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += buttonDel_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.plus1;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(40, 52);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(83, 73);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 45;
dataGridView.Size = new Size(630, 450);
dataGridView.TabIndex = 1;
//
// FormProducts
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Controls.Add(panel1);
Name = "FormProducts";
Text = "FormProducts";
panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
Load += FormProducts_Load;
}
#endregion
private Panel panel1;
private Button buttonUpdate;
private Button buttonDel;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,116 @@
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
namespace ProjectGasStation.Forms
{
public partial class FormProducts : Form
{
private readonly IUnityContainer _container;
private readonly IProductRepository _productRepository;
public FormProducts(IUnityContainer container, IProductRepository productRepository)
{
InitializeComponent();
_container = container ??
throw new ArgumentNullException(nameof(container));
_productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
}
private void FormProducts_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource = _productRepository.ReadProducts();
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FormProduct>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormProduct>();
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
{
_productRepository.DeleteProduct(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id =
Convert.ToInt32(dataGridView.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,196 @@
namespace ProjectGasStation.Forms
{
partial class FormPurchase
{
/// <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()
{
labelProduct = new Label();
labelSupplier = new Label();
labelQuantity = new Label();
dateTimePicker1 = new DateTimePicker();
labelDate = new Label();
labelPrice = new Label();
numericUpDown1 = new NumericUpDown();
numericUpDown2 = new NumericUpDown();
comboBoxProduct = new ComboBox();
comboBoxSupplier = new ComboBox();
buttonAdd = new Button();
buttonCancel = new Button();
((System.ComponentModel.ISupportInitialize)numericUpDown1).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDown2).BeginInit();
SuspendLayout();
//
// labelProduct
//
labelProduct.AutoSize = true;
labelProduct.Location = new Point(44, 39);
labelProduct.Name = "labelProduct";
labelProduct.Size = new Size(45, 17);
labelProduct.TabIndex = 0;
labelProduct.Text = "Товар";
//
// labelSupplier
//
labelSupplier.AutoSize = true;
labelSupplier.Location = new Point(46, 96);
labelSupplier.Name = "labelSupplier";
labelSupplier.Size = new Size(74, 17);
labelSupplier.TabIndex = 1;
labelSupplier.Text = "Поставщик";
//
// labelQuantity
//
labelQuantity.AutoSize = true;
labelQuantity.Location = new Point(46, 144);
labelQuantity.Name = "labelQuantity";
labelQuantity.Size = new Size(82, 17);
labelQuantity.TabIndex = 2;
labelQuantity.Text = "Количество ";
//
// dateTimePicker1
//
dateTimePicker1.Location = new Point(147, 242);
dateTimePicker1.Name = "dateTimePicker1";
dateTimePicker1.Size = new Size(221, 25);
dateTimePicker1.TabIndex = 3;
dateTimePicker1.ValueChanged += dateTimePicker1_ValueChanged;
//
// labelDate
//
labelDate.AutoSize = true;
labelDate.Location = new Point(44, 242);
labelDate.Name = "labelDate";
labelDate.Size = new Size(36, 17);
labelDate.TabIndex = 4;
labelDate.Text = "Дата";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(46, 197);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(39, 17);
labelPrice.TabIndex = 5;
labelPrice.Text = "Цена";
//
// numericUpDown1
//
numericUpDown1.DecimalPlaces = 2;
numericUpDown1.Location = new Point(147, 197);
numericUpDown1.Minimum = new decimal(new int[] { 1, 0, 0, 131072 });
numericUpDown1.Name = "numericUpDown1";
numericUpDown1.Size = new Size(132, 25);
numericUpDown1.TabIndex = 6;
numericUpDown1.Value = new decimal(new int[] { 1, 0, 0, 131072 });
//
// numericUpDown2
//
numericUpDown2.DecimalPlaces = 3;
numericUpDown2.Location = new Point(147, 144);
numericUpDown2.Minimum = new decimal(new int[] { 1, 0, 0, 196608 });
numericUpDown2.Name = "numericUpDown2";
numericUpDown2.Size = new Size(132, 25);
numericUpDown2.TabIndex = 7;
numericUpDown2.Value = new decimal(new int[] { 1, 0, 0, 196608 });
//
// comboBoxProduct
//
comboBoxProduct.FormattingEnabled = true;
comboBoxProduct.Location = new Point(147, 39);
comboBoxProduct.Name = "comboBoxProduct";
comboBoxProduct.Size = new Size(134, 25);
comboBoxProduct.TabIndex = 8;
//
// comboBoxSupplier
//
comboBoxSupplier.FormattingEnabled = true;
comboBoxSupplier.Location = new Point(147, 96);
comboBoxSupplier.Name = "comboBoxSupplier";
comboBoxSupplier.Size = new Size(134, 25);
comboBoxSupplier.TabIndex = 9;
//
// buttonAdd
//
buttonAdd.Location = new Point(45, 388);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(123, 42);
buttonAdd.TabIndex = 10;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += this.buttonAdd_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(227, 388);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(115, 42);
buttonCancel.TabIndex = 11;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += this.buttonCancel_Click;
//
// FormPurchase
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(398, 485);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(comboBoxSupplier);
Controls.Add(comboBoxProduct);
Controls.Add(numericUpDown2);
Controls.Add(numericUpDown1);
Controls.Add(labelPrice);
Controls.Add(labelDate);
Controls.Add(dateTimePicker1);
Controls.Add(labelQuantity);
Controls.Add(labelSupplier);
Controls.Add(labelProduct);
Name = "FormPurchase";
Text = "FormPurchases";
((System.ComponentModel.ISupportInitialize)numericUpDown1).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDown2).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelProduct;
private Label labelSupplier;
private Label labelQuantity;
private DateTimePicker dateTimePicker1;
private Label labelDate;
private Label labelPrice;
private NumericUpDown numericUpDown1;
private NumericUpDown numericUpDown2;
private ComboBox comboBoxProduct;
private ComboBox comboBoxSupplier;
private Button buttonAdd;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,95 @@
using ProjectGasStation.Entities;
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectGasStation.Forms
{
public partial class FormPurchase : Form
{
private readonly IPurchaseRepository _purchaseRepository;
private int? _purchaseId;
public int Id
{
set
{
try
{
var purchase =
_purchaseRepository.ReadPurchaseById(value);
if (purchase == null)
{
throw new
InvalidDataException(nameof(purchase));
}
comboBoxProduct.SelectedValue = purchase.ProductId;
comboBoxSupplier.SelectedValue = purchase.SupplierId;
numericUpDown1.Value = (decimal)purchase.Price;
numericUpDown2.Value = (decimal)purchase.Quantity;
_purchaseId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormPurchase(IPurchaseRepository purchaseRepository, IProductRepository productRepository, ISupplierRepository supplierRepository)
{
InitializeComponent();
_purchaseRepository = purchaseRepository ?? throw new ArgumentNullException(nameof(purchaseRepository));
comboBoxProduct.DataSource = productRepository.ReadProducts();
comboBoxProduct.DisplayMember = "Name";
comboBoxProduct.ValueMember = "Id";
comboBoxSupplier.DataSource = supplierRepository.ReadSuppliers();
comboBoxSupplier.DisplayMember = "Name";
comboBoxSupplier.ValueMember = "Id";
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
if (comboBoxProduct.SelectedIndex < 0 || comboBoxSupplier.SelectedIndex < 0)
{
throw new Exception("Имеются незаполненные поля");
}
if (_purchaseId.HasValue)
{
_purchaseRepository.UpdatePurchase(CreatePurchase(_purchaseId.Value));
}
else
{
_purchaseRepository.CreatePurchase(CreatePurchase(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e) => Close();
private Purchase CreatePurchase(int id) => Purchase.CreateOperation(id, Convert.ToInt32(comboBoxProduct.SelectedValue),
Convert.ToInt32(comboBoxSupplier.SelectedValue), (double)numericUpDown2.Value, dateTimePicker1.Value, (double)numericUpDown1.Value);
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
}
}
}

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 ProjectGasStation.Forms
{
partial class FormPurchases
{
/// <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()
{
dataGridView1 = new DataGridView();
panel1 = new Panel();
buttonUpdate = new Button();
buttonAdd = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
panel1.SuspendLayout();
SuspendLayout();
//
// dataGridView1
//
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView1.Dock = DockStyle.Fill;
dataGridView1.Location = new Point(0, 0);
dataGridView1.Name = "dataGridView1";
dataGridView1.RowHeadersWidth = 45;
dataGridView1.Size = new Size(800, 397);
dataGridView1.TabIndex = 0;
//
// panel1
//
panel1.Controls.Add(buttonUpdate);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(647, 0);
panel1.Name = "panel1";
panel1.Size = new Size(153, 397);
panel1.TabIndex = 1;
//
// buttonUpdate
//
buttonUpdate.BackgroundImage = Properties.Resources.edit;
buttonUpdate.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpdate.Location = new Point(32, 237);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(83, 66);
buttonUpdate.TabIndex = 1;
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.plus1;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(32, 74);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(83, 66);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// FormPurchases
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 397);
Controls.Add(panel1);
Controls.Add(dataGridView1);
Name = "FormPurchases";
Text = "FormPurchase";
Load += FormPurchases_Load;
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
panel1.ResumeLayout(false);
ResumeLayout(false);
}
private void F(object sender, EventArgs e)
{
throw new NotImplementedException();
}
#endregion
private DataGridView dataGridView1;
private Panel panel1;
private Button buttonUpdate;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,86 @@
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
namespace ProjectGasStation.Forms;
public partial class FormPurchases : Form
{
private readonly IUnityContainer _container;
private readonly IPurchaseRepository _purchaseRepository;
public FormPurchases(IUnityContainer container, IPurchaseRepository purchaseRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_purchaseRepository = purchaseRepository ?? throw new ArgumentNullException(nameof(_purchaseRepository));
}
private void FormPurchases_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<FormPurchase>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormPurchase>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView1.DataSource = _purchaseRepository.ReadPurchases();
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView1.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridView1.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,154 @@
namespace ProjectGasStation.Forms
{
partial class FormSale
{
/// <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()
{
labelEmployee = new Label();
dateTimePicker1 = new DateTimePicker();
label1 = new Label();
dataGridView1 = new DataGridView();
buttonAdd = new Button();
buttonCancel = new Button();
comboBoxEmployee = new ComboBox();
ColumnProduct = new DataGridViewComboBoxColumn();
ColumnQuantity = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
SuspendLayout();
//
// labelEmployee
//
labelEmployee.AutoSize = true;
labelEmployee.Location = new Point(12, 26);
labelEmployee.Name = "labelEmployee";
labelEmployee.Size = new Size(66, 15);
labelEmployee.TabIndex = 0;
labelEmployee.Text = "Сотрудник";
//
// dateTimePicker1
//
dateTimePicker1.Location = new Point(58, 64);
dateTimePicker1.Name = "dateTimePicker1";
dateTimePicker1.Size = new Size(221, 23);
dateTimePicker1.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 64);
label1.Name = "label1";
label1.Size = new Size(32, 15);
label1.TabIndex = 2;
label1.Text = "Дата";
//
// dataGridView1
//
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { ColumnProduct, ColumnQuantity });
dataGridView1.Location = new Point(12, 174);
dataGridView1.Name = "dataGridView1";
dataGridView1.RowHeadersWidth = 45;
dataGridView1.Size = new Size(267, 290);
dataGridView1.TabIndex = 3;
dataGridView1.CellContentClick += dataGridView1_CellContentClick;
//
// buttonAdd
//
buttonAdd.Location = new Point(12, 490);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(115, 38);
buttonAdd.TabIndex = 4;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(164, 490);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(115, 38);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// comboBoxEmployee
//
comboBoxEmployee.FormattingEnabled = true;
comboBoxEmployee.Location = new Point(88, 26);
comboBoxEmployee.Name = "comboBoxEmployee";
comboBoxEmployee.Size = new Size(193, 23);
comboBoxEmployee.TabIndex = 6;
//
// ColumnProduct
//
ColumnProduct.HeaderText = "Товар";
ColumnProduct.MinimumWidth = 6;
ColumnProduct.Name = "ColumnProduct";
ColumnProduct.Resizable = DataGridViewTriState.True;
ColumnProduct.SortMode = DataGridViewColumnSortMode.Automatic;
ColumnProduct.Width = 110;
//
// ColumnQuantity
//
ColumnQuantity.HeaderText = "Количество";
ColumnQuantity.MinimumWidth = 6;
ColumnQuantity.Name = "ColumnQuantity";
ColumnQuantity.Width = 110;
//
// FormSale
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(293, 549);
Controls.Add(comboBoxEmployee);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(dataGridView1);
Controls.Add(label1);
Controls.Add(dateTimePicker1);
Controls.Add(labelEmployee);
Name = "FormSale";
Text = "FormSale";
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelEmployee;
private DateTimePicker dateTimePicker1;
private Label label1;
private DataGridView dataGridView1;
private Button buttonAdd;
private Button buttonCancel;
private ComboBox comboBoxEmployee;
private DataGridViewComboBoxColumn ColumnProduct;
private DataGridViewTextBoxColumn ColumnQuantity;
}
}

View File

@ -0,0 +1,67 @@
using ProjectGasStation.Entities;
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectGasStation.Forms;
public partial class FormSale : Form
{
private readonly ISaleRepository _saleRepository;
public FormSale(ISaleRepository saleRepository, IProductRepository productRepository, IEmployeeRepository employeeRepository)
{
InitializeComponent();
_saleRepository = saleRepository ?? throw new ArgumentNullException(nameof(saleRepository));
comboBoxEmployee.DataSource = employeeRepository.ReadEmployees();
comboBoxEmployee.DisplayMember = "Iв";
comboBoxEmployee.ValueMember = "Id";
ColumnProduct.DataSource = productRepository.ReadProducts();
ColumnProduct.DisplayMember = "Id";
ColumnProduct.ValueMember = "Id";
}
private void buttonAdd_Click(object sender, EventArgs e)
{
//if (dataGridView1.RowCount < 1 || comboBoxEmployee.SelectedIndex < 0 || dateTimePicker1.CustomFormat != " ")
//{
// throw new Exception("Имеются незаполненны поля");
//}
try
{
_saleRepository.CreateSale(Sale.CreateOperation(0, Convert.ToInt32(comboBoxEmployee.SelectedValue), dateTimePicker1.Value, CreateListProductFromDataGrid()));
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e) => Close();
private List<SaleProduct> CreateListProductFromDataGrid()
{
var list = new List<SaleProduct>();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
list.Add(SaleProduct.CreateOperation(0, Convert.ToInt32(row.Cells["ColumnProduct"].Value), Convert.ToDouble(row.Cells["ColumnQuantity"].Value)));
}
list.RemoveAt(list.Count - 1);
return list;
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
}

View File

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

View File

@ -0,0 +1,103 @@
namespace ProjectGasStation.Forms
{
partial class FormSales
{
/// <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()
{
panel1 = new Panel();
buttonAdd = new Button();
dataGridView = new DataGridView();
buttonDelete = new Button();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(buttonDelete);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(626, 0);
panel1.Name = "panel1";
panel1.Size = new Size(174, 397);
panel1.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.plus1;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(42, 44);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(96, 83);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 45;
dataGridView.Size = new Size(626, 397);
dataGridView.TabIndex = 1;
//
// buttonDelete
//
buttonDelete.BackgroundImage = Properties.Resources.minus;
buttonDelete.BackgroundImageLayout = ImageLayout.Stretch;
buttonDelete.Location = new Point(42, 240);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(96, 83);
buttonDelete.TabIndex = 1;
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// FormSales
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 397);
Controls.Add(dataGridView);
Controls.Add(panel1);
Name = "FormSales";
Text = "Sales";
Load += FormSales_Load;
panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Panel panel1;
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonDelete;
}
}

View File

@ -0,0 +1,84 @@
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
namespace ProjectGasStation.Forms;
public partial class FormSales : Form
{
private readonly IUnityContainer _container;
private readonly ISaleRepository _saleRepository;
public FormSales(IUnityContainer container, ISaleRepository saleRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_saleRepository = saleRepository ?? throw new ArgumentNullException(nameof(saleRepository));
}
private void FormSales_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<FormSale>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource = _saleRepository.ReadSales();
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
return true;
}
private void buttonDelete_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_saleRepository.DeleteSale(findId);
LoadList();
}
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,128 @@
namespace ProjectGasStation.Forms
{
partial class FormSupplier
{
/// <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()
{
labelName = new Label();
label1 = new Label();
labelINN = new Label();
textBoxName = new TextBox();
textBoxINN = new TextBox();
buttonAdd = new Button();
button2 = new Button();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(43, 63);
labelName.Name = "labelName";
labelName.Size = new Size(65, 17);
labelName.TabIndex = 0;
labelName.Text = "Название";
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(43, 125);
label1.Name = "label1";
label1.Size = new Size(0, 17);
label1.TabIndex = 1;
//
// labelINN
//
labelINN.AutoSize = true;
labelINN.Location = new Point(49, 119);
labelINN.Name = "labelINN";
labelINN.Size = new Size(36, 17);
labelINN.TabIndex = 2;
labelINN.Text = "ИНН";
//
// textBoxName
//
textBoxName.Location = new Point(144, 65);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(110, 25);
textBoxName.TabIndex = 3;
//
// textBoxINN
//
textBoxINN.Location = new Point(145, 116);
textBoxINN.Name = "textBoxINN";
textBoxINN.Size = new Size(110, 25);
textBoxINN.TabIndex = 4;
//
// buttonAdd
//
buttonAdd.Location = new Point(25, 243);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(97, 32);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// button2
//
button2.Location = new Point(170, 243);
button2.Name = "button2";
button2.Size = new Size(97, 32);
button2.TabIndex = 6;
button2.Text = "Отмена";
button2.UseVisualStyleBackColor = true;
button2.Click += button2_Click;
//
// FormSupplier
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(299, 307);
Controls.Add(button2);
Controls.Add(buttonAdd);
Controls.Add(textBoxINN);
Controls.Add(textBoxName);
Controls.Add(labelINN);
Controls.Add(label1);
Controls.Add(labelName);
Name = "FormSupplier";
Text = "FormSupplier";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label label1;
private Label labelINN;
private TextBox textBoxName;
private TextBox textBoxINN;
private Button buttonAdd;
private Button button2;
}
}

View File

@ -0,0 +1,77 @@
using ProjectGasStation.Entities;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectGasStation.Forms
{
public partial class FormSupplier : Form
{
private readonly ISupplierRepository _supplierRepository;
private int? _supplierId;
public int Id
{
set
{
try
{
var supplier = _supplierRepository.ReadSupplierById(value);
if (supplier == null)
{
throw new InvalidDataException(nameof(supplier));
}
textBoxName.Text = supplier.Name;
textBoxINN.Text = supplier.INN;
_supplierId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при получении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FormSupplier(ISupplierRepository supplierRepository)
{
InitializeComponent();
_supplierRepository = supplierRepository ?? throw new ArgumentNullException(nameof(supplierRepository));
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxName.Text) || string.IsNullOrWhiteSpace(textBoxINN.Text))
{
throw new Exception("Имеются незаполненные поля");
}
if (_supplierId.HasValue)
{
_supplierRepository.UpdateSupplier(CreateSupplier(_supplierId.Value));
}
else
{
_supplierRepository.CreateSupplier(CreateSupplier(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button2_Click(object sender, EventArgs e) => Close();
private Supplier CreateSupplier(int id) => Supplier.CreateEntity(id, textBoxName.Text, textBoxINN.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,117 @@
namespace ProjectGasStation.Forms
{
partial class FormSuppliers
{
/// <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()
{
panel1 = new Panel();
buttonUpdate = new Button();
buttonRemove = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(buttonUpdate);
panel1.Controls.Add(buttonRemove);
panel1.Controls.Add(buttonAdd);
panel1.Dock = DockStyle.Right;
panel1.Location = new Point(660, 0);
panel1.Name = "panel1";
panel1.Size = new Size(140, 450);
panel1.TabIndex = 0;
//
// buttonUpdate
//
buttonUpdate.BackgroundImage = Properties.Resources.edit;
buttonUpdate.BackgroundImageLayout = ImageLayout.Stretch;
buttonUpdate.Location = new Point(30, 282);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(83, 73);
buttonUpdate.TabIndex = 2;
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.BackgroundImage = Properties.Resources.minus;
buttonRemove.BackgroundImageLayout = ImageLayout.Stretch;
buttonRemove.Location = new Point(30, 167);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(83, 73);
buttonRemove.TabIndex = 1;
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonAdd
//
buttonAdd.BackgroundImage = Properties.Resources.plus1;
buttonAdd.BackgroundImageLayout = ImageLayout.Stretch;
buttonAdd.Location = new Point(30, 46);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(83, 73);
buttonAdd.TabIndex = 0;
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 45;
dataGridView.Size = new Size(660, 450);
dataGridView.TabIndex = 1;
//
// FormSuppliers
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Controls.Add(panel1);
Name = "FormSuppliers";
Text = "FormSuppliers";
panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
Load += FormSuppliers_Load;
}
#endregion
private Panel panel1;
private Button buttonUpdate;
private Button buttonRemove;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,107 @@
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
namespace ProjectGasStation.Forms
{
public partial class FormSuppliers : Form
{
private readonly IUnityContainer _container;
private readonly ISupplierRepository _supplierRepository;
public FormSuppliers(IUnityContainer container, ISupplierRepository supplierRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_supplierRepository = supplierRepository ?? throw new ArgumentNullException(nameof(supplierRepository));
}
private void FormSuppliers_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<FormSupplier>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_supplierRepository.DeleteSupplier(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FormSupplier>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList() => dataGridView.DataSource = _supplierRepository.ReadSuppliers();
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridView.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,14 @@
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;
namespace ProjectGasStation.Implementations;
internal class ConnectionString : IConnectionString
{
string IConnectionString.ConnectionString => "Server=localhost;Port=5432;Database=GasStation;Username=postgres;Password=525252;";
}

View File

@ -0,0 +1,136 @@
using Microsoft.Extensions.Logging;
using ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Data.SqlClient;
using Dapper;
using Npgsql;
namespace ProjectGasStation.Implementations;
public class EmployeeRepository : IEmployeeRepository
{
private readonly IConnectionString _connectionstring;
private readonly ILogger<EmployeeRepository> _logger;
public EmployeeRepository(IConnectionString connectionString, ILogger<EmployeeRepository> logger)
{
_connectionstring = connectionString;
_logger = logger;
}
public void CreateEmployee(Employee employee)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(employee));
try
{
using var connection = new NpgsqlConnection(_connectionstring.ConnectionString);
connection.Open();
var queryInsert = @"
INSERT INTO Employees (Name, EmployeePost)
VALUES (@Name, @EmployeePost)";
connection.Execute(queryInsert, employee);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void UpdateEmployee(Employee employee)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(employee));
try
{
using var connection = new NpgsqlConnection(_connectionstring.ConnectionString);
var queryUpdate = @"
UPDATE Employees
SET
Name=@Name,
EmployeePost=@EmployeePost
WHERE Id=@Id";
connection.Execute(queryUpdate, employee);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public void DeleteEmployee(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionstring.ConnectionString);
connection.Open();
var queryDelete = @"
DELETE FROM Employees
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Employee ReadEmployeeById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionstring.ConnectionString);
var querySelect = @"
SELECT * FROM Employees
WHERE Id=@id";
var employee = connection.QueryFirst<Employee>(querySelect, new { id });
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(employee));
return employee;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Employee> ReadEmployees()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionstring.ConnectionString);
var querySelect = "SELECT * FROM Employees";
var employees = connection.Query<Employee>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(employees));
return employees;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}

View File

@ -0,0 +1,128 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectGasStation.Entities;
using ProjectGasStation.Entities.Enums;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
namespace ProjectGasStation.Implementations;
public class ProductRepository : IProductRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ProductRepository> _logger;
public ProductRepository(IConnectionString connectionString, ILogger<ProductRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateProduct(Product product)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Products (Name, Price, ProductType)
VALUES (@Name, @Price, @ProductType)";
connection.Execute(queryInsert, product);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteProduct(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Products
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Product ReadProductById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Products
WHERE Id=@id";
var product = connection.QueryFirst<Product>(querySelect, new
{
id
});
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(product));
return product;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Product> ReadProducts()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Products";
var products = connection.Query<Product>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(products));
return products;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdateProduct(Product product)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Products
SET
Name=@Name,
Price=@Price,
ProductType=@ProductType
WHERE Id=@Id";
connection.Execute(queryUpdate, product);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectGasStation.Entities;
using ProjectGasStation.Repositories;
using Dapper;
namespace ProjectGasStation.Implementations;
public class PurchaseRepository : IPurchaseRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<Purchase> _logger;
public PurchaseRepository(IConnectionString connectionString, ILogger<Purchase> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreatePurchase(Purchase purchase)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(purchase));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Purchases (ProductId, SupplierId, Quantity, PurchaseDate, Price)
VALUES (@ProductId, @SupplierId, @Quantity, @PurchaseDate, @Price)";
connection.Execute(queryInsert, purchase);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public IEnumerable<Purchase> ReadPurchases()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM Purchases";
var purchase = connection.Query<Purchase>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(purchase));
return purchase;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdatePurchase(Purchase purchase)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(purchase));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Purchases
SET
ProductId=@ProductId,
SupplierId=@SupplierId,
Quantity=@Quantity,
PurchaseDate=@PurchaseDate,
Price=@Price
WHERE Id=@Id";
connection.Execute(queryUpdate, purchase);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
public Purchase ReadPurchaseById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Purchases
WHERE Id=@id";
var purchase = connection.QueryFirst<Purchase>(querySelect, new
{
id
});
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(purchase));
return purchase;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
}

View File

@ -0,0 +1,109 @@
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectGasStation.Entities;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Implementations;
public class SaleRepository : ISaleRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<Sale> _logger;
public SaleRepository(IConnectionString connectionString, ILogger<Sale> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateSale(Sale sale)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(sale));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryInsert = @"
INSERT INTO Sales (EmployeeId, SaleDate)
VALUES (@EmployeeId, @SaleDate);
SELECT MAX(Id) FROM Sales";
var saleId = connection.QueryFirst<int>(queryInsert, sale, transaction);
var querySubInsert = @"
INSERT INTO SaleProduct (SaleId, ProductId, Quantity)
VALUES (@SaleId, @ProductId, @Quantity)";
foreach (var elem in sale.SaleProducts)
{
connection.Execute(querySubInsert, new
{
saleId,
elem.ProductId,
elem.Quantity
}, transaction);
}
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public IEnumerable<Sale> ReadSales(DateTime? dateFrom = null, DateTime? dateTo = null, int? employeeId = null)
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT * FROM Sales";
var sale = connection.Query<Sale>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(sale));
return sale;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void DeleteSale(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
// Сначала удаляем связанные записи из SaleProduct
var queryDeleteSaleProduct = @"
DELETE FROM SaleProduct
WHERE SaleId = @id";
connection.Execute(queryDeleteSaleProduct, new { id }, transaction);
// Теперь можно удалить саму продажу
var queryDeleteSale = @"
DELETE FROM Sales
WHERE Id = @id";
connection.Execute(queryDeleteSale, new { id }, transaction);
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
}

View File

@ -0,0 +1,125 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectGasStation.Entities;
using ProjectGasStation.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
namespace ProjectGasStation.Implementations;
public class SupplierRepository : ISupplierRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<SupplierRepository> _logger;
public SupplierRepository(IConnectionString connectionString, ILogger<SupplierRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateSupplier(Supplier supplier)
{
_logger.LogInformation("Добавление объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(supplier));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Suppliers (Name, inn)
VALUES (@Name, @inn)";
connection.Execute(queryInsert, supplier);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта");
throw;
}
}
public void DeleteSupplier(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Suppliers
WHERE Id=@id";
connection.Execute(queryDelete, new { id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
public Supplier ReadSupplierById(int id)
{
_logger.LogInformation("Получение объекта по идентификатору");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Suppliers
WHERE Id=@id";
var supplier = connection.QueryFirst<Supplier>(querySelect, new
{
id
});
_logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(supplier));
return supplier;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске объекта");
throw;
}
}
public IEnumerable<Supplier> ReadSuppliers()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Suppliers";
var suppliers = connection.Query<Supplier>(querySelect);
_logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(suppliers));
return suppliers;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
public void UpdateSupplier(Supplier supplier)
{
_logger.LogInformation("Редактирование объекта");
_logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(supplier));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Suppliers
SET
Name=@Name,
inn=@inn
WHERE Id=@Id";
connection.Execute(queryUpdate, supplier);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании объекта");
throw;
}
}
}

View File

@ -1,3 +1,14 @@
using ProjectGasStation.Implementations;
using ProjectGasStation.Repositories;
using Unity;
using Unity.Lifetime;
using Serilog;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Unity.Microsoft.Logging;
using Newtonsoft.Json;
namespace ProjectGasStation namespace ProjectGasStation
{ {
internal static class Program internal static class Program
@ -11,7 +22,36 @@ namespace ProjectGasStation
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.Run(new Form1()); Application.Run(CreateUnityContainer().Resolve<FormGasStation>());
}
private static IUnityContainer CreateUnityContainer()
{
var container = new UnityContainer();
container.AddExtension(new LoggingExtension(CreateLoggerFactory()));
container.RegisterType<IEmployeeRepository, EmployeeRepository>(new TransientLifetimeManager());
container.RegisterType<IProductRepository, ProductRepository>(new TransientLifetimeManager());
container.RegisterType<IPurchaseRepository, PurchaseRepository>(new TransientLifetimeManager());
container.RegisterType<ISaleRepository, SaleRepository>(new TransientLifetimeManager());
container.RegisterType<ISupplierRepository, SupplierRepository>(new TransientLifetimeManager());
container.RegisterType<IConnectionString, ConnectionString>(new TransientLifetimeManager());
return container;
}
private static LoggerFactory CreateLoggerFactory()
{
var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
return loggerFactory;
} }
} }
} }

View File

@ -2,10 +2,42 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<SupportedOSPlatformVersion>8.0</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<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="8.0.5" />
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.9.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<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>
</Project> </Project>

View File

@ -0,0 +1,113 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ProjectGasStation.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("ProjectGasStation.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 edit {
get {
object obj = ResourceManager.GetObject("edit", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap minus {
get {
object obj = ResourceManager.GetObject("minus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap plus {
get {
object obj = ResourceManager.GetObject("plus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap plus1 {
get {
object obj = ResourceManager.GetObject("plus1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Union_76_Gas_Station {
get {
object obj = ResourceManager.GetObject("Union_76_Gas_Station", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,136 @@
<?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="minus" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\minus.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="plus1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\plus.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="plus" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\plus.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Union_76_Gas_Station" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Union_76_Gas_Station.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="edit" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\edit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface IConnectionString
{
public string ConnectionString { get; }
}

View File

@ -0,0 +1,21 @@
using ProjectGasStation.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface IEmployeeRepository
{
IEnumerable<Employee> ReadEmployees();
Employee ReadEmployeeById(int id);
void CreateEmployee(Employee employee);
void UpdateEmployee(Employee employee);
void DeleteEmployee(int id);
}

View File

@ -0,0 +1,21 @@
using ProjectGasStation.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface IProductRepository
{
IEnumerable<Product> ReadProducts();
Product ReadProductById(int id);
void CreateProduct(Product product);
void UpdateProduct(Product product);
void DeleteProduct(int id);
}

View File

@ -0,0 +1,18 @@
using ProjectGasStation.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface IPurchaseRepository
{
IEnumerable<Purchase> ReadPurchases();
Purchase ReadPurchaseById(int id);
void CreatePurchase(Purchase purchase);
void UpdatePurchase(Purchase purchase);
}

View File

@ -0,0 +1,17 @@
using ProjectGasStation.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface ISaleRepository
{
IEnumerable<Sale> ReadSales(DateTime? dateFrom = null, DateTime? dateTo = null, int? employeeId = null);
void DeleteSale(int id);
void CreateSale(Sale sale);
}

View File

@ -0,0 +1,21 @@
using ProjectGasStation.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectGasStation.Repositories;
public interface ISupplierRepository
{
IEnumerable<Supplier> ReadSuppliers();
Supplier ReadSupplierById(int id);
void CreateSupplier(Supplier supplier);
void UpdateSupplier(Supplier supplier);
void DeleteSupplier(int id);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

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