first commit
This commit is contained in:
commit
1c822aa386
1
.vs/Neshina1703.csproj.dtbcache.json
Normal file
1
.vs/Neshina1703.csproj.dtbcache.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"RootPath":"C:\\Users\\Student\\ISP31\\Neshina1703","ProjectFileName":"Neshina1703.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"AdminForm.cs"},{"SourceFile":"AdminForm.Designer.cs"},{"SourceFile":"ClientForm.cs"},{"SourceFile":"ClientForm.Designer.cs"},{"SourceFile":"DB.cs"},{"SourceFile":"EmployeeForm.cs"},{"SourceFile":"EmployeeForm.Designer.cs"},{"SourceFile":"Form1.cs"},{"SourceFile":"Form1.Designer.cs"},{"SourceFile":"OrderForm.cs"},{"SourceFile":"OrderForm.Designer.cs"},{"SourceFile":"ProductForm.cs"},{"SourceFile":"ProductForm.Designer.cs"},{"SourceFile":"Program.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"Properties\\Settings.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.7.2.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\Student\\Downloads\\mysql.data\\MySql.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Deployment.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Drawing.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Windows.Forms.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Users\\Student\\ISP31\\Neshina1703\\bin\\Debug\\Neshina1703.exe","OutputItemRelativePath":"Neshina1703.exe"},{"OutputItemFullPath":"C:\\Users\\Student\\ISP31\\Neshina1703\\bin\\Debug\\Neshina1703.pdb","OutputItemRelativePath":"Neshina1703.pdb"}],"CopyToOutputEntries":[]}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.vs/Neshina1703/v17/.suo
Normal file
BIN
.vs/Neshina1703/v17/.suo
Normal file
Binary file not shown.
BIN
.vs/Neshina1703/v17/TestStore/0/000.testlog
Normal file
BIN
.vs/Neshina1703/v17/TestStore/0/000.testlog
Normal file
Binary file not shown.
BIN
.vs/Neshina1703/v17/TestStore/0/testlog.manifest
Normal file
BIN
.vs/Neshina1703/v17/TestStore/0/testlog.manifest
Normal file
Binary file not shown.
319
AdminForm.Designer.cs
generated
Normal file
319
AdminForm.Designer.cs
generated
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class AdminForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.TabControl tabControl;
|
||||||
|
private System.Windows.Forms.TabPage tabProducts;
|
||||||
|
private System.Windows.Forms.TabPage tabOrders;
|
||||||
|
private System.Windows.Forms.DataGridView dgvProducts;
|
||||||
|
private System.Windows.Forms.DataGridView dgvOrders;
|
||||||
|
private System.Windows.Forms.Button btnAddProduct;
|
||||||
|
private System.Windows.Forms.Button btnEditProduct;
|
||||||
|
private System.Windows.Forms.Button btnDeleteProduct;
|
||||||
|
private System.Windows.Forms.Button btnRefresh;
|
||||||
|
private System.Windows.Forms.Button btnLogout;
|
||||||
|
private System.Windows.Forms.Label lblUser;
|
||||||
|
private System.Windows.Forms.TextBox txtSearch;
|
||||||
|
private System.Windows.Forms.ComboBox cbFilterStatus;
|
||||||
|
private System.Windows.Forms.ComboBox cbFilterSupplier;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||||
|
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||||
|
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||||
|
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdminForm));
|
||||||
|
this.tabControl = new System.Windows.Forms.TabControl();
|
||||||
|
this.tabProducts = new System.Windows.Forms.TabPage();
|
||||||
|
this.dgvProducts = new System.Windows.Forms.DataGridView();
|
||||||
|
this.txtSearch = new System.Windows.Forms.TextBox();
|
||||||
|
this.cbFilterStatus = new System.Windows.Forms.ComboBox();
|
||||||
|
this.cbFilterSupplier = new System.Windows.Forms.ComboBox();
|
||||||
|
this.btnAddProduct = new System.Windows.Forms.Button();
|
||||||
|
this.btnEditProduct = new System.Windows.Forms.Button();
|
||||||
|
this.btnDeleteProduct = new System.Windows.Forms.Button();
|
||||||
|
this.btnRefresh = new System.Windows.Forms.Button();
|
||||||
|
this.tabOrders = new System.Windows.Forms.TabPage();
|
||||||
|
this.dgvOrders = new System.Windows.Forms.DataGridView();
|
||||||
|
this.btnLogout = new System.Windows.Forms.Button();
|
||||||
|
this.lblUser = new System.Windows.Forms.Label();
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.tabControl.SuspendLayout();
|
||||||
|
this.tabProducts.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).BeginInit();
|
||||||
|
this.tabOrders.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrders)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// tabControl
|
||||||
|
//
|
||||||
|
this.tabControl.Controls.Add(this.tabProducts);
|
||||||
|
this.tabControl.Controls.Add(this.tabOrders);
|
||||||
|
this.tabControl.Location = new System.Drawing.Point(12, 45);
|
||||||
|
this.tabControl.Name = "tabControl";
|
||||||
|
this.tabControl.SelectedIndex = 0;
|
||||||
|
this.tabControl.Size = new System.Drawing.Size(768, 380);
|
||||||
|
this.tabControl.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// tabProducts
|
||||||
|
//
|
||||||
|
this.tabProducts.Controls.Add(this.button1);
|
||||||
|
this.tabProducts.Controls.Add(this.dgvProducts);
|
||||||
|
this.tabProducts.Controls.Add(this.txtSearch);
|
||||||
|
this.tabProducts.Controls.Add(this.cbFilterStatus);
|
||||||
|
this.tabProducts.Controls.Add(this.cbFilterSupplier);
|
||||||
|
this.tabProducts.Controls.Add(this.btnAddProduct);
|
||||||
|
this.tabProducts.Controls.Add(this.btnEditProduct);
|
||||||
|
this.tabProducts.Controls.Add(this.btnDeleteProduct);
|
||||||
|
this.tabProducts.Controls.Add(this.btnRefresh);
|
||||||
|
this.tabProducts.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabProducts.Name = "tabProducts";
|
||||||
|
this.tabProducts.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabProducts.Size = new System.Drawing.Size(760, 354);
|
||||||
|
this.tabProducts.TabIndex = 0;
|
||||||
|
this.tabProducts.Text = "Товары";
|
||||||
|
this.tabProducts.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// dgvProducts
|
||||||
|
//
|
||||||
|
this.dgvProducts.AllowUserToAddRows = false;
|
||||||
|
this.dgvProducts.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvProducts.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvProducts.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||||
|
dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
dataGridViewCellStyle1.ForeColor = System.Drawing.Color.Black;
|
||||||
|
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||||
|
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||||
|
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||||
|
this.dgvProducts.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
|
||||||
|
this.dgvProducts.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||||
|
dataGridViewCellStyle2.BackColor = System.Drawing.Color.White;
|
||||||
|
dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||||
|
dataGridViewCellStyle2.ForeColor = System.Drawing.Color.Black;
|
||||||
|
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||||
|
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||||
|
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
|
||||||
|
this.dgvProducts.DefaultCellStyle = dataGridViewCellStyle2;
|
||||||
|
this.dgvProducts.Location = new System.Drawing.Point(6, 32);
|
||||||
|
this.dgvProducts.Name = "dgvProducts";
|
||||||
|
this.dgvProducts.ReadOnly = true;
|
||||||
|
this.dgvProducts.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvProducts.Size = new System.Drawing.Size(748, 270);
|
||||||
|
this.dgvProducts.TabIndex = 3;
|
||||||
|
this.dgvProducts.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvProducts_CellDoubleClick);
|
||||||
|
//
|
||||||
|
// txtSearch
|
||||||
|
//
|
||||||
|
this.txtSearch.Location = new System.Drawing.Point(6, 6);
|
||||||
|
this.txtSearch.Name = "txtSearch";
|
||||||
|
this.txtSearch.Size = new System.Drawing.Size(200, 20);
|
||||||
|
this.txtSearch.TabIndex = 0;
|
||||||
|
this.txtSearch.TextChanged += new System.EventHandler(this.txtSearch_TextChanged);
|
||||||
|
//
|
||||||
|
// cbFilterStatus
|
||||||
|
//
|
||||||
|
this.cbFilterStatus.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbFilterStatus.FormattingEnabled = true;
|
||||||
|
this.cbFilterStatus.Items.AddRange(new object[] {
|
||||||
|
"Все",
|
||||||
|
"Свободно",
|
||||||
|
"По рецепту"});
|
||||||
|
this.cbFilterStatus.Location = new System.Drawing.Point(212, 5);
|
||||||
|
this.cbFilterStatus.Name = "cbFilterStatus";
|
||||||
|
this.cbFilterStatus.Size = new System.Drawing.Size(120, 21);
|
||||||
|
this.cbFilterStatus.TabIndex = 1;
|
||||||
|
this.cbFilterStatus.SelectedIndexChanged += new System.EventHandler(this.ApplyFilters);
|
||||||
|
//
|
||||||
|
// cbFilterSupplier
|
||||||
|
//
|
||||||
|
this.cbFilterSupplier.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbFilterSupplier.FormattingEnabled = true;
|
||||||
|
this.cbFilterSupplier.Location = new System.Drawing.Point(338, 5);
|
||||||
|
this.cbFilterSupplier.Name = "cbFilterSupplier";
|
||||||
|
this.cbFilterSupplier.Size = new System.Drawing.Size(150, 21);
|
||||||
|
this.cbFilterSupplier.TabIndex = 2;
|
||||||
|
this.cbFilterSupplier.SelectedIndexChanged += new System.EventHandler(this.ApplyFilters);
|
||||||
|
//
|
||||||
|
// btnAddProduct
|
||||||
|
//
|
||||||
|
this.btnAddProduct.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnAddProduct.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnAddProduct.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnAddProduct.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnAddProduct.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnAddProduct.Location = new System.Drawing.Point(6, 308);
|
||||||
|
this.btnAddProduct.Name = "btnAddProduct";
|
||||||
|
this.btnAddProduct.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnAddProduct.TabIndex = 4;
|
||||||
|
this.btnAddProduct.Text = "Добавить";
|
||||||
|
this.btnAddProduct.UseVisualStyleBackColor = false;
|
||||||
|
this.btnAddProduct.Click += new System.EventHandler(this.btnAddProduct_Click);
|
||||||
|
//
|
||||||
|
// btnEditProduct
|
||||||
|
//
|
||||||
|
this.btnEditProduct.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
this.btnEditProduct.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnEditProduct.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnEditProduct.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnEditProduct.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnEditProduct.Location = new System.Drawing.Point(112, 308);
|
||||||
|
this.btnEditProduct.Name = "btnEditProduct";
|
||||||
|
this.btnEditProduct.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnEditProduct.TabIndex = 5;
|
||||||
|
this.btnEditProduct.Text = "Изменить";
|
||||||
|
this.btnEditProduct.UseVisualStyleBackColor = false;
|
||||||
|
this.btnEditProduct.Click += new System.EventHandler(this.btnEditProduct_Click);
|
||||||
|
//
|
||||||
|
// btnDeleteProduct
|
||||||
|
//
|
||||||
|
this.btnDeleteProduct.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnDeleteProduct.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnDeleteProduct.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnDeleteProduct.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnDeleteProduct.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnDeleteProduct.Location = new System.Drawing.Point(218, 308);
|
||||||
|
this.btnDeleteProduct.Name = "btnDeleteProduct";
|
||||||
|
this.btnDeleteProduct.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnDeleteProduct.TabIndex = 6;
|
||||||
|
this.btnDeleteProduct.Text = "Удалить";
|
||||||
|
this.btnDeleteProduct.UseVisualStyleBackColor = false;
|
||||||
|
this.btnDeleteProduct.Click += new System.EventHandler(this.btnDeleteProduct_Click);
|
||||||
|
//
|
||||||
|
// btnRefresh
|
||||||
|
//
|
||||||
|
this.btnRefresh.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
this.btnRefresh.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnRefresh.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnRefresh.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnRefresh.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnRefresh.Location = new System.Drawing.Point(324, 308);
|
||||||
|
this.btnRefresh.Name = "btnRefresh";
|
||||||
|
this.btnRefresh.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnRefresh.TabIndex = 7;
|
||||||
|
this.btnRefresh.Text = "Обновить";
|
||||||
|
this.btnRefresh.UseVisualStyleBackColor = false;
|
||||||
|
this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click);
|
||||||
|
//
|
||||||
|
// tabOrders
|
||||||
|
//
|
||||||
|
this.tabOrders.Controls.Add(this.dgvOrders);
|
||||||
|
this.tabOrders.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabOrders.Name = "tabOrders";
|
||||||
|
this.tabOrders.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabOrders.Size = new System.Drawing.Size(760, 354);
|
||||||
|
this.tabOrders.TabIndex = 1;
|
||||||
|
this.tabOrders.Text = "Заказы";
|
||||||
|
this.tabOrders.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// dgvOrders
|
||||||
|
//
|
||||||
|
this.dgvOrders.AllowUserToAddRows = false;
|
||||||
|
this.dgvOrders.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvOrders.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvOrders.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||||
|
dataGridViewCellStyle3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
dataGridViewCellStyle3.ForeColor = System.Drawing.Color.Black;
|
||||||
|
dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||||
|
dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||||
|
dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||||
|
this.dgvOrders.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle3;
|
||||||
|
this.dgvOrders.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||||
|
dataGridViewCellStyle4.BackColor = System.Drawing.Color.White;
|
||||||
|
dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||||
|
dataGridViewCellStyle4.ForeColor = System.Drawing.Color.Black;
|
||||||
|
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||||
|
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||||
|
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
|
||||||
|
this.dgvOrders.DefaultCellStyle = dataGridViewCellStyle4;
|
||||||
|
this.dgvOrders.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.dgvOrders.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.dgvOrders.Name = "dgvOrders";
|
||||||
|
this.dgvOrders.ReadOnly = true;
|
||||||
|
this.dgvOrders.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvOrders.Size = new System.Drawing.Size(754, 348);
|
||||||
|
this.dgvOrders.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnLogout
|
||||||
|
//
|
||||||
|
this.btnLogout.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnLogout.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnLogout.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnLogout.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnLogout.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnLogout.Location = new System.Drawing.Point(690, 12);
|
||||||
|
this.btnLogout.Name = "btnLogout";
|
||||||
|
this.btnLogout.Size = new System.Drawing.Size(90, 30);
|
||||||
|
this.btnLogout.TabIndex = 1;
|
||||||
|
this.btnLogout.Text = "Выход";
|
||||||
|
this.btnLogout.UseVisualStyleBackColor = false;
|
||||||
|
this.btnLogout.Click += new System.EventHandler(this.btnLogout_Click);
|
||||||
|
//
|
||||||
|
// lblUser
|
||||||
|
//
|
||||||
|
this.lblUser.AutoSize = true;
|
||||||
|
this.lblUser.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblUser.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.lblUser.Location = new System.Drawing.Point(12, 15);
|
||||||
|
this.lblUser.Name = "lblUser";
|
||||||
|
this.lblUser.Size = new System.Drawing.Size(129, 17);
|
||||||
|
this.lblUser.TabIndex = 0;
|
||||||
|
this.lblUser.Text = "Администратор:";
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.button1.Location = new System.Drawing.Point(623, 309);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(131, 35);
|
||||||
|
this.button1.TabIndex = 8;
|
||||||
|
this.button1.Text = "Генерировать QR";
|
||||||
|
this.button1.UseVisualStyleBackColor = false;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// AdminForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
|
||||||
|
this.ClientSize = new System.Drawing.Size(792, 437);
|
||||||
|
this.Controls.Add(this.lblUser);
|
||||||
|
this.Controls.Add(this.btnLogout);
|
||||||
|
this.Controls.Add(this.tabControl);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "AdminForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Аптека — Администратор";
|
||||||
|
this.Load += new System.EventHandler(this.AdminForm_Load);
|
||||||
|
this.tabControl.ResumeLayout(false);
|
||||||
|
this.tabProducts.ResumeLayout(false);
|
||||||
|
this.tabProducts.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).EndInit();
|
||||||
|
this.tabOrders.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrders)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
}
|
||||||
|
}
|
||||||
277
AdminForm.cs
Normal file
277
AdminForm.cs
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class AdminForm : Form
|
||||||
|
{
|
||||||
|
private int userId;
|
||||||
|
private string userName;
|
||||||
|
private DataTable allProducts;
|
||||||
|
|
||||||
|
public AdminForm(int userId, string userName)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.userId = userId;
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AdminForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
lblUser.Text = $" {userName}";
|
||||||
|
LoadSuppliers();
|
||||||
|
LoadProducts();
|
||||||
|
LoadOrders();
|
||||||
|
SetupGrids();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSuppliers()
|
||||||
|
{
|
||||||
|
var suppliers = DB.ExecuteQuery("SELECT DISTINCT supplier_name FROM suppliers ORDER BY supplier_name");
|
||||||
|
cbFilterSupplier.Items.Clear();
|
||||||
|
cbFilterSupplier.Items.Add("Все поставщики");
|
||||||
|
foreach (DataRow row in suppliers.Rows)
|
||||||
|
cbFilterSupplier.Items.Add(row["supplier_name"].ToString());
|
||||||
|
cbFilterSupplier.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadProducts()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string query = @"SELECT
|
||||||
|
m.id AS 'ID',
|
||||||
|
m.medication_name AS 'Название',
|
||||||
|
CONCAT(m.price, ' ₽') AS 'Цена',
|
||||||
|
m.stock_quantity AS 'На складе',
|
||||||
|
m.batch_number AS 'Партия',
|
||||||
|
s.supplier_name AS 'Поставщик',
|
||||||
|
ds.status_name AS 'Отпуск',
|
||||||
|
IF(m.has_analog, '✅', '❌') AS 'Аналог'
|
||||||
|
FROM medications m
|
||||||
|
LEFT JOIN suppliers s ON m.supplier_id = s.id
|
||||||
|
LEFT JOIN dispensing_statuses ds ON m.dispensing_status_id = ds.id
|
||||||
|
ORDER BY m.medication_name";
|
||||||
|
|
||||||
|
allProducts = DB.ExecuteQuery(query);
|
||||||
|
ApplyFilters();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки товаров: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyFilters(object sender = null, EventArgs e = null)
|
||||||
|
{
|
||||||
|
if (allProducts == null) return;
|
||||||
|
|
||||||
|
DataView view = allProducts.DefaultView;
|
||||||
|
string filter = "";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(txtSearch.Text.Trim()))
|
||||||
|
filter += $"Название LIKE '%{txtSearch.Text.Trim()}%'";
|
||||||
|
|
||||||
|
if (cbFilterStatus.SelectedIndex > 0)
|
||||||
|
{
|
||||||
|
string status = cbFilterStatus.SelectedItem.ToString();
|
||||||
|
if (!string.IsNullOrEmpty(filter)) filter += " AND ";
|
||||||
|
filter += $"Отпуск = '{status}'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbFilterSupplier.SelectedIndex > 0)
|
||||||
|
{
|
||||||
|
string supplier = cbFilterSupplier.SelectedItem.ToString();
|
||||||
|
if (!string.IsNullOrEmpty(filter)) filter += " AND ";
|
||||||
|
filter += $"Поставщик = '{supplier}'";
|
||||||
|
}
|
||||||
|
|
||||||
|
view.RowFilter = filter;
|
||||||
|
dgvProducts.DataSource = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtSearch_TextChanged(object sender, EventArgs e) => ApplyFilters();
|
||||||
|
|
||||||
|
private void SetupGrids()
|
||||||
|
{
|
||||||
|
dgvProducts.Columns["ID"].Visible = false;
|
||||||
|
dgvProducts.Columns["Цена"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
|
||||||
|
dgvProducts.Columns["На складе"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
|
||||||
|
dgvProducts.Columns["Аналог"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
|
||||||
|
dgvProducts.CellFormatting += (s, args) =>
|
||||||
|
{
|
||||||
|
if (dgvProducts.Columns[args.ColumnIndex].Name == "На складе" &&
|
||||||
|
args.Value != null && Convert.ToInt32(args.Value) < 10)
|
||||||
|
{
|
||||||
|
args.CellStyle.BackColor = Color.FromArgb(255, 220, 220);
|
||||||
|
args.CellStyle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dgvOrders.Columns["ID"].Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadOrders()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string query = @"SELECT
|
||||||
|
p.id AS 'ID',
|
||||||
|
p.purchase_date AS 'Дата',
|
||||||
|
COALESCE(c.full_name, '—') AS 'Клиент',
|
||||||
|
COALESCE(pr.prescription_number, '—') AS 'Рецепт',
|
||||||
|
GROUP_CONCAT(CONCAT(m.medication_name, ' ×', pm.quantity) SEPARATOR ', ') AS 'Состав',
|
||||||
|
SUM(m.price * pm.quantity) AS 'Сумма, ₽'
|
||||||
|
FROM purchases p
|
||||||
|
LEFT JOIN clients c ON p.client_id = c.id
|
||||||
|
LEFT JOIN prescriptions pr ON p.prescription_id = pr.id
|
||||||
|
LEFT JOIN purchase_medications pm ON p.id = pm.purchase_id
|
||||||
|
LEFT JOIN medications m ON pm.medication_id = m.id
|
||||||
|
GROUP BY p.id
|
||||||
|
ORDER BY p.purchase_date DESC";
|
||||||
|
|
||||||
|
dgvOrders.DataSource = DB.ExecuteQuery(query);
|
||||||
|
dgvOrders.Columns["Сумма, ₽"].DefaultCellStyle.Format = "0.00 ₽";
|
||||||
|
dgvOrders.Columns["Сумма, ₽"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки заказов: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dgvProducts_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.RowIndex >= 0)
|
||||||
|
EditSelectedProduct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnAddProduct_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var productForm = new ProductForm(-1);
|
||||||
|
if (productForm.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
LoadProducts();
|
||||||
|
LoadSuppliers();
|
||||||
|
MessageBox.Show("овар добавлен!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnEditProduct_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
EditSelectedProduct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditSelectedProduct()
|
||||||
|
{
|
||||||
|
if (dgvProducts.CurrentRow == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите товар для редактирования!", "Внимание",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int productId = Convert.ToInt32(dgvProducts.CurrentRow.Cells["ID"].Value);
|
||||||
|
var productForm = new ProductForm(productId);
|
||||||
|
if (productForm.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
LoadProducts();
|
||||||
|
MessageBox.Show("Товар обновлён!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnDeleteProduct_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (dgvProducts.CurrentRow == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите товар для удаления!", "Внимание",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int productId = Convert.ToInt32(dgvProducts.CurrentRow.Cells["ID"].Value);
|
||||||
|
string productName = dgvProducts.CurrentRow.Cells["Название"].Value.ToString();
|
||||||
|
var checkQuery = "SELECT COUNT(*) FROM purchase_medications WHERE medication_id = @id";
|
||||||
|
var count = DB.ExecuteScalar(checkQuery, new MySqlParameter[] { new MySqlParameter("@id", productId) });
|
||||||
|
if (Convert.ToInt32(count) > 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show(" Нельзя удалить товар, который есть в истории заказов!", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = MessageBox.Show(
|
||||||
|
$"Удалить товар \"{productName}\"?\n\nЭто действие нельзя отменить.",
|
||||||
|
"Подтверждение удаления",
|
||||||
|
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
|
|
||||||
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DB.ExecuteCommand("DELETE FROM medications WHERE id = @id",
|
||||||
|
new MySqlParameter[] { new MySqlParameter("@id", productId) });
|
||||||
|
|
||||||
|
LoadProducts();
|
||||||
|
MessageBox.Show("Товар удалён!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnRefresh_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
txtSearch.Clear();
|
||||||
|
cbFilterStatus.SelectedIndex = 0;
|
||||||
|
cbFilterSupplier.SelectedIndex = 0;
|
||||||
|
LoadProducts();
|
||||||
|
LoadOrders();
|
||||||
|
MessageBox.Show("Данные обновлены", "Информация",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnLogout_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show("Выйти из системы?", "Подтверждение",
|
||||||
|
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
|
|
||||||
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
this.Hide();
|
||||||
|
var loginForm = new LoginForm();
|
||||||
|
loginForm.Show();
|
||||||
|
this.FormClosed += (s, args) => loginForm.FormClosed += (s2, a2) => Application.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnActivated(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnActivated(e);
|
||||||
|
LoadProducts();
|
||||||
|
LoadOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (dgvProducts.CurrentRow != null)
|
||||||
|
{
|
||||||
|
int productId = Convert.ToInt32(dgvProducts.CurrentRow.Cells["ID"].Value);
|
||||||
|
var qrForm = new QRCodeViewerForm(productId);
|
||||||
|
qrForm.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1253
AdminForm.resx
Normal file
1253
AdminForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
6
App.config
Normal file
6
App.config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
39
ClientForm.Designer.cs
generated
Normal file
39
ClientForm.Designer.cs
generated
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class ClientForm
|
||||||
|
{
|
||||||
|
/// <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 = "ClientForm";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
20
ClientForm.cs
Normal file
20
ClientForm.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
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 Neshina1703
|
||||||
|
{
|
||||||
|
public partial class ClientForm : Form
|
||||||
|
{
|
||||||
|
public ClientForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
DB.cs
Normal file
64
DB.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public static partial class DB
|
||||||
|
{
|
||||||
|
public static string ConnectionString =
|
||||||
|
"Server=cfif31.ru;Database=ISPr25-21_NeshinaPV_1703;Uid=ISPr25-21_NeshinaPV;Password=ISPr25-21_NeshinaPV;SslMode=none;";
|
||||||
|
|
||||||
|
public static MySqlConnection GetConnection()
|
||||||
|
{
|
||||||
|
return new MySqlConnection(ConnectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataTable ExecuteQuery(string query, MySqlParameter[] parameters = null)
|
||||||
|
{
|
||||||
|
using (var conn = GetConnection())
|
||||||
|
{
|
||||||
|
using (var cmd = new MySqlCommand(query, conn))
|
||||||
|
{
|
||||||
|
if (parameters != null)
|
||||||
|
cmd.Parameters.AddRange(parameters);
|
||||||
|
|
||||||
|
var adapter = new MySqlDataAdapter(cmd);
|
||||||
|
var table = new DataTable();
|
||||||
|
adapter.Fill(table);
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ExecuteCommand(string query, MySqlParameter[] parameters = null)
|
||||||
|
{
|
||||||
|
using (var conn = GetConnection())
|
||||||
|
{
|
||||||
|
using (var cmd = new MySqlCommand(query, conn))
|
||||||
|
{
|
||||||
|
if (parameters != null)
|
||||||
|
cmd.Parameters.AddRange(parameters);
|
||||||
|
|
||||||
|
conn.Open();
|
||||||
|
return cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object ExecuteScalar(string query, MySqlParameter[] parameters = null)
|
||||||
|
{
|
||||||
|
using (var conn = GetConnection())
|
||||||
|
{
|
||||||
|
using (var cmd = new MySqlCommand(query, conn))
|
||||||
|
{
|
||||||
|
if (parameters != null)
|
||||||
|
cmd.Parameters.AddRange(parameters);
|
||||||
|
|
||||||
|
conn.Open();
|
||||||
|
return cmd.ExecuteScalar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
240
EmployeeForm.Designer.cs
generated
Normal file
240
EmployeeForm.Designer.cs
generated
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class EmployeeForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.TabControl tabControl;
|
||||||
|
private System.Windows.Forms.TabPage tabProducts;
|
||||||
|
private System.Windows.Forms.TabPage tabOrders;
|
||||||
|
private System.Windows.Forms.TabPage tabClients;
|
||||||
|
private System.Windows.Forms.DataGridView dgvProducts;
|
||||||
|
private System.Windows.Forms.DataGridView dgvOrders;
|
||||||
|
private System.Windows.Forms.DataGridView dgvClients;
|
||||||
|
private System.Windows.Forms.Button btnCreateOrder;
|
||||||
|
private System.Windows.Forms.Button btnAddCard;
|
||||||
|
private System.Windows.Forms.Button btnLogout;
|
||||||
|
private System.Windows.Forms.Label lblUser;
|
||||||
|
private System.Windows.Forms.BindingSource productsBindingSource;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EmployeeForm));
|
||||||
|
this.tabControl = new System.Windows.Forms.TabControl();
|
||||||
|
this.tabProducts = new System.Windows.Forms.TabPage();
|
||||||
|
this.dgvProducts = new System.Windows.Forms.DataGridView();
|
||||||
|
this.tabOrders = new System.Windows.Forms.TabPage();
|
||||||
|
this.dgvOrders = new System.Windows.Forms.DataGridView();
|
||||||
|
this.btnCreateOrder = new System.Windows.Forms.Button();
|
||||||
|
this.tabClients = new System.Windows.Forms.TabPage();
|
||||||
|
this.dgvClients = new System.Windows.Forms.DataGridView();
|
||||||
|
this.btnAddCard = new System.Windows.Forms.Button();
|
||||||
|
this.productsBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||||
|
this.btnLogout = new System.Windows.Forms.Button();
|
||||||
|
this.lblUser = new System.Windows.Forms.Label();
|
||||||
|
this.button1 = new System.Windows.Forms.Button();
|
||||||
|
this.tabControl.SuspendLayout();
|
||||||
|
this.tabProducts.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).BeginInit();
|
||||||
|
this.tabOrders.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrders)).BeginInit();
|
||||||
|
this.tabClients.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvClients)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.productsBindingSource)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// tabControl
|
||||||
|
//
|
||||||
|
this.tabControl.Controls.Add(this.tabProducts);
|
||||||
|
this.tabControl.Controls.Add(this.tabOrders);
|
||||||
|
this.tabControl.Controls.Add(this.tabClients);
|
||||||
|
this.tabControl.Location = new System.Drawing.Point(12, 45);
|
||||||
|
this.tabControl.Name = "tabControl";
|
||||||
|
this.tabControl.SelectedIndex = 0;
|
||||||
|
this.tabControl.Size = new System.Drawing.Size(760, 380);
|
||||||
|
this.tabControl.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// tabProducts
|
||||||
|
//
|
||||||
|
this.tabProducts.Controls.Add(this.dgvProducts);
|
||||||
|
this.tabProducts.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabProducts.Name = "tabProducts";
|
||||||
|
this.tabProducts.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabProducts.Size = new System.Drawing.Size(752, 354);
|
||||||
|
this.tabProducts.TabIndex = 0;
|
||||||
|
this.tabProducts.Text = " Товары";
|
||||||
|
this.tabProducts.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// dgvProducts
|
||||||
|
//
|
||||||
|
this.dgvProducts.AllowUserToAddRows = false;
|
||||||
|
this.dgvProducts.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvProducts.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvProducts.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvProducts.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvProducts.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.dgvProducts.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.dgvProducts.Name = "dgvProducts";
|
||||||
|
this.dgvProducts.ReadOnly = true;
|
||||||
|
this.dgvProducts.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvProducts.Size = new System.Drawing.Size(746, 348);
|
||||||
|
this.dgvProducts.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// tabOrders
|
||||||
|
//
|
||||||
|
this.tabOrders.Controls.Add(this.dgvOrders);
|
||||||
|
this.tabOrders.Controls.Add(this.btnCreateOrder);
|
||||||
|
this.tabOrders.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabOrders.Name = "tabOrders";
|
||||||
|
this.tabOrders.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabOrders.Size = new System.Drawing.Size(752, 354);
|
||||||
|
this.tabOrders.TabIndex = 1;
|
||||||
|
this.tabOrders.Text = " Заказы";
|
||||||
|
this.tabOrders.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// dgvOrders
|
||||||
|
//
|
||||||
|
this.dgvOrders.AllowUserToAddRows = false;
|
||||||
|
this.dgvOrders.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvOrders.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvOrders.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvOrders.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvOrders.Dock = System.Windows.Forms.DockStyle.Top;
|
||||||
|
this.dgvOrders.Location = new System.Drawing.Point(3, 3);
|
||||||
|
this.dgvOrders.Name = "dgvOrders";
|
||||||
|
this.dgvOrders.ReadOnly = true;
|
||||||
|
this.dgvOrders.Size = new System.Drawing.Size(746, 300);
|
||||||
|
this.dgvOrders.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// btnCreateOrder
|
||||||
|
//
|
||||||
|
this.btnCreateOrder.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));
|
||||||
|
this.btnCreateOrder.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnCreateOrder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnCreateOrder.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnCreateOrder.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnCreateOrder.Location = new System.Drawing.Point(10, 310);
|
||||||
|
this.btnCreateOrder.Name = "btnCreateOrder";
|
||||||
|
this.btnCreateOrder.Size = new System.Drawing.Size(160, 35);
|
||||||
|
this.btnCreateOrder.TabIndex = 0;
|
||||||
|
this.btnCreateOrder.Text = "Оформить заказ";
|
||||||
|
this.btnCreateOrder.UseVisualStyleBackColor = false;
|
||||||
|
this.btnCreateOrder.Click += new System.EventHandler(this.btnCreateOrder_Click);
|
||||||
|
//
|
||||||
|
// tabClients
|
||||||
|
//
|
||||||
|
this.tabClients.Controls.Add(this.dgvClients);
|
||||||
|
this.tabClients.Controls.Add(this.btnAddCard);
|
||||||
|
this.tabClients.Location = new System.Drawing.Point(4, 22);
|
||||||
|
this.tabClients.Name = "tabClients";
|
||||||
|
this.tabClients.Size = new System.Drawing.Size(752, 354);
|
||||||
|
this.tabClients.TabIndex = 2;
|
||||||
|
this.tabClients.Text = " Клиенты";
|
||||||
|
this.tabClients.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// dgvClients
|
||||||
|
//
|
||||||
|
this.dgvClients.AllowUserToAddRows = false;
|
||||||
|
this.dgvClients.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvClients.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvClients.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvClients.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvClients.Dock = System.Windows.Forms.DockStyle.Top;
|
||||||
|
this.dgvClients.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.dgvClients.Name = "dgvClients";
|
||||||
|
this.dgvClients.ReadOnly = true;
|
||||||
|
this.dgvClients.Size = new System.Drawing.Size(752, 300);
|
||||||
|
this.dgvClients.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// btnAddCard
|
||||||
|
//
|
||||||
|
this.btnAddCard.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(180)))), ((int)(((byte)(80)))));
|
||||||
|
this.btnAddCard.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnAddCard.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnAddCard.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnAddCard.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnAddCard.Location = new System.Drawing.Point(10, 310);
|
||||||
|
this.btnAddCard.Name = "btnAddCard";
|
||||||
|
this.btnAddCard.Size = new System.Drawing.Size(160, 35);
|
||||||
|
this.btnAddCard.TabIndex = 1;
|
||||||
|
this.btnAddCard.Text = " Завести карту";
|
||||||
|
this.btnAddCard.UseVisualStyleBackColor = false;
|
||||||
|
this.btnAddCard.Click += new System.EventHandler(this.btnAddCard_Click);
|
||||||
|
//
|
||||||
|
// btnLogout
|
||||||
|
//
|
||||||
|
this.btnLogout.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
|
||||||
|
this.btnLogout.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnLogout.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnLogout.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnLogout.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnLogout.Location = new System.Drawing.Point(680, 12);
|
||||||
|
this.btnLogout.Name = "btnLogout";
|
||||||
|
this.btnLogout.Size = new System.Drawing.Size(90, 30);
|
||||||
|
this.btnLogout.TabIndex = 2;
|
||||||
|
this.btnLogout.Text = " Выход";
|
||||||
|
this.btnLogout.UseVisualStyleBackColor = false;
|
||||||
|
this.btnLogout.Click += new System.EventHandler(this.btnLogout_Click);
|
||||||
|
//
|
||||||
|
// lblUser
|
||||||
|
//
|
||||||
|
this.lblUser.AutoSize = true;
|
||||||
|
this.lblUser.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblUser.Location = new System.Drawing.Point(12, 18);
|
||||||
|
this.lblUser.Name = "lblUser";
|
||||||
|
this.lblUser.Size = new System.Drawing.Size(92, 17);
|
||||||
|
this.lblUser.TabIndex = 3;
|
||||||
|
this.lblUser.Text = "Сотрудник:";
|
||||||
|
//
|
||||||
|
// button1
|
||||||
|
//
|
||||||
|
this.button1.Location = new System.Drawing.Point(518, 12);
|
||||||
|
this.button1.Name = "button1";
|
||||||
|
this.button1.Size = new System.Drawing.Size(105, 30);
|
||||||
|
this.button1.TabIndex = 4;
|
||||||
|
this.button1.Text = "сообщения";
|
||||||
|
this.button1.UseVisualStyleBackColor = true;
|
||||||
|
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||||
|
//
|
||||||
|
// EmployeeForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.White;
|
||||||
|
this.ClientSize = new System.Drawing.Size(784, 437);
|
||||||
|
this.Controls.Add(this.button1);
|
||||||
|
this.Controls.Add(this.lblUser);
|
||||||
|
this.Controls.Add(this.btnLogout);
|
||||||
|
this.Controls.Add(this.tabControl);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "EmployeeForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Аптека — Сотрудник";
|
||||||
|
this.Load += new System.EventHandler(this.EmployeeForm_Load);
|
||||||
|
this.tabControl.ResumeLayout(false);
|
||||||
|
this.tabProducts.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).EndInit();
|
||||||
|
this.tabOrders.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrders)).EndInit();
|
||||||
|
this.tabClients.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvClients)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.productsBindingSource)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private System.Windows.Forms.Button button1;
|
||||||
|
}
|
||||||
|
}
|
||||||
189
EmployeeForm.cs
Normal file
189
EmployeeForm.cs
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class EmployeeForm : Form
|
||||||
|
{
|
||||||
|
private int userId;
|
||||||
|
private string userName;
|
||||||
|
|
||||||
|
public EmployeeForm(int userId, string userName)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.userId = userId;
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmployeeForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
lblUser.Text = $"👤 {userName}";
|
||||||
|
LoadProducts();
|
||||||
|
LoadOrders();
|
||||||
|
LoadClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Загрузка товаров в DataGrid
|
||||||
|
private void LoadProducts()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string query = @"SELECT
|
||||||
|
m.id AS 'ID',
|
||||||
|
m.medication_name AS 'Название',
|
||||||
|
m.price AS 'Цена, ₽',
|
||||||
|
m.stock_quantity AS 'На складе',
|
||||||
|
ds.status_name AS 'Отпуск',
|
||||||
|
s.supplier_name AS 'Поставщик'
|
||||||
|
FROM medications m
|
||||||
|
LEFT JOIN dispensing_statuses ds ON m.dispensing_status_id = ds.id
|
||||||
|
LEFT JOIN suppliers s ON m.supplier_id = s.id
|
||||||
|
ORDER BY m.medication_name";
|
||||||
|
|
||||||
|
dgvProducts.DataSource = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
// Скрыть ID и настроить столбцы
|
||||||
|
if (dgvProducts.Columns["ID"] != null)
|
||||||
|
dgvProducts.Columns["ID"].Visible = false;
|
||||||
|
|
||||||
|
FormatGrid(dgvProducts);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки товаров: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Загрузка истории заказов
|
||||||
|
private void LoadOrders()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string query = @"SELECT
|
||||||
|
p.id AS 'ID',
|
||||||
|
p.purchase_date AS 'Дата',
|
||||||
|
c.full_name AS 'Клиент',
|
||||||
|
pr.prescription_number AS 'Рецепт №',
|
||||||
|
GROUP_CONCAT(CONCAT(m.medication_name, ' ×', pm.quantity) SEPARATOR ', ') AS 'Состав'
|
||||||
|
FROM purchases p
|
||||||
|
LEFT JOIN clients c ON p.client_id = c.id
|
||||||
|
LEFT JOIN prescriptions pr ON p.prescription_id = pr.id
|
||||||
|
LEFT JOIN purchase_medications pm ON p.id = pm.purchase_id
|
||||||
|
LEFT JOIN medications m ON pm.medication_id = m.id
|
||||||
|
GROUP BY p.id
|
||||||
|
ORDER BY p.purchase_date DESC";
|
||||||
|
|
||||||
|
dgvOrders.DataSource = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
if (dgvOrders.Columns["ID"] != null)
|
||||||
|
dgvOrders.Columns["ID"].Visible = false;
|
||||||
|
|
||||||
|
FormatGrid(dgvOrders);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки заказов: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Загрузка клиентов в DataGrid
|
||||||
|
private void LoadClients()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string query = @"SELECT
|
||||||
|
c.id AS 'ID',
|
||||||
|
c.full_name AS 'ФИО',
|
||||||
|
c.phone AS 'Телефон',
|
||||||
|
c.email AS 'Email',
|
||||||
|
dc.discount_percentage AS 'Скидка, %'
|
||||||
|
FROM clients c
|
||||||
|
LEFT JOIN discount_cards dc ON c.discount_card_id = dc.id
|
||||||
|
ORDER BY c.full_name";
|
||||||
|
|
||||||
|
dgvClients.DataSource = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
if (dgvClients.Columns["ID"] != null)
|
||||||
|
dgvClients.Columns["ID"].Visible = false;
|
||||||
|
|
||||||
|
FormatGrid(dgvClients);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки клиентов: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Форматирование DataGrid
|
||||||
|
private void FormatGrid(DataGridView grid)
|
||||||
|
{
|
||||||
|
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
grid.DefaultCellStyle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F);
|
||||||
|
grid.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
grid.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(240, 240, 240);
|
||||||
|
grid.DefaultCellStyle.SelectionBackColor = System.Drawing.Color.FromArgb(0, 120, 215);
|
||||||
|
grid.DefaultCellStyle.SelectionForeColor = System.Drawing.Color.White;
|
||||||
|
grid.RowHeadersVisible = false;
|
||||||
|
grid.AllowUserToResizeRows = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Кнопка: Оформить заказ
|
||||||
|
private void btnCreateOrder_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var orderForm = new OrderForm(userId);
|
||||||
|
if (orderForm.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
LoadProducts(); // Обновить остатки
|
||||||
|
LoadOrders(); // Показать новый заказ
|
||||||
|
MessageBox.Show("✅ Заказ оформлен!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Кнопка: Завести бонусную карту
|
||||||
|
private void btnAddCard_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var clientForm = new ClientForm();
|
||||||
|
if (clientForm.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
LoadClients();
|
||||||
|
MessageBox.Show("✅ Карта заведена!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Кнопка: Выход
|
||||||
|
private void btnLogout_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show("Выйти из системы?", "Подтверждение",
|
||||||
|
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
|
|
||||||
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
this.Hide();
|
||||||
|
var loginForm = new LoginForm();
|
||||||
|
loginForm.Show();
|
||||||
|
this.FormClosed += (s, args) => loginForm.FormClosed += (s2, a2) => Application.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 Обновление при возврате фокуса
|
||||||
|
protected override void OnActivated(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnActivated(e);
|
||||||
|
LoadProducts();
|
||||||
|
LoadOrders();
|
||||||
|
LoadClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var messengerForm = new MessengerForm(userId);
|
||||||
|
messengerForm.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1256
EmployeeForm.resx
Normal file
1256
EmployeeForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
110
Form1.Designer.cs
generated
Normal file
110
Form1.Designer.cs
generated
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class LoginForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.Label lblTitle;
|
||||||
|
private System.Windows.Forms.Label lblEmail;
|
||||||
|
private System.Windows.Forms.Label lblPassword;
|
||||||
|
private System.Windows.Forms.TextBox txtEmail;
|
||||||
|
private System.Windows.Forms.TextBox txtPassword;
|
||||||
|
private System.Windows.Forms.Button btnLogin;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null)) components.Dispose();
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LoginForm));
|
||||||
|
this.lblTitle = new System.Windows.Forms.Label();
|
||||||
|
this.lblEmail = new System.Windows.Forms.Label();
|
||||||
|
this.lblPassword = new System.Windows.Forms.Label();
|
||||||
|
this.txtEmail = new System.Windows.Forms.TextBox();
|
||||||
|
this.txtPassword = new System.Windows.Forms.TextBox();
|
||||||
|
this.btnLogin = new System.Windows.Forms.Button();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblTitle
|
||||||
|
//
|
||||||
|
this.lblTitle.AutoSize = true;
|
||||||
|
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblTitle.Location = new System.Drawing.Point(95, 110);
|
||||||
|
this.lblTitle.Name = "lblTitle";
|
||||||
|
this.lblTitle.Size = new System.Drawing.Size(140, 24);
|
||||||
|
this.lblTitle.TabIndex = 1;
|
||||||
|
this.lblTitle.Text = "Авторизация";
|
||||||
|
//
|
||||||
|
// lblEmail
|
||||||
|
//
|
||||||
|
this.lblEmail.AutoSize = true;
|
||||||
|
this.lblEmail.Location = new System.Drawing.Point(40, 160);
|
||||||
|
this.lblEmail.Name = "lblEmail";
|
||||||
|
this.lblEmail.Size = new System.Drawing.Size(35, 13);
|
||||||
|
this.lblEmail.TabIndex = 2;
|
||||||
|
this.lblEmail.Text = "Email:";
|
||||||
|
//
|
||||||
|
// lblPassword
|
||||||
|
//
|
||||||
|
this.lblPassword.AutoSize = true;
|
||||||
|
this.lblPassword.Location = new System.Drawing.Point(40, 210);
|
||||||
|
this.lblPassword.Name = "lblPassword";
|
||||||
|
this.lblPassword.Size = new System.Drawing.Size(48, 13);
|
||||||
|
this.lblPassword.TabIndex = 4;
|
||||||
|
this.lblPassword.Text = "Пароль:";
|
||||||
|
//
|
||||||
|
// txtEmail
|
||||||
|
//
|
||||||
|
this.txtEmail.Location = new System.Drawing.Point(43, 180);
|
||||||
|
this.txtEmail.Name = "txtEmail";
|
||||||
|
this.txtEmail.Size = new System.Drawing.Size(230, 20);
|
||||||
|
this.txtEmail.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// txtPassword
|
||||||
|
//
|
||||||
|
this.txtPassword.Location = new System.Drawing.Point(43, 230);
|
||||||
|
this.txtPassword.Name = "txtPassword";
|
||||||
|
this.txtPassword.PasswordChar = '*';
|
||||||
|
this.txtPassword.Size = new System.Drawing.Size(230, 20);
|
||||||
|
this.txtPassword.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// btnLogin
|
||||||
|
//
|
||||||
|
this.btnLogin.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));
|
||||||
|
this.btnLogin.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnLogin.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnLogin.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnLogin.Location = new System.Drawing.Point(110, 270);
|
||||||
|
this.btnLogin.Name = "btnLogin";
|
||||||
|
this.btnLogin.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnLogin.TabIndex = 6;
|
||||||
|
this.btnLogin.Text = "Войти";
|
||||||
|
this.btnLogin.UseVisualStyleBackColor = false;
|
||||||
|
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
|
||||||
|
//
|
||||||
|
// LoginForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(320, 350);
|
||||||
|
this.Controls.Add(this.lblTitle);
|
||||||
|
this.Controls.Add(this.lblEmail);
|
||||||
|
this.Controls.Add(this.txtEmail);
|
||||||
|
this.Controls.Add(this.lblPassword);
|
||||||
|
this.Controls.Add(this.txtPassword);
|
||||||
|
this.Controls.Add(this.btnLogin);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "LoginForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Аптека — Вход";
|
||||||
|
this.Load += new System.EventHandler(this.LoginForm_Load);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
Form1.cs
Normal file
68
Form1.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class LoginForm : Form
|
||||||
|
{
|
||||||
|
public LoginForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnLogin_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
string email = txtEmail.Text.Trim();
|
||||||
|
string password = txtPassword.Text.Trim();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Введите email и пароль!", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@email", email),
|
||||||
|
new MySqlParameter("@password_hash", password)
|
||||||
|
};
|
||||||
|
|
||||||
|
var query = "SELECT id, full_name, position_id FROM employees WHERE email = @email AND password_hash = @password_hash LIMIT 1";
|
||||||
|
var result = DB.ExecuteQuery(query, parameters);
|
||||||
|
|
||||||
|
if (result.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
int userId = Convert.ToInt32(result.Rows[0]["id"]);
|
||||||
|
string fullName = result.Rows[0]["full_name"].ToString();
|
||||||
|
int positionId = Convert.ToInt32(result.Rows[0]["position_id"]);
|
||||||
|
|
||||||
|
this.Hide();
|
||||||
|
|
||||||
|
if (positionId == 1) // Главный фармацевт = Админ
|
||||||
|
{
|
||||||
|
new AdminForm(userId, fullName).Show();
|
||||||
|
}
|
||||||
|
else // Фармацевт = Сотрудник
|
||||||
|
{
|
||||||
|
new EmployeeForm(userId, fullName).Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.FormClosed += (s, args) => Application.Exit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Неверный email или пароль!", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
txtPassword.Clear();
|
||||||
|
txtPassword.Focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoginForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1253
Form1.resx
Normal file
1253
Form1.resx
Normal file
File diff suppressed because it is too large
Load Diff
178
MessageHelper.cs
Normal file
178
MessageHelper.cs
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public static class MessageHelper
|
||||||
|
{
|
||||||
|
public static int CreateConversation(int employeeId1, int employeeId2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var conn = DB.GetConnection())
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (var transaction = conn.BeginTransaction())
|
||||||
|
{
|
||||||
|
var cmd1 = new MySqlCommand("INSERT INTO conversations (created_at) VALUES (NOW())", conn, transaction);
|
||||||
|
cmd1.ExecuteNonQuery();
|
||||||
|
cmd1.CommandText = "SELECT LAST_INSERT_ID()";
|
||||||
|
int conversationId = Convert.ToInt32(cmd1.ExecuteScalar());
|
||||||
|
|
||||||
|
var cmd2 = new MySqlCommand(
|
||||||
|
"INSERT INTO conversation_participants (conversation_id, employee_id) VALUES (@conv, @emp1), (@conv, @emp2)",
|
||||||
|
conn, transaction);
|
||||||
|
cmd2.Parameters.AddWithValue("@conv", conversationId);
|
||||||
|
cmd2.Parameters.AddWithValue("@emp1", employeeId1);
|
||||||
|
cmd2.Parameters.AddWithValue("@emp2", employeeId2);
|
||||||
|
cmd2.ExecuteNonQuery();
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
return conversationId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception("Ошибка создания чата: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int? GetExistingConversation(int employeeId1, int employeeId2)
|
||||||
|
{
|
||||||
|
var query = @"SELECT c.id FROM conversations c
|
||||||
|
JOIN conversation_participants cp1 ON c.id = cp1.conversation_id
|
||||||
|
JOIN conversation_participants cp2 ON c.id = cp2.conversation_id
|
||||||
|
WHERE cp1.employee_id = @emp1 AND cp2.employee_id = @emp2";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@emp1", employeeId1),
|
||||||
|
new MySqlParameter("@emp2", employeeId2)
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = DB.ExecuteScalar(query, parameters);
|
||||||
|
return result != null && result != DBNull.Value ? Convert.ToInt32(result) : (int?)null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMessage(int conversationId, int senderId, string messageText)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(messageText)) return;
|
||||||
|
|
||||||
|
var query = @"INSERT INTO messages (conversation_id, sender_id, message_text, sent_at)
|
||||||
|
VALUES (@conv, @sender, @text, NOW())";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@conv", conversationId),
|
||||||
|
new MySqlParameter("@sender", senderId),
|
||||||
|
new MySqlParameter("@text", messageText)
|
||||||
|
};
|
||||||
|
|
||||||
|
DB.ExecuteCommand(query, parameters);
|
||||||
|
|
||||||
|
DB.ExecuteCommand("UPDATE conversations SET updated_at = NOW() WHERE id = @id",
|
||||||
|
new MySqlParameter[] { new MySqlParameter("@id", conversationId) });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataTable GetMessages(int conversationId, int limit = 100)
|
||||||
|
{
|
||||||
|
var query = @"SELECT m.id, m.message_text, m.sent_at, m.is_read,
|
||||||
|
e.id as sender_id, e.full_name as sender_name
|
||||||
|
FROM messages m
|
||||||
|
JOIN employees e ON m.sender_id = e.id
|
||||||
|
WHERE m.conversation_id = @conv
|
||||||
|
ORDER BY m.sent_at DESC
|
||||||
|
LIMIT @limit";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@conv", conversationId),
|
||||||
|
new MySqlParameter("@limit", limit)
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = DB.ExecuteQuery(query, parameters);
|
||||||
|
var view = table.DefaultView;
|
||||||
|
view.Sort = "sent_at ASC";
|
||||||
|
return view.ToTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataTable GetConversationsForEmployee(int employeeId)
|
||||||
|
{
|
||||||
|
var query = @"SELECT c.id, c.updated_at,
|
||||||
|
e.id as other_employee_id,
|
||||||
|
e.full_name as other_employee_name,
|
||||||
|
(SELECT COUNT(*) FROM messages m
|
||||||
|
WHERE m.conversation_id = c.id
|
||||||
|
AND m.sender_id != @emp
|
||||||
|
AND m.is_read = FALSE) as unread_count,
|
||||||
|
(SELECT message_text FROM messages m2
|
||||||
|
WHERE m2.conversation_id = c.id
|
||||||
|
ORDER BY m2.sent_at DESC LIMIT 1) as last_message
|
||||||
|
FROM conversations c
|
||||||
|
JOIN conversation_participants cp ON c.id = cp.conversation_id
|
||||||
|
JOIN employees e ON e.id = (
|
||||||
|
SELECT cp2.employee_id FROM conversation_participants cp2
|
||||||
|
WHERE cp2.conversation_id = c.id AND cp2.employee_id != @emp
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
WHERE cp.employee_id = @emp
|
||||||
|
ORDER BY c.updated_at DESC";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@emp", employeeId)
|
||||||
|
};
|
||||||
|
|
||||||
|
return DB.ExecuteQuery(query, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataTable GetAllEmployeesExcept(int currentEmployeeId)
|
||||||
|
{
|
||||||
|
var query = @"SELECT id, full_name, position_id
|
||||||
|
FROM employees
|
||||||
|
WHERE id != @emp
|
||||||
|
ORDER BY full_name";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@emp", currentEmployeeId)
|
||||||
|
};
|
||||||
|
|
||||||
|
return DB.ExecuteQuery(query, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MarkMessagesAsRead(int conversationId, int employeeId)
|
||||||
|
{
|
||||||
|
var query = @"UPDATE messages m
|
||||||
|
JOIN conversation_participants cp ON m.conversation_id = cp.conversation_id
|
||||||
|
SET m.is_read = TRUE
|
||||||
|
WHERE m.conversation_id = @conv
|
||||||
|
AND m.sender_id != @emp";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@conv", conversationId),
|
||||||
|
new MySqlParameter("@emp", employeeId)
|
||||||
|
};
|
||||||
|
|
||||||
|
DB.ExecuteCommand(query, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetUnreadMessagesCount(int employeeId)
|
||||||
|
{
|
||||||
|
var query = @"SELECT COUNT(*) FROM messages m
|
||||||
|
JOIN conversation_participants cp ON m.conversation_id = cp.conversation_id
|
||||||
|
WHERE cp.employee_id = @emp AND m.sender_id != @emp AND m.is_read = FALSE";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@emp", employeeId)
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = DB.ExecuteScalar(query, parameters);
|
||||||
|
return result != null && result != DBNull.Value ? Convert.ToInt32(result) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
160
MessengerForm.Designer.cs
generated
Normal file
160
MessengerForm.Designer.cs
generated
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class MessengerForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.SplitContainer splitContainer;
|
||||||
|
private System.Windows.Forms.Panel panelLeft;
|
||||||
|
private System.Windows.Forms.Panel panelRight;
|
||||||
|
private System.Windows.Forms.DataGridView dgvConversations;
|
||||||
|
private System.Windows.Forms.Button btnStartChat;
|
||||||
|
private System.Windows.Forms.ComboBox cbEmployees;
|
||||||
|
private System.Windows.Forms.FlowLayoutPanel flowMessages;
|
||||||
|
private System.Windows.Forms.TextBox txtMessage;
|
||||||
|
private System.Windows.Forms.Button btnSend;
|
||||||
|
private System.Windows.Forms.Label lblCurrentChat;
|
||||||
|
private System.Windows.Forms.Label lblTitle;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
components.Dispose();
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.splitContainer = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.panelLeft = new System.Windows.Forms.Panel();
|
||||||
|
this.dgvConversations = new System.Windows.Forms.DataGridView();
|
||||||
|
this.btnStartChat = new System.Windows.Forms.Button();
|
||||||
|
this.cbEmployees = new System.Windows.Forms.ComboBox();
|
||||||
|
this.panelRight = new System.Windows.Forms.Panel();
|
||||||
|
this.flowMessages = new System.Windows.Forms.FlowLayoutPanel();
|
||||||
|
this.txtMessage = new System.Windows.Forms.TextBox();
|
||||||
|
this.btnSend = new System.Windows.Forms.Button();
|
||||||
|
this.lblCurrentChat = new System.Windows.Forms.Label();
|
||||||
|
this.lblTitle = new System.Windows.Forms.Label();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||||
|
this.splitContainer.Panel1.SuspendLayout();
|
||||||
|
this.splitContainer.Panel2.SuspendLayout();
|
||||||
|
this.splitContainer.SuspendLayout();
|
||||||
|
this.panelLeft.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvConversations)).BeginInit();
|
||||||
|
this.panelRight.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
|
||||||
|
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.splitContainer.Location = new System.Drawing.Point(0, 50);
|
||||||
|
this.splitContainer.Name = "splitContainer";
|
||||||
|
this.splitContainer.Size = new System.Drawing.Size(800, 400);
|
||||||
|
this.splitContainer.SplitterDistance = 250;
|
||||||
|
|
||||||
|
this.panelLeft.BackColor = System.Drawing.Color.FromArgb(176, 253, 161);
|
||||||
|
this.panelLeft.Controls.Add(this.dgvConversations);
|
||||||
|
this.panelLeft.Controls.Add(this.btnStartChat);
|
||||||
|
this.panelLeft.Controls.Add(this.cbEmployees);
|
||||||
|
this.panelLeft.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
|
||||||
|
this.dgvConversations.AllowUserToAddRows = false;
|
||||||
|
this.dgvConversations.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvConversations.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvConversations.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvConversations.Dock = System.Windows.Forms.DockStyle.Top;
|
||||||
|
this.dgvConversations.Location = new System.Drawing.Point(0, 60);
|
||||||
|
this.dgvConversations.Name = "dgvConversations";
|
||||||
|
this.dgvConversations.ReadOnly = true;
|
||||||
|
this.dgvConversations.Size = new System.Drawing.Size(250, 340);
|
||||||
|
this.dgvConversations.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvConversations.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvConversations_CellClick);
|
||||||
|
|
||||||
|
this.btnStartChat.BackColor = System.Drawing.Color.FromArgb(91, 209, 45);
|
||||||
|
this.btnStartChat.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnStartChat.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnStartChat.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnStartChat.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnStartChat.Location = new System.Drawing.Point(5, 30);
|
||||||
|
this.btnStartChat.Name = "btnStartChat";
|
||||||
|
this.btnStartChat.Size = new System.Drawing.Size(100, 30);
|
||||||
|
this.btnStartChat.TabIndex = 1;
|
||||||
|
this.btnStartChat.Text = "Начать чат";
|
||||||
|
this.btnStartChat.Click += new System.EventHandler(this.btnStartChat_Click);
|
||||||
|
|
||||||
|
this.cbEmployees.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbEmployees.FormattingEnabled = true;
|
||||||
|
this.cbEmployees.Location = new System.Drawing.Point(5, 5);
|
||||||
|
this.cbEmployees.Name = "cbEmployees";
|
||||||
|
this.cbEmployees.Size = new System.Drawing.Size(240, 21);
|
||||||
|
|
||||||
|
this.panelRight.BackColor = System.Drawing.Color.White;
|
||||||
|
this.panelRight.Controls.Add(this.flowMessages);
|
||||||
|
this.panelRight.Controls.Add(this.txtMessage);
|
||||||
|
this.panelRight.Controls.Add(this.btnSend);
|
||||||
|
this.panelRight.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
|
||||||
|
this.flowMessages.AutoScroll = true;
|
||||||
|
this.flowMessages.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.flowMessages.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||||
|
this.flowMessages.Location = new System.Drawing.Point(0, 30);
|
||||||
|
this.flowMessages.Name = "flowMessages";
|
||||||
|
this.flowMessages.Size = new System.Drawing.Size(546, 330);
|
||||||
|
this.flowMessages.WrapContents = false;
|
||||||
|
|
||||||
|
this.txtMessage.Location = new System.Drawing.Point(0, 360);
|
||||||
|
this.txtMessage.Multiline = true;
|
||||||
|
this.txtMessage.Name = "txtMessage";
|
||||||
|
this.txtMessage.Size = new System.Drawing.Size(460, 40);
|
||||||
|
this.txtMessage.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtMessage_KeyDown);
|
||||||
|
|
||||||
|
this.btnSend.BackColor = System.Drawing.Color.FromArgb(91, 209, 45);
|
||||||
|
this.btnSend.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnSend.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnSend.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnSend.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnSend.Location = new System.Drawing.Point(465, 360);
|
||||||
|
this.btnSend.Name = "btnSend";
|
||||||
|
this.btnSend.Size = new System.Drawing.Size(80, 40);
|
||||||
|
this.btnSend.TabIndex = 2;
|
||||||
|
this.btnSend.Text = "Отправить";
|
||||||
|
this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
|
||||||
|
|
||||||
|
this.lblCurrentChat.AutoSize = true;
|
||||||
|
this.lblCurrentChat.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblCurrentChat.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.lblCurrentChat.Location = new System.Drawing.Point(265, 15);
|
||||||
|
|
||||||
|
this.lblTitle.AutoSize = true;
|
||||||
|
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblTitle.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.lblTitle.Location = new System.Drawing.Point(12, 15);
|
||||||
|
this.lblTitle.Text = "💬 Мессенджер";
|
||||||
|
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.White;
|
||||||
|
this.ClientSize = new System.Drawing.Size(800, 450);
|
||||||
|
this.Controls.Add(this.lblTitle);
|
||||||
|
this.Controls.Add(this.lblCurrentChat);
|
||||||
|
this.Controls.Add(this.splitContainer);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "MessengerForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
this.Text = "Аптека — Мессенджер";
|
||||||
|
this.Load += new System.EventHandler(this.MessengerForm_Load);
|
||||||
|
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MessengerForm_FormClosing);
|
||||||
|
|
||||||
|
this.splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
this.splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
this.splitContainer.Panel2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
|
||||||
|
this.splitContainer.ResumeLayout(false);
|
||||||
|
this.panelLeft.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvConversations)).EndInit();
|
||||||
|
this.panelRight.ResumeLayout(false);
|
||||||
|
this.panelRight.PerformLayout();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
260
MessengerForm.cs
Normal file
260
MessengerForm.cs
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class MessengerForm : Form
|
||||||
|
{
|
||||||
|
private int currentEmployeeId;
|
||||||
|
private int? currentConversationId;
|
||||||
|
private System.Windows.Forms.Timer refreshTimer;
|
||||||
|
|
||||||
|
public MessengerForm(int employeeId)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.currentEmployeeId = employeeId;
|
||||||
|
SetupTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupTimer()
|
||||||
|
{
|
||||||
|
refreshTimer = new System.Windows.Forms.Timer();
|
||||||
|
refreshTimer.Interval = 5000;
|
||||||
|
refreshTimer.Tick += RefreshTimer_Tick;
|
||||||
|
refreshTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshTimer_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoadConversations();
|
||||||
|
if (currentConversationId.HasValue)
|
||||||
|
LoadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MessengerForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoadConversations();
|
||||||
|
LoadEmployees();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadConversations()
|
||||||
|
{
|
||||||
|
var conversations = MessageHelper.GetConversationsForEmployee(currentEmployeeId);
|
||||||
|
dgvConversations.DataSource = conversations;
|
||||||
|
|
||||||
|
if (dgvConversations.Columns.Count > 0)
|
||||||
|
{
|
||||||
|
if (dgvConversations.Columns["id"] != null)
|
||||||
|
dgvConversations.Columns["id"].Visible = false;
|
||||||
|
|
||||||
|
if (dgvConversations.Columns["other_employee_id"] != null)
|
||||||
|
dgvConversations.Columns["other_employee_id"].Visible = false;
|
||||||
|
|
||||||
|
if (dgvConversations.Columns["updated_at"] != null)
|
||||||
|
dgvConversations.Columns["updated_at"].Visible = false;
|
||||||
|
|
||||||
|
if (dgvConversations.Columns["other_employee_name"] != null)
|
||||||
|
{
|
||||||
|
dgvConversations.Columns["other_employee_name"].HeaderText = "Собеседник";
|
||||||
|
dgvConversations.Columns["other_employee_name"].Width = 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dgvConversations.Columns["last_message"] != null)
|
||||||
|
{
|
||||||
|
dgvConversations.Columns["last_message"].HeaderText = "Последнее сообщение";
|
||||||
|
dgvConversations.Columns["last_message"].Width = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dgvConversations.Columns["unread_count"] != null)
|
||||||
|
{
|
||||||
|
dgvConversations.Columns["unread_count"].HeaderText = "🔔";
|
||||||
|
dgvConversations.Columns["unread_count"].Width = 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dgvConversations.ClearSelection();
|
||||||
|
if (currentConversationId.HasValue)
|
||||||
|
{
|
||||||
|
foreach (DataGridViewRow row in dgvConversations.Rows)
|
||||||
|
{
|
||||||
|
if (row.Cells["id"] != null && row.Cells["id"].Value != null)
|
||||||
|
{
|
||||||
|
if (Convert.ToInt32(row.Cells["id"].Value) == currentConversationId.Value)
|
||||||
|
{
|
||||||
|
row.Selected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
var employees = MessageHelper.GetAllEmployeesExcept(currentEmployeeId);
|
||||||
|
cbEmployees.DataSource = employees;
|
||||||
|
cbEmployees.DisplayMember = "full_name";
|
||||||
|
cbEmployees.ValueMember = "id";
|
||||||
|
cbEmployees.SelectedIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadMessages()
|
||||||
|
{
|
||||||
|
if (!currentConversationId.HasValue) return;
|
||||||
|
|
||||||
|
var messages = MessageHelper.GetMessages(currentConversationId.Value);
|
||||||
|
flowMessages.Controls.Clear();
|
||||||
|
|
||||||
|
foreach (DataRow row in messages.Rows)
|
||||||
|
{
|
||||||
|
int senderId = Convert.ToInt32(row["sender_id"]);
|
||||||
|
string messageText = row["message_text"].ToString();
|
||||||
|
DateTime sentAt = Convert.ToDateTime(row["sent_at"]);
|
||||||
|
bool isMyMessage = senderId == currentEmployeeId;
|
||||||
|
|
||||||
|
var bubble = CreateMessageBubble(messageText, sentAt, isMyMessage);
|
||||||
|
flowMessages.Controls.Add(bubble);
|
||||||
|
}
|
||||||
|
|
||||||
|
flowMessages.ScrollControlIntoView(flowMessages.Controls[flowMessages.Controls.Count - 1]);
|
||||||
|
MessageHelper.MarkMessagesAsRead(currentConversationId.Value, currentEmployeeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Panel CreateMessageBubble(string text, DateTime sentAt, bool isMyMessage)
|
||||||
|
{
|
||||||
|
var bubble = new Panel
|
||||||
|
{
|
||||||
|
AutoSize = true,
|
||||||
|
AutoSizeMode = AutoSizeMode.GrowAndShrink,
|
||||||
|
Margin = new Padding(5),
|
||||||
|
MaximumSize = new Size(400, 0),
|
||||||
|
BackColor = isMyMessage ? Color.FromArgb(91, 209, 45) : Color.FromArgb(176, 253, 161),
|
||||||
|
Padding = new Padding(10),
|
||||||
|
Cursor = Cursors.Default
|
||||||
|
};
|
||||||
|
|
||||||
|
var labelText = new Label
|
||||||
|
{
|
||||||
|
Text = text,
|
||||||
|
AutoSize = false,
|
||||||
|
MaximumSize = new Size(380, 0),
|
||||||
|
ForeColor = Color.Black,
|
||||||
|
BackColor = Color.Transparent,
|
||||||
|
Dock = DockStyle.Top,
|
||||||
|
Padding = new Padding(5)
|
||||||
|
};
|
||||||
|
labelText.Size = new Size(380, labelText.PreferredHeight);
|
||||||
|
|
||||||
|
var labelTime = new Label
|
||||||
|
{
|
||||||
|
Text = sentAt.ToString("HH:mm"),
|
||||||
|
AutoSize = true,
|
||||||
|
ForeColor = Color.Black,
|
||||||
|
BackColor = Color.Transparent,
|
||||||
|
Dock = DockStyle.Bottom,
|
||||||
|
Font = new Font("Microsoft Sans Serif", 7F),
|
||||||
|
Padding = new Padding(5, 0, 5, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
bubble.Controls.Add(labelText);
|
||||||
|
bubble.Controls.Add(labelTime);
|
||||||
|
|
||||||
|
if (isMyMessage)
|
||||||
|
{
|
||||||
|
bubble.Dock = DockStyle.Right;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bubble.Dock = DockStyle.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bubble;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dgvConversations_CellClick(object sender, DataGridViewCellEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.RowIndex >= 0)
|
||||||
|
{
|
||||||
|
var row = dgvConversations.Rows[e.RowIndex];
|
||||||
|
if (row.Cells["id"] != null && row.Cells["id"].Value != null)
|
||||||
|
{
|
||||||
|
currentConversationId = Convert.ToInt32(row.Cells["id"].Value);
|
||||||
|
lblCurrentChat.Text = "Чат с: " + row.Cells["other_employee_name"].Value.ToString();
|
||||||
|
LoadMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSend_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SendMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtMessage_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyCode == Keys.Enter && !e.Shift)
|
||||||
|
{
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
SendMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendMessage()
|
||||||
|
{
|
||||||
|
if (!currentConversationId.HasValue)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите чат для отправки сообщения!", "Внимание",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string text = txtMessage.Text.Trim();
|
||||||
|
if (string.IsNullOrEmpty(text)) return;
|
||||||
|
|
||||||
|
MessageHelper.SendMessage(currentConversationId.Value, currentEmployeeId, text);
|
||||||
|
txtMessage.Clear();
|
||||||
|
LoadMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnStartChat_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (cbEmployees.SelectedValue == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите сотрудника для чата!", "Внимание",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedEmployeeId = Convert.ToInt32(cbEmployees.SelectedValue);
|
||||||
|
int? conversationId = MessageHelper.GetExistingConversation(currentEmployeeId, selectedEmployeeId);
|
||||||
|
|
||||||
|
if (!conversationId.HasValue)
|
||||||
|
{
|
||||||
|
conversationId = MessageHelper.CreateConversation(currentEmployeeId, selectedEmployeeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentConversationId = conversationId;
|
||||||
|
LoadConversations();
|
||||||
|
|
||||||
|
foreach (DataGridViewRow row in dgvConversations.Rows)
|
||||||
|
{
|
||||||
|
if (row.Cells["id"] != null && row.Cells["id"].Value != null &&
|
||||||
|
Convert.ToInt32(row.Cells["id"].Value) == conversationId.Value)
|
||||||
|
{
|
||||||
|
dgvConversations.ClearSelection();
|
||||||
|
row.Selected = true;
|
||||||
|
dgvConversations_CellClick(dgvConversations, new DataGridViewCellEventArgs(0, row.Index));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MessengerForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
refreshTimer?.Stop();
|
||||||
|
refreshTimer?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
MessengerForm.resx
Normal file
120
MessengerForm.resx
Normal 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>
|
||||||
159
Neshina1703.csproj
Normal file
159
Neshina1703.csproj
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<RootNamespace>Neshina1703</RootNamespace>
|
||||||
|
<AssemblyName>Neshina1703</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="MySql.Data">
|
||||||
|
<HintPath>..\..\Downloads\mysql.data\MySql.Data.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
<Reference Include="QRCoder, Version=1.7.0.0, Culture=neutral, PublicKeyToken=c4ed5b9ae8358a28, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\QRCoder.1.7.0\lib\net40\QRCoder.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AdminForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="AdminForm.Designer.cs">
|
||||||
|
<DependentUpon>AdminForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ClientForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ClientForm.Designer.cs">
|
||||||
|
<DependentUpon>ClientForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="DB.cs" />
|
||||||
|
<Compile Include="EmployeeForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="EmployeeForm.Designer.cs">
|
||||||
|
<DependentUpon>EmployeeForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form1.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form1.Designer.cs">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="MessageHelper.cs" />
|
||||||
|
<Compile Include="MessengerForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="MessengerForm.Designer.cs">
|
||||||
|
<DependentUpon>MessengerForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OrderForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OrderForm.Designer.cs">
|
||||||
|
<DependentUpon>OrderForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ProductForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ProductForm.Designer.cs">
|
||||||
|
<DependentUpon>ProductForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="QRCodeGenerator.cs" />
|
||||||
|
<Compile Include="QRCodeViewerForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="QRCodeViewerForm.Designer.cs">
|
||||||
|
<DependentUpon>QRCodeViewerForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="AdminForm.resx">
|
||||||
|
<DependentUpon>AdminForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="EmployeeForm.resx">
|
||||||
|
<DependentUpon>EmployeeForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Form1.resx">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="MessengerForm.resx">
|
||||||
|
<DependentUpon>MessengerForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="OrderForm.resx">
|
||||||
|
<DependentUpon>OrderForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="ProductForm.resx">
|
||||||
|
<DependentUpon>ProductForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="QRCodeViewerForm.resx">
|
||||||
|
<DependentUpon>QRCodeViewerForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
25
Neshina1703.sln
Normal file
25
Neshina1703.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.8.34511.84
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neshina1703", "Neshina1703.csproj", "{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1A170F4A-81FE-440F-BD92-8C7A76ECD60F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {A3C18389-E3A9-45D5-8D6C-8D26FF3ADE3C}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
280
OrderForm.Designer.cs
generated
Normal file
280
OrderForm.Designer.cs
generated
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class OrderForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.Label lblTitle;
|
||||||
|
private System.Windows.Forms.Label lblClient;
|
||||||
|
private System.Windows.Forms.Label lblPrescription;
|
||||||
|
private System.Windows.Forms.Label lblProducts;
|
||||||
|
private System.Windows.Forms.Label lblOrder;
|
||||||
|
private System.Windows.Forms.Label lblTotal;
|
||||||
|
private System.Windows.Forms.ComboBox cbClient;
|
||||||
|
private System.Windows.Forms.ComboBox cbPrescription;
|
||||||
|
private System.Windows.Forms.DataGridView dgvProducts;
|
||||||
|
private System.Windows.Forms.DataGridView dgvOrder;
|
||||||
|
private System.Windows.Forms.NumericUpDown numQuantity;
|
||||||
|
private System.Windows.Forms.Button btnAddToOrder;
|
||||||
|
private System.Windows.Forms.Button btnRemoveFromOrder;
|
||||||
|
private System.Windows.Forms.Button btnSave;
|
||||||
|
private System.Windows.Forms.Button btnCancel;
|
||||||
|
private System.Windows.Forms.BindingSource productsBindingSource;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OrderForm));
|
||||||
|
this.lblTitle = new System.Windows.Forms.Label();
|
||||||
|
this.lblClient = new System.Windows.Forms.Label();
|
||||||
|
this.lblPrescription = new System.Windows.Forms.Label();
|
||||||
|
this.lblProducts = new System.Windows.Forms.Label();
|
||||||
|
this.lblOrder = new System.Windows.Forms.Label();
|
||||||
|
this.lblTotal = new System.Windows.Forms.Label();
|
||||||
|
this.cbClient = new System.Windows.Forms.ComboBox();
|
||||||
|
this.cbPrescription = new System.Windows.Forms.ComboBox();
|
||||||
|
this.dgvProducts = new System.Windows.Forms.DataGridView();
|
||||||
|
this.dgvOrder = new System.Windows.Forms.DataGridView();
|
||||||
|
this.numQuantity = new System.Windows.Forms.NumericUpDown();
|
||||||
|
this.btnAddToOrder = new System.Windows.Forms.Button();
|
||||||
|
this.btnRemoveFromOrder = new System.Windows.Forms.Button();
|
||||||
|
this.btnSave = new System.Windows.Forms.Button();
|
||||||
|
this.btnCancel = new System.Windows.Forms.Button();
|
||||||
|
this.productsBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrder)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.numQuantity)).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.productsBindingSource)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblTitle
|
||||||
|
//
|
||||||
|
this.lblTitle.AutoSize = true;
|
||||||
|
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblTitle.Location = new System.Drawing.Point(12, 15);
|
||||||
|
this.lblTitle.Name = "lblTitle";
|
||||||
|
this.lblTitle.Size = new System.Drawing.Size(215, 24);
|
||||||
|
this.lblTitle.TabIndex = 0;
|
||||||
|
this.lblTitle.Text = " Оформление заказа";
|
||||||
|
//
|
||||||
|
// lblClient
|
||||||
|
//
|
||||||
|
this.lblClient.AutoSize = true;
|
||||||
|
this.lblClient.Location = new System.Drawing.Point(12, 55);
|
||||||
|
this.lblClient.Name = "lblClient";
|
||||||
|
this.lblClient.Size = new System.Drawing.Size(46, 13);
|
||||||
|
this.lblClient.TabIndex = 1;
|
||||||
|
this.lblClient.Text = "Клиент:";
|
||||||
|
//
|
||||||
|
// lblPrescription
|
||||||
|
//
|
||||||
|
this.lblPrescription.AutoSize = true;
|
||||||
|
this.lblPrescription.Location = new System.Drawing.Point(280, 55);
|
||||||
|
this.lblPrescription.Name = "lblPrescription";
|
||||||
|
this.lblPrescription.Size = new System.Drawing.Size(60, 13);
|
||||||
|
this.lblPrescription.TabIndex = 3;
|
||||||
|
this.lblPrescription.Text = "Рецепт №:";
|
||||||
|
//
|
||||||
|
// lblProducts
|
||||||
|
//
|
||||||
|
this.lblProducts.AutoSize = true;
|
||||||
|
this.lblProducts.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblProducts.Location = new System.Drawing.Point(12, 110);
|
||||||
|
this.lblProducts.Name = "lblProducts";
|
||||||
|
this.lblProducts.Size = new System.Drawing.Size(142, 15);
|
||||||
|
this.lblProducts.TabIndex = 5;
|
||||||
|
this.lblProducts.Text = " Доступные товары:";
|
||||||
|
//
|
||||||
|
// lblOrder
|
||||||
|
//
|
||||||
|
this.lblOrder.AutoSize = true;
|
||||||
|
this.lblOrder.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblOrder.Location = new System.Drawing.Point(480, 110);
|
||||||
|
this.lblOrder.Name = "lblOrder";
|
||||||
|
this.lblOrder.Size = new System.Drawing.Size(108, 15);
|
||||||
|
this.lblOrder.TabIndex = 6;
|
||||||
|
this.lblOrder.Text = "Состав заказа:";
|
||||||
|
//
|
||||||
|
// lblTotal
|
||||||
|
//
|
||||||
|
this.lblTotal.AutoSize = true;
|
||||||
|
this.lblTotal.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblTotal.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.lblTotal.Location = new System.Drawing.Point(480, 345);
|
||||||
|
this.lblTotal.Name = "lblTotal";
|
||||||
|
this.lblTotal.Size = new System.Drawing.Size(94, 20);
|
||||||
|
this.lblTotal.TabIndex = 10;
|
||||||
|
this.lblTotal.Text = "Итого: 0 ₽";
|
||||||
|
//
|
||||||
|
// cbClient
|
||||||
|
//
|
||||||
|
this.cbClient.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbClient.FormattingEnabled = true;
|
||||||
|
this.cbClient.Location = new System.Drawing.Point(15, 75);
|
||||||
|
this.cbClient.Name = "cbClient";
|
||||||
|
this.cbClient.Size = new System.Drawing.Size(250, 21);
|
||||||
|
this.cbClient.TabIndex = 2;
|
||||||
|
this.cbClient.SelectedIndexChanged += new System.EventHandler(this.cbClient_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// cbPrescription
|
||||||
|
//
|
||||||
|
this.cbPrescription.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbPrescription.Enabled = false;
|
||||||
|
this.cbPrescription.FormattingEnabled = true;
|
||||||
|
this.cbPrescription.Location = new System.Drawing.Point(283, 75);
|
||||||
|
this.cbPrescription.Name = "cbPrescription";
|
||||||
|
this.cbPrescription.Size = new System.Drawing.Size(150, 21);
|
||||||
|
this.cbPrescription.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// dgvProducts
|
||||||
|
//
|
||||||
|
this.dgvProducts.AllowUserToAddRows = false;
|
||||||
|
this.dgvProducts.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvProducts.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvProducts.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvProducts.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvProducts.Location = new System.Drawing.Point(15, 130);
|
||||||
|
this.dgvProducts.Name = "dgvProducts";
|
||||||
|
this.dgvProducts.ReadOnly = true;
|
||||||
|
this.dgvProducts.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvProducts.Size = new System.Drawing.Size(450, 200);
|
||||||
|
this.dgvProducts.TabIndex = 0;
|
||||||
|
this.dgvProducts.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvProducts_CellDoubleClick);
|
||||||
|
//
|
||||||
|
// dgvOrder
|
||||||
|
//
|
||||||
|
this.dgvOrder.AllowUserToAddRows = false;
|
||||||
|
this.dgvOrder.AllowUserToDeleteRows = false;
|
||||||
|
this.dgvOrder.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||||
|
this.dgvOrder.BackgroundColor = System.Drawing.Color.White;
|
||||||
|
this.dgvOrder.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgvOrder.Location = new System.Drawing.Point(483, 130);
|
||||||
|
this.dgvOrder.Name = "dgvOrder";
|
||||||
|
this.dgvOrder.ReadOnly = true;
|
||||||
|
this.dgvOrder.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgvOrder.Size = new System.Drawing.Size(290, 200);
|
||||||
|
this.dgvOrder.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// numQuantity
|
||||||
|
//
|
||||||
|
this.numQuantity.Location = new System.Drawing.Point(15, 340);
|
||||||
|
this.numQuantity.Minimum = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
this.numQuantity.Name = "numQuantity";
|
||||||
|
this.numQuantity.Size = new System.Drawing.Size(60, 20);
|
||||||
|
this.numQuantity.TabIndex = 7;
|
||||||
|
this.numQuantity.Value = new decimal(new int[] {
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0});
|
||||||
|
//
|
||||||
|
// btnAddToOrder
|
||||||
|
//
|
||||||
|
this.btnAddToOrder.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(180)))), ((int)(((byte)(80)))));
|
||||||
|
this.btnAddToOrder.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnAddToOrder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnAddToOrder.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnAddToOrder.Location = new System.Drawing.Point(85, 337);
|
||||||
|
this.btnAddToOrder.Name = "btnAddToOrder";
|
||||||
|
this.btnAddToOrder.Size = new System.Drawing.Size(120, 25);
|
||||||
|
this.btnAddToOrder.TabIndex = 8;
|
||||||
|
this.btnAddToOrder.Text = " Добавить";
|
||||||
|
this.btnAddToOrder.UseVisualStyleBackColor = false;
|
||||||
|
this.btnAddToOrder.Click += new System.EventHandler(this.btnAddToOrder_Click);
|
||||||
|
//
|
||||||
|
// btnRemoveFromOrder
|
||||||
|
//
|
||||||
|
this.btnRemoveFromOrder.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
|
||||||
|
this.btnRemoveFromOrder.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnRemoveFromOrder.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnRemoveFromOrder.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnRemoveFromOrder.Location = new System.Drawing.Point(211, 337);
|
||||||
|
this.btnRemoveFromOrder.Name = "btnRemoveFromOrder";
|
||||||
|
this.btnRemoveFromOrder.Size = new System.Drawing.Size(120, 25);
|
||||||
|
this.btnRemoveFromOrder.TabIndex = 9;
|
||||||
|
this.btnRemoveFromOrder.Text = "Удалить";
|
||||||
|
this.btnRemoveFromOrder.UseVisualStyleBackColor = false;
|
||||||
|
this.btnRemoveFromOrder.Click += new System.EventHandler(this.btnRemoveFromOrder_Click);
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
this.btnSave.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215)))));
|
||||||
|
this.btnSave.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnSave.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnSave.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnSave.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnSave.Location = new System.Drawing.Point(580, 390);
|
||||||
|
this.btnSave.Name = "btnSave";
|
||||||
|
this.btnSave.Size = new System.Drawing.Size(120, 40);
|
||||||
|
this.btnSave.TabIndex = 11;
|
||||||
|
this.btnSave.Text = "Оформить";
|
||||||
|
this.btnSave.UseVisualStyleBackColor = false;
|
||||||
|
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
|
||||||
|
//
|
||||||
|
// btnCancel
|
||||||
|
//
|
||||||
|
this.btnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(150)))), ((int)(((byte)(150)))), ((int)(((byte)(150)))));
|
||||||
|
this.btnCancel.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnCancel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnCancel.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnCancel.Location = new System.Drawing.Point(710, 390);
|
||||||
|
this.btnCancel.Name = "btnCancel";
|
||||||
|
this.btnCancel.Size = new System.Drawing.Size(80, 40);
|
||||||
|
this.btnCancel.TabIndex = 12;
|
||||||
|
this.btnCancel.Text = "Отмена";
|
||||||
|
this.btnCancel.UseVisualStyleBackColor = false;
|
||||||
|
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||||
|
//
|
||||||
|
// OrderForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.White;
|
||||||
|
this.ClientSize = new System.Drawing.Size(800, 450);
|
||||||
|
this.Controls.Add(this.lblTitle);
|
||||||
|
this.Controls.Add(this.lblClient);
|
||||||
|
this.Controls.Add(this.cbClient);
|
||||||
|
this.Controls.Add(this.lblPrescription);
|
||||||
|
this.Controls.Add(this.cbPrescription);
|
||||||
|
this.Controls.Add(this.lblProducts);
|
||||||
|
this.Controls.Add(this.dgvProducts);
|
||||||
|
this.Controls.Add(this.lblOrder);
|
||||||
|
this.Controls.Add(this.dgvOrder);
|
||||||
|
this.Controls.Add(this.numQuantity);
|
||||||
|
this.Controls.Add(this.btnAddToOrder);
|
||||||
|
this.Controls.Add(this.btnRemoveFromOrder);
|
||||||
|
this.Controls.Add(this.lblTotal);
|
||||||
|
this.Controls.Add(this.btnSave);
|
||||||
|
this.Controls.Add(this.btnCancel);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "OrderForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Аптека — Новый заказ";
|
||||||
|
this.Load += new System.EventHandler(this.OrderForm_Load);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvProducts)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgvOrder)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.numQuantity)).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.productsBindingSource)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
347
OrderForm.cs
Normal file
347
OrderForm.cs
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class OrderForm : Form
|
||||||
|
{
|
||||||
|
private int userId;
|
||||||
|
private List<OrderItem> orderItems = new List<OrderItem>();
|
||||||
|
private decimal orderTotal = 0;
|
||||||
|
|
||||||
|
public OrderForm(int userId)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OrderForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoadClients();
|
||||||
|
LoadProducts();
|
||||||
|
SetupGrids();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadClients()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var query = @"SELECT 0 AS id, '— Без регистрации —' AS full_name
|
||||||
|
UNION ALL
|
||||||
|
SELECT id, full_name FROM clients ORDER BY full_name";
|
||||||
|
|
||||||
|
var clients = DB.ExecuteQuery(query);
|
||||||
|
cbClient.DataSource = clients;
|
||||||
|
cbClient.DisplayMember = "full_name";
|
||||||
|
cbClient.ValueMember = "id";
|
||||||
|
cbClient.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки клиентов: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cbClient_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
object selectedValue = cbClient.SelectedValue;
|
||||||
|
|
||||||
|
if (selectedValue == null || selectedValue == DBNull.Value)
|
||||||
|
{
|
||||||
|
cbPrescription.DataSource = null;
|
||||||
|
cbPrescription.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientId;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
clientId = Convert.ToInt32(selectedValue);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
cbPrescription.DataSource = null;
|
||||||
|
cbPrescription.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientId == 0)
|
||||||
|
{
|
||||||
|
cbPrescription.DataSource = null;
|
||||||
|
cbPrescription.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = @"SELECT id, prescription_number, valid_until
|
||||||
|
FROM prescriptions
|
||||||
|
WHERE client_id = @clientId AND valid_until >= CURDATE()
|
||||||
|
ORDER BY valid_until";
|
||||||
|
|
||||||
|
var prescriptions = DB.ExecuteQuery(query,
|
||||||
|
new MySqlParameter[] { new MySqlParameter("@clientId", clientId) });
|
||||||
|
|
||||||
|
if (prescriptions.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
var table = prescriptions.Clone();
|
||||||
|
table.Rows.Add(0, "— Без рецепта —", DBNull.Value);
|
||||||
|
foreach (DataRow row in prescriptions.Rows)
|
||||||
|
table.ImportRow(row);
|
||||||
|
|
||||||
|
cbPrescription.DataSource = table;
|
||||||
|
cbPrescription.DisplayMember = "prescription_number";
|
||||||
|
cbPrescription.ValueMember = "id";
|
||||||
|
cbPrescription.SelectedIndex = 0;
|
||||||
|
cbPrescription.Enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cbPrescription.DataSource = null;
|
||||||
|
cbPrescription.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadProducts()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var query = @"SELECT
|
||||||
|
m.id,
|
||||||
|
m.medication_name AS 'Название',
|
||||||
|
m.price,
|
||||||
|
m.stock_quantity AS 'Остаток',
|
||||||
|
ds.status_name AS 'Тип'
|
||||||
|
FROM medications m
|
||||||
|
LEFT JOIN dispensing_statuses ds ON m.dispensing_status_id = ds.id
|
||||||
|
WHERE m.stock_quantity > 0
|
||||||
|
ORDER BY m.medication_name";
|
||||||
|
|
||||||
|
dgvProducts.DataSource = DB.ExecuteQuery(query);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки товаров: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupGrids()
|
||||||
|
{
|
||||||
|
if (dgvProducts.Columns["id"] != null)
|
||||||
|
dgvProducts.Columns["id"].Visible = false;
|
||||||
|
if (dgvProducts.Columns["price"] != null)
|
||||||
|
dgvProducts.Columns["price"].DefaultCellStyle.Format = "0.00 ₽";
|
||||||
|
|
||||||
|
dgvOrder.Columns.Clear();
|
||||||
|
dgvOrder.Columns.Add("Name", "Товар");
|
||||||
|
dgvOrder.Columns.Add("Price", "Цена");
|
||||||
|
dgvOrder.Columns.Add("Quantity", "Кол-во");
|
||||||
|
dgvOrder.Columns.Add("Total", "Сумма");
|
||||||
|
dgvOrder.Columns["Price"].DefaultCellStyle.Format = "0.00 ₽";
|
||||||
|
dgvOrder.Columns["Total"].DefaultCellStyle.Format = "0.00 ₽";
|
||||||
|
dgvOrder.Columns["Total"].DefaultCellStyle.Font =
|
||||||
|
new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dgvProducts_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.RowIndex >= 0)
|
||||||
|
AddProductToOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnAddToOrder_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
AddProductToOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddProductToOrder()
|
||||||
|
{
|
||||||
|
if (dgvProducts.CurrentRow == null) return;
|
||||||
|
|
||||||
|
int productId = Convert.ToInt32(dgvProducts.CurrentRow.Cells["id"].Value);
|
||||||
|
string name = dgvProducts.CurrentRow.Cells["Название"].Value.ToString();
|
||||||
|
decimal price = Convert.ToDecimal(dgvProducts.CurrentRow.Cells["price"].Value);
|
||||||
|
int stock = Convert.ToInt32(dgvProducts.CurrentRow.Cells["Остаток"].Value);
|
||||||
|
int quantity = (int)numQuantity.Value;
|
||||||
|
|
||||||
|
if (quantity > stock)
|
||||||
|
{
|
||||||
|
MessageBox.Show($" На складе только {stock} шт.!", "Недостаточно товара",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existing = orderItems.FirstOrDefault(x => x.ProductId == productId);
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
if (existing.Quantity + quantity > stock)
|
||||||
|
{
|
||||||
|
MessageBox.Show($" Превышен остаток на складе!", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
existing.Quantity += quantity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orderItems.Add(new OrderItem
|
||||||
|
{
|
||||||
|
ProductId = productId,
|
||||||
|
Name = name,
|
||||||
|
Price = price,
|
||||||
|
Quantity = quantity
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshOrderGrid();
|
||||||
|
numQuantity.Value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnRemoveFromOrder_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (dgvOrder.CurrentRow == null) return;
|
||||||
|
|
||||||
|
int index = dgvOrder.CurrentRow.Index;
|
||||||
|
orderItems.RemoveAt(index);
|
||||||
|
RefreshOrderGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshOrderGrid()
|
||||||
|
{
|
||||||
|
dgvOrder.Rows.Clear();
|
||||||
|
orderTotal = 0;
|
||||||
|
|
||||||
|
foreach (var item in orderItems)
|
||||||
|
{
|
||||||
|
decimal lineTotal = item.Price * item.Quantity;
|
||||||
|
orderTotal += lineTotal;
|
||||||
|
|
||||||
|
dgvOrder.Rows.Add(item.Name, item.Price, item.Quantity, lineTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
lblTotal.Text = $"Итого: {orderTotal:0.00} ₽";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (orderItems.Count == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show(" Добавьте товары в заказ!", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var conn = DB.GetConnection())
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (var transaction = conn.BeginTransaction())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object clientVal = cbClient.SelectedValue;
|
||||||
|
int? clientId = null;
|
||||||
|
if (clientVal != null && clientVal != DBNull.Value)
|
||||||
|
{
|
||||||
|
int id = Convert.ToInt32(clientVal);
|
||||||
|
if (id > 0) clientId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int? prescriptionId = null;
|
||||||
|
if (cbPrescription.Enabled && cbPrescription.SelectedValue != null && cbPrescription.SelectedValue != DBNull.Value)
|
||||||
|
{
|
||||||
|
int pid = Convert.ToInt32(cbPrescription.SelectedValue);
|
||||||
|
if (pid > 0) prescriptionId = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var insertPurchase = @"INSERT INTO purchases (purchase_date, client_id, prescription_id)
|
||||||
|
VALUES (@date, @client, @prescription)";
|
||||||
|
|
||||||
|
var purchaseParams = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@date", DateTime.Now.ToString("yyyy-MM-dd")),
|
||||||
|
new MySqlParameter("@client", clientId ?? (object)DBNull.Value),
|
||||||
|
new MySqlParameter("@prescription", prescriptionId ?? (object)DBNull.Value)
|
||||||
|
};
|
||||||
|
|
||||||
|
int purchaseId;
|
||||||
|
using (var cmd = new MySqlCommand(insertPurchase, conn, transaction))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddRange(purchaseParams);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
cmd.CommandText = "SELECT LAST_INSERT_ID()";
|
||||||
|
purchaseId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||||
|
}
|
||||||
|
foreach (var item in orderItems)
|
||||||
|
{
|
||||||
|
var insertItem = @"INSERT INTO purchase_medications (purchase_id, medication_id, quantity)
|
||||||
|
VALUES (@purchase, @medication, @qty)";
|
||||||
|
|
||||||
|
var itemParams = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@purchase", purchaseId),
|
||||||
|
new MySqlParameter("@medication", item.ProductId),
|
||||||
|
new MySqlParameter("@qty", item.Quantity)
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var cmd = new MySqlCommand(insertItem, conn, transaction))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddRange(itemParams);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateStock = @"UPDATE medications SET stock_quantity = stock_quantity - @qty WHERE id = @id";
|
||||||
|
var stockParams = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@qty", item.Quantity),
|
||||||
|
new MySqlParameter("@id", item.ProductId)
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var cmd = new MySqlCommand(updateStock, conn, transaction))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddRange(stockParams);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
this.DialogResult =DialogResult.OK;
|
||||||
|
MessageBox.Show($"Заказ оформлен!\nСумма: {orderTotal:0.00} ₽", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(" Ошибка сохранения: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCancel_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.DialogResult = DialogResult.Cancel;
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
private class OrderItem
|
||||||
|
{
|
||||||
|
public int ProductId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public decimal Price { get; set; }
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1256
OrderForm.resx
Normal file
1256
OrderForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
342
ProductForm.Designer.cs
generated
Normal file
342
ProductForm.Designer.cs
generated
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class ProductForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.Label lblTitle;
|
||||||
|
private System.Windows.Forms.Label lblName;
|
||||||
|
private System.Windows.Forms.Label lblPrice;
|
||||||
|
private System.Windows.Forms.Label lblDiscount;
|
||||||
|
private System.Windows.Forms.Label lblQuantity;
|
||||||
|
private System.Windows.Forms.Label lblBatch;
|
||||||
|
private System.Windows.Forms.Label lblSupplier;
|
||||||
|
private System.Windows.Forms.Label lblStatus;
|
||||||
|
private System.Windows.Forms.Label lblImage;
|
||||||
|
private System.Windows.Forms.Label lblAnalog;
|
||||||
|
private System.Windows.Forms.TextBox txtName;
|
||||||
|
private System.Windows.Forms.TextBox txtPrice;
|
||||||
|
private System.Windows.Forms.TextBox txtDiscount;
|
||||||
|
private System.Windows.Forms.TextBox txtQuantity;
|
||||||
|
private System.Windows.Forms.TextBox txtBatch;
|
||||||
|
private System.Windows.Forms.ComboBox cbSupplier;
|
||||||
|
private System.Windows.Forms.ComboBox cbStatus;
|
||||||
|
private System.Windows.Forms.TextBox txtImage;
|
||||||
|
private System.Windows.Forms.Button btnBrowse;
|
||||||
|
private System.Windows.Forms.CheckBox cbAnalog;
|
||||||
|
private System.Windows.Forms.Button btnSave;
|
||||||
|
private System.Windows.Forms.Button btnCancel;
|
||||||
|
private System.Windows.Forms.ErrorProvider errorProvider;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProductForm));
|
||||||
|
this.lblTitle = new System.Windows.Forms.Label();
|
||||||
|
this.lblName = new System.Windows.Forms.Label();
|
||||||
|
this.lblPrice = new System.Windows.Forms.Label();
|
||||||
|
this.lblDiscount = new System.Windows.Forms.Label();
|
||||||
|
this.lblQuantity = new System.Windows.Forms.Label();
|
||||||
|
this.lblBatch = new System.Windows.Forms.Label();
|
||||||
|
this.lblSupplier = new System.Windows.Forms.Label();
|
||||||
|
this.lblStatus = new System.Windows.Forms.Label();
|
||||||
|
this.lblImage = new System.Windows.Forms.Label();
|
||||||
|
this.lblAnalog = new System.Windows.Forms.Label();
|
||||||
|
this.txtName = new System.Windows.Forms.TextBox();
|
||||||
|
this.txtPrice = new System.Windows.Forms.TextBox();
|
||||||
|
this.txtDiscount = new System.Windows.Forms.TextBox();
|
||||||
|
this.txtQuantity = new System.Windows.Forms.TextBox();
|
||||||
|
this.txtBatch = new System.Windows.Forms.TextBox();
|
||||||
|
this.cbSupplier = new System.Windows.Forms.ComboBox();
|
||||||
|
this.cbStatus = new System.Windows.Forms.ComboBox();
|
||||||
|
this.txtImage = new System.Windows.Forms.TextBox();
|
||||||
|
this.btnBrowse = new System.Windows.Forms.Button();
|
||||||
|
this.cbAnalog = new System.Windows.Forms.CheckBox();
|
||||||
|
this.btnSave = new System.Windows.Forms.Button();
|
||||||
|
this.btnCancel = new System.Windows.Forms.Button();
|
||||||
|
this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
|
||||||
|
this.lblPercent1 = new System.Windows.Forms.Label();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblTitle
|
||||||
|
//
|
||||||
|
this.lblTitle.AutoSize = true;
|
||||||
|
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.lblTitle.Location = new System.Drawing.Point(12, 15);
|
||||||
|
this.lblTitle.Name = "lblTitle";
|
||||||
|
this.lblTitle.Size = new System.Drawing.Size(70, 24);
|
||||||
|
this.lblTitle.TabIndex = 0;
|
||||||
|
this.lblTitle.Text = "Товар";
|
||||||
|
//
|
||||||
|
// lblName
|
||||||
|
//
|
||||||
|
this.lblName.AutoSize = true;
|
||||||
|
this.lblName.Location = new System.Drawing.Point(15, 60);
|
||||||
|
this.lblName.Name = "lblName";
|
||||||
|
this.lblName.Size = new System.Drawing.Size(57, 13);
|
||||||
|
this.lblName.TabIndex = 1;
|
||||||
|
this.lblName.Text = "Название";
|
||||||
|
//
|
||||||
|
// lblPrice
|
||||||
|
//
|
||||||
|
this.lblPrice.AutoSize = true;
|
||||||
|
this.lblPrice.Location = new System.Drawing.Point(15, 110);
|
||||||
|
this.lblPrice.Name = "lblPrice";
|
||||||
|
this.lblPrice.Size = new System.Drawing.Size(40, 13);
|
||||||
|
this.lblPrice.TabIndex = 3;
|
||||||
|
this.lblPrice.Text = "Цена *";
|
||||||
|
//
|
||||||
|
// lblDiscount
|
||||||
|
//
|
||||||
|
this.lblDiscount.AutoSize = true;
|
||||||
|
this.lblDiscount.Location = new System.Drawing.Point(160, 110);
|
||||||
|
this.lblDiscount.Name = "lblDiscount";
|
||||||
|
this.lblDiscount.Size = new System.Drawing.Size(44, 13);
|
||||||
|
this.lblDiscount.TabIndex = 5;
|
||||||
|
this.lblDiscount.Text = "Скидка";
|
||||||
|
//
|
||||||
|
// lblQuantity
|
||||||
|
//
|
||||||
|
this.lblQuantity.AutoSize = true;
|
||||||
|
this.lblQuantity.Location = new System.Drawing.Point(270, 110);
|
||||||
|
this.lblQuantity.Name = "lblQuantity";
|
||||||
|
this.lblQuantity.Size = new System.Drawing.Size(67, 13);
|
||||||
|
this.lblQuantity.TabIndex = 8;
|
||||||
|
this.lblQuantity.Text = "На складе *";
|
||||||
|
//
|
||||||
|
// lblBatch
|
||||||
|
//
|
||||||
|
this.lblBatch.AutoSize = true;
|
||||||
|
this.lblBatch.Location = new System.Drawing.Point(15, 160);
|
||||||
|
this.lblBatch.Name = "lblBatch";
|
||||||
|
this.lblBatch.Size = new System.Drawing.Size(79, 13);
|
||||||
|
this.lblBatch.TabIndex = 10;
|
||||||
|
this.lblBatch.Text = "Номер партии";
|
||||||
|
//
|
||||||
|
// lblSupplier
|
||||||
|
//
|
||||||
|
this.lblSupplier.AutoSize = true;
|
||||||
|
this.lblSupplier.Location = new System.Drawing.Point(190, 160);
|
||||||
|
this.lblSupplier.Name = "lblSupplier";
|
||||||
|
this.lblSupplier.Size = new System.Drawing.Size(65, 13);
|
||||||
|
this.lblSupplier.TabIndex = 12;
|
||||||
|
this.lblSupplier.Text = "Поставщик";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
this.lblStatus.AutoSize = true;
|
||||||
|
this.lblStatus.Location = new System.Drawing.Point(15, 210);
|
||||||
|
this.lblStatus.Name = "lblStatus";
|
||||||
|
this.lblStatus.Size = new System.Drawing.Size(43, 13);
|
||||||
|
this.lblStatus.TabIndex = 14;
|
||||||
|
this.lblStatus.Text = "Отпуск";
|
||||||
|
//
|
||||||
|
// lblImage
|
||||||
|
//
|
||||||
|
this.lblImage.AutoSize = true;
|
||||||
|
this.lblImage.Location = new System.Drawing.Point(190, 210);
|
||||||
|
this.lblImage.Name = "lblImage";
|
||||||
|
this.lblImage.Size = new System.Drawing.Size(77, 13);
|
||||||
|
this.lblImage.TabIndex = 16;
|
||||||
|
this.lblImage.Text = "Изображение";
|
||||||
|
//
|
||||||
|
// lblAnalog
|
||||||
|
//
|
||||||
|
this.lblAnalog.AutoSize = true;
|
||||||
|
this.lblAnalog.Location = new System.Drawing.Point(15, 260);
|
||||||
|
this.lblAnalog.Name = "lblAnalog";
|
||||||
|
this.lblAnalog.Size = new System.Drawing.Size(94, 13);
|
||||||
|
this.lblAnalog.TabIndex = 19;
|
||||||
|
this.lblAnalog.Text = "Наличие аналога";
|
||||||
|
//
|
||||||
|
// txtName
|
||||||
|
//
|
||||||
|
this.txtName.Location = new System.Drawing.Point(18, 76);
|
||||||
|
this.txtName.Name = "txtName";
|
||||||
|
this.txtName.Size = new System.Drawing.Size(350, 20);
|
||||||
|
this.txtName.TabIndex = 0;
|
||||||
|
this.txtName.Validating += new System.ComponentModel.CancelEventHandler(this.txtName_Validating);
|
||||||
|
//
|
||||||
|
// txtPrice
|
||||||
|
//
|
||||||
|
this.txtPrice.Location = new System.Drawing.Point(18, 126);
|
||||||
|
this.txtPrice.Name = "txtPrice";
|
||||||
|
this.txtPrice.Size = new System.Drawing.Size(120, 20);
|
||||||
|
this.txtPrice.TabIndex = 1;
|
||||||
|
this.txtPrice.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtPrice_KeyPress);
|
||||||
|
this.txtPrice.Validating += new System.ComponentModel.CancelEventHandler(this.txtPrice_Validating);
|
||||||
|
//
|
||||||
|
// txtDiscount
|
||||||
|
//
|
||||||
|
this.txtDiscount.Location = new System.Drawing.Point(163, 126);
|
||||||
|
this.txtDiscount.Name = "txtDiscount";
|
||||||
|
this.txtDiscount.Size = new System.Drawing.Size(80, 20);
|
||||||
|
this.txtDiscount.TabIndex = 2;
|
||||||
|
this.txtDiscount.Text = "0";
|
||||||
|
this.txtDiscount.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtDiscount_KeyPress);
|
||||||
|
//
|
||||||
|
// txtQuantity
|
||||||
|
//
|
||||||
|
this.txtQuantity.Location = new System.Drawing.Point(273, 126);
|
||||||
|
this.txtQuantity.Name = "txtQuantity";
|
||||||
|
this.txtQuantity.Size = new System.Drawing.Size(95, 20);
|
||||||
|
this.txtQuantity.TabIndex = 3;
|
||||||
|
this.txtQuantity.Text = "0";
|
||||||
|
this.txtQuantity.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtQuantity_KeyPress);
|
||||||
|
this.txtQuantity.Validating += new System.ComponentModel.CancelEventHandler(this.txtQuantity_Validating);
|
||||||
|
//
|
||||||
|
// txtBatch
|
||||||
|
//
|
||||||
|
this.txtBatch.Location = new System.Drawing.Point(18, 176);
|
||||||
|
this.txtBatch.Name = "txtBatch";
|
||||||
|
this.txtBatch.Size = new System.Drawing.Size(150, 20);
|
||||||
|
this.txtBatch.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// cbSupplier
|
||||||
|
//
|
||||||
|
this.cbSupplier.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbSupplier.FormattingEnabled = true;
|
||||||
|
this.cbSupplier.Location = new System.Drawing.Point(193, 176);
|
||||||
|
this.cbSupplier.Name = "cbSupplier";
|
||||||
|
this.cbSupplier.Size = new System.Drawing.Size(175, 21);
|
||||||
|
this.cbSupplier.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// cbStatus
|
||||||
|
//
|
||||||
|
this.cbStatus.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cbStatus.FormattingEnabled = true;
|
||||||
|
this.cbStatus.Items.AddRange(new object[] {
|
||||||
|
"Свободно",
|
||||||
|
"По рецепту"});
|
||||||
|
this.cbStatus.Location = new System.Drawing.Point(18, 226);
|
||||||
|
this.cbStatus.Name = "cbStatus";
|
||||||
|
this.cbStatus.Size = new System.Drawing.Size(150, 21);
|
||||||
|
this.cbStatus.TabIndex = 6;
|
||||||
|
this.cbStatus.Validating += new System.ComponentModel.CancelEventHandler(this.cbStatus_Validating);
|
||||||
|
//
|
||||||
|
// txtImage
|
||||||
|
//
|
||||||
|
this.txtImage.Location = new System.Drawing.Point(193, 226);
|
||||||
|
this.txtImage.Name = "txtImage";
|
||||||
|
this.txtImage.ReadOnly = true;
|
||||||
|
this.txtImage.Size = new System.Drawing.Size(140, 20);
|
||||||
|
this.txtImage.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// btnBrowse
|
||||||
|
//
|
||||||
|
this.btnBrowse.Location = new System.Drawing.Point(336, 225);
|
||||||
|
this.btnBrowse.Name = "btnBrowse";
|
||||||
|
this.btnBrowse.Size = new System.Drawing.Size(32, 23);
|
||||||
|
this.btnBrowse.TabIndex = 8;
|
||||||
|
this.btnBrowse.Text = "...";
|
||||||
|
this.btnBrowse.UseVisualStyleBackColor = true;
|
||||||
|
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
|
||||||
|
//
|
||||||
|
// cbAnalog
|
||||||
|
//
|
||||||
|
this.cbAnalog.AutoSize = true;
|
||||||
|
this.cbAnalog.Location = new System.Drawing.Point(18, 279);
|
||||||
|
this.cbAnalog.Name = "cbAnalog";
|
||||||
|
this.cbAnalog.Size = new System.Drawing.Size(41, 17);
|
||||||
|
this.cbAnalog.TabIndex = 9;
|
||||||
|
this.cbAnalog.Text = "Да";
|
||||||
|
this.cbAnalog.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
this.btnSave.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(180)))), ((int)(((byte)(80)))));
|
||||||
|
this.btnSave.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnSave.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnSave.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnSave.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnSave.Location = new System.Drawing.Point(16, 320);
|
||||||
|
this.btnSave.Name = "btnSave";
|
||||||
|
this.btnSave.Size = new System.Drawing.Size(120, 40);
|
||||||
|
this.btnSave.TabIndex = 10;
|
||||||
|
this.btnSave.Text = "Сохранить";
|
||||||
|
this.btnSave.UseVisualStyleBackColor = false;
|
||||||
|
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
|
||||||
|
//
|
||||||
|
// btnCancel
|
||||||
|
//
|
||||||
|
this.btnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(150)))), ((int)(((byte)(150)))), ((int)(((byte)(150)))));
|
||||||
|
this.btnCancel.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnCancel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnCancel.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnCancel.Location = new System.Drawing.Point(155, 320);
|
||||||
|
this.btnCancel.Name = "btnCancel";
|
||||||
|
this.btnCancel.Size = new System.Drawing.Size(100, 40);
|
||||||
|
this.btnCancel.TabIndex = 11;
|
||||||
|
this.btnCancel.Text = "Отмена";
|
||||||
|
this.btnCancel.UseVisualStyleBackColor = false;
|
||||||
|
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||||
|
//
|
||||||
|
// errorProvider
|
||||||
|
//
|
||||||
|
this.errorProvider.ContainerControl = this;
|
||||||
|
//
|
||||||
|
// lblPercent1
|
||||||
|
//
|
||||||
|
this.lblPercent1.AutoSize = true;
|
||||||
|
this.lblPercent1.Location = new System.Drawing.Point(246, 129);
|
||||||
|
this.lblPercent1.Name = "lblPercent1";
|
||||||
|
this.lblPercent1.Size = new System.Drawing.Size(15, 13);
|
||||||
|
this.lblPercent1.TabIndex = 6;
|
||||||
|
this.lblPercent1.Text = "%";
|
||||||
|
//
|
||||||
|
// ProductForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.White;
|
||||||
|
this.ClientSize = new System.Drawing.Size(385, 380);
|
||||||
|
this.Controls.Add(this.lblTitle);
|
||||||
|
this.Controls.Add(this.lblName);
|
||||||
|
this.Controls.Add(this.txtName);
|
||||||
|
this.Controls.Add(this.lblPrice);
|
||||||
|
this.Controls.Add(this.txtPrice);
|
||||||
|
this.Controls.Add(this.lblDiscount);
|
||||||
|
this.Controls.Add(this.txtDiscount);
|
||||||
|
this.Controls.Add(this.lblPercent1);
|
||||||
|
this.Controls.Add(this.lblQuantity);
|
||||||
|
this.Controls.Add(this.txtQuantity);
|
||||||
|
this.Controls.Add(this.lblBatch);
|
||||||
|
this.Controls.Add(this.txtBatch);
|
||||||
|
this.Controls.Add(this.lblSupplier);
|
||||||
|
this.Controls.Add(this.cbSupplier);
|
||||||
|
this.Controls.Add(this.lblStatus);
|
||||||
|
this.Controls.Add(this.cbStatus);
|
||||||
|
this.Controls.Add(this.lblImage);
|
||||||
|
this.Controls.Add(this.txtImage);
|
||||||
|
this.Controls.Add(this.btnBrowse);
|
||||||
|
this.Controls.Add(this.lblAnalog);
|
||||||
|
this.Controls.Add(this.cbAnalog);
|
||||||
|
this.Controls.Add(this.btnSave);
|
||||||
|
this.Controls.Add(this.btnCancel);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "ProductForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
this.Text = "Товар";
|
||||||
|
this.Load += new System.EventHandler(this.ProductForm_Load);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label lblPercent1;
|
||||||
|
}
|
||||||
|
}
|
||||||
309
ProductForm.cs
Normal file
309
ProductForm.cs
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class ProductForm : Form
|
||||||
|
{
|
||||||
|
private int productId;
|
||||||
|
private bool IsNew => productId == -1;
|
||||||
|
private string selectedImageFile = null;
|
||||||
|
|
||||||
|
public ProductForm(int productId)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.productId = productId;
|
||||||
|
|
||||||
|
if (!IsNew)
|
||||||
|
{
|
||||||
|
this.Text = "Редактирование товара";
|
||||||
|
lblTitle.Text = "Редактирование";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.Text = " Новый товар";
|
||||||
|
lblTitle.Text = " Новый товар";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProductForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoadSuppliers();
|
||||||
|
LoadStatuses();
|
||||||
|
|
||||||
|
if (!IsNew)
|
||||||
|
LoadProductData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSuppliers()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var query = "SELECT id, supplier_name FROM suppliers ORDER BY supplier_name";
|
||||||
|
var suppliers = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
cbSupplier.DataSource = suppliers;
|
||||||
|
cbSupplier.DisplayMember = "supplier_name";
|
||||||
|
cbSupplier.ValueMember = "id";
|
||||||
|
cbSupplier.SelectedIndex = -1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки поставщиков: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadStatuses()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var query = "SELECT id, status_name FROM dispensing_statuses ORDER BY id";
|
||||||
|
var statuses = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
cbStatus.DataSource = statuses;
|
||||||
|
cbStatus.DisplayMember = "status_name";
|
||||||
|
cbStatus.ValueMember = "id";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки статусов: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadProductData()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var query = "SELECT * FROM medications WHERE id = @id";
|
||||||
|
var parameters = new MySqlParameter[] { new MySqlParameter("@id", productId) };
|
||||||
|
var row = DB.ExecuteQuery(query, parameters).Rows[0];
|
||||||
|
|
||||||
|
txtName.Text = row["medication_name"].ToString();
|
||||||
|
txtPrice.Text = row["price"].ToString();
|
||||||
|
|
||||||
|
if (row["discount_percent"] != DBNull.Value)
|
||||||
|
txtDiscount.Text = Convert.ToDecimal(row["discount_percent"]).ToString("0");
|
||||||
|
else
|
||||||
|
txtDiscount.Text = "0";
|
||||||
|
|
||||||
|
txtQuantity.Text = row["stock_quantity"].ToString();
|
||||||
|
txtBatch.Text = row["batch_number"] != DBNull.Value ? row["batch_number"].ToString() : "";
|
||||||
|
|
||||||
|
if (row["supplier_id"] != DBNull.Value)
|
||||||
|
cbSupplier.SelectedValue = row["supplier_id"];
|
||||||
|
|
||||||
|
if (row["dispensing_status_id"] != DBNull.Value)
|
||||||
|
cbStatus.SelectedValue = row["dispensing_status_id"];
|
||||||
|
|
||||||
|
txtImage.Text = row["image_filename"] != DBNull.Value ? row["image_filename"].ToString() : "";
|
||||||
|
selectedImageFile = txtImage.Text;
|
||||||
|
|
||||||
|
if (row["has_analog"] != DBNull.Value)
|
||||||
|
cbAnalog.Checked = Convert.ToBoolean(row["has_analog"]);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Ошибка загрузки данных: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtPrice_KeyPress(object sender, KeyPressEventArgs e)
|
||||||
|
{
|
||||||
|
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
|
||||||
|
e.Handled = true;
|
||||||
|
if (e.KeyChar == '.' && (sender as TextBox).Text.Contains("."))
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtDiscount_KeyPress(object sender, KeyPressEventArgs e)
|
||||||
|
{
|
||||||
|
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtQuantity_KeyPress(object sender, KeyPressEventArgs e)
|
||||||
|
{
|
||||||
|
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtName_Validating(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(txtName.Text))
|
||||||
|
{
|
||||||
|
errorProvider.SetError(txtName, "Обязательное поле");
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errorProvider.SetError(txtName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtPrice_Validating(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(txtPrice.Text) || !decimal.TryParse(txtPrice.Text, out var price) || price <= 0)
|
||||||
|
{
|
||||||
|
errorProvider.SetError(txtPrice, "Введите цену > 0");
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errorProvider.SetError(txtPrice, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtQuantity_Validating(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(txtQuantity.Text) || !int.TryParse(txtQuantity.Text, out var qty) || qty < 0)
|
||||||
|
{
|
||||||
|
errorProvider.SetError(txtQuantity, "Введите количество >= 0");
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errorProvider.SetError(txtQuantity, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cbStatus_Validating(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
if (cbStatus.SelectedIndex < 0)
|
||||||
|
{
|
||||||
|
errorProvider.SetError(cbStatus, "Выберите статус");
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errorProvider.SetError(cbStatus, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnBrowse_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (var ofd = new OpenFileDialog())
|
||||||
|
{
|
||||||
|
ofd.Filter = "Изображения|*.jpg;*.jpeg;*.png;*.gif|Все файлы|*.*";
|
||||||
|
ofd.Title = "Выберите изображение товара";
|
||||||
|
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
selectedImageFile = Path.GetFileName(ofd.FileName);
|
||||||
|
txtImage.Text = selectedImageFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!ValidateChildren())
|
||||||
|
{
|
||||||
|
MessageBox.Show("Исправьте ошибки в форме!", "Ошибка ввода",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@name", txtName.Text.Trim()),
|
||||||
|
new MySqlParameter("@price", decimal.Parse(txtPrice.Text)),
|
||||||
|
new MySqlParameter("@discount", string.IsNullOrWhiteSpace(txtDiscount.Text) ? 0 : decimal.Parse(txtDiscount.Text)),
|
||||||
|
new MySqlParameter("@quantity", int.Parse(txtQuantity.Text)),
|
||||||
|
new MySqlParameter("@batch", string.IsNullOrWhiteSpace(txtBatch.Text) ? (object)DBNull.Value : txtBatch.Text.Trim()),
|
||||||
|
new MySqlParameter("@supplier", cbSupplier.SelectedValue ?? (object)DBNull.Value),
|
||||||
|
new MySqlParameter("@status", cbStatus.SelectedValue),
|
||||||
|
new MySqlParameter("@image", string.IsNullOrWhiteSpace(selectedImageFile) ? (object)DBNull.Value : selectedImageFile),
|
||||||
|
new MySqlParameter("@analog", cbAnalog.Checked)
|
||||||
|
};
|
||||||
|
|
||||||
|
string query;
|
||||||
|
|
||||||
|
if (IsNew)
|
||||||
|
{
|
||||||
|
query = @"INSERT INTO medications
|
||||||
|
(medication_name, price, discount_percent, stock_quantity, batch_number,
|
||||||
|
supplier_id, dispensing_status_id, image_filename, has_analog)
|
||||||
|
VALUES
|
||||||
|
(@name, @price, @discount, @quantity, @batch, @supplier, @status, @image, @analog)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query = @"UPDATE medications SET
|
||||||
|
medication_name = @name,
|
||||||
|
price = @price,
|
||||||
|
discount_percent = @discount,
|
||||||
|
stock_quantity = @quantity,
|
||||||
|
batch_number = @batch,
|
||||||
|
supplier_id = @supplier,
|
||||||
|
dispensing_status_id = @status,
|
||||||
|
image_filename = @image,
|
||||||
|
has_analog = @analog
|
||||||
|
WHERE id = @id";
|
||||||
|
|
||||||
|
parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@name", txtName.Text.Trim()),
|
||||||
|
new MySqlParameter("@price", decimal.Parse(txtPrice.Text)),
|
||||||
|
new MySqlParameter("@discount", string.IsNullOrWhiteSpace(txtDiscount.Text) ? 0 : decimal.Parse(txtDiscount.Text)),
|
||||||
|
new MySqlParameter("@quantity", int.Parse(txtQuantity.Text)),
|
||||||
|
new MySqlParameter("@batch", string.IsNullOrWhiteSpace(txtBatch.Text) ? (object)DBNull.Value : txtBatch.Text.Trim()),
|
||||||
|
new MySqlParameter("@supplier", cbSupplier.SelectedValue ?? (object)DBNull.Value),
|
||||||
|
new MySqlParameter("@status", cbStatus.SelectedValue),
|
||||||
|
new MySqlParameter("@image", string.IsNullOrWhiteSpace(selectedImageFile) ? (object)DBNull.Value : selectedImageFile),
|
||||||
|
new MySqlParameter("@analog", cbAnalog.Checked),
|
||||||
|
new MySqlParameter("@id", productId)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = DB.ExecuteCommand(query, parameters);
|
||||||
|
|
||||||
|
if (result > 0)
|
||||||
|
{
|
||||||
|
this.DialogResult = DialogResult.OK;
|
||||||
|
MessageBox.Show(
|
||||||
|
IsNew ? "Товар добавлен!" : "Товар обновлён!",
|
||||||
|
"Успех",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Information);
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Не удалось сохранить товар", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MySqlException ex)
|
||||||
|
{
|
||||||
|
string msg = ex.Number == 1062
|
||||||
|
? " Товар с таким названием уже существует!"
|
||||||
|
: " Ошибка базы данных: " + ex.Message;
|
||||||
|
|
||||||
|
MessageBox.Show(msg, "Ошибка сохранения",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(" Ошибка: " + ex.Message, "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCancel_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.DialogResult = DialogResult.Cancel;
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ProcessDialogKey(Keys keyData)
|
||||||
|
{
|
||||||
|
if (keyData == Keys.Escape)
|
||||||
|
{
|
||||||
|
btnCancel_Click(null, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return base.ProcessDialogKey(keyData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1256
ProductForm.resx
Normal file
1256
ProductForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
22
Program.cs
Normal file
22
Program.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Главная точка входа для приложения.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new LoginForm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Общие сведения об этой сборке предоставляются следующим набором
|
||||||
|
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||||
|
// связанных со сборкой.
|
||||||
|
[assembly: AssemblyTitle("Neshina1703")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Neshina1703")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2026")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||||
|
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||||
|
// COM, следует установить атрибут ComVisible в TRUE для этого типа.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||||
|
[assembly: Guid("1a170f4a-81fe-440f-bd92-8c7a76ecd60f")]
|
||||||
|
|
||||||
|
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||||
|
//
|
||||||
|
// Основной номер версии
|
||||||
|
// Дополнительный номер версии
|
||||||
|
// Номер сборки
|
||||||
|
// Редакция
|
||||||
|
//
|
||||||
|
// Можно задать все значения или принять номера сборки и редакции по умолчанию
|
||||||
|
// используя "*", как показано ниже:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
71
Properties/Resources.Designer.cs
generated
Normal file
71
Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Этот код создан программным средством.
|
||||||
|
// Версия среды выполнения: 4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
|
||||||
|
// код создан повторно.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Neshina1703.Properties
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
|
||||||
|
/// </summary>
|
||||||
|
// Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
|
||||||
|
// класс с помощью таких средств, как ResGen или Visual Studio.
|
||||||
|
// Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
|
||||||
|
// с параметром /str или заново постройте свой VS-проект.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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 ((resourceMan == null))
|
||||||
|
{
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Neshina1703.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
Properties/Resources.resx
Normal file
117
Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?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.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: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" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</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" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
30
Properties/Settings.Designer.cs
generated
Normal file
30
Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Neshina1703.Properties
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||||
|
{
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
Properties/Settings.settings
Normal file
7
Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
202
QRCodeGenerator.cs
Normal file
202
QRCodeGenerator.cs
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using QRCoder;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public static class QRCodeHelper
|
||||||
|
{
|
||||||
|
private static readonly string QRCodeFolder = Path.Combine(
|
||||||
|
Application.StartupPath, "QRCodes");
|
||||||
|
public static string BaseUrl = "http://localhost:5000/medication/";
|
||||||
|
|
||||||
|
static QRCodeHelper()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(QRCodeFolder))
|
||||||
|
Directory.CreateDirectory(QRCodeFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GenerateQRCodeForMedication(int medicationId, string medicationName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var medicationInfo = GetMedicationInfo(medicationId);
|
||||||
|
string qrData = CreateQRCodeData(medicationInfo);
|
||||||
|
using (var qrGenerator = new QRCodeGenerator())
|
||||||
|
using (var qrCodeData = qrGenerator.CreateQrCode(qrData, QRCodeGenerator.ECCLevel.Q))
|
||||||
|
using (var qrCode = new PngByteQRCode(qrCodeData))
|
||||||
|
{
|
||||||
|
string fileName = $"medication_{medicationId}.png";
|
||||||
|
string filePath = Path.Combine(QRCodeFolder, fileName);
|
||||||
|
File.WriteAllBytes(filePath, qrCode.GetGraphic(20));
|
||||||
|
SaveQRCodePath(medicationId, filePath);
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка генерации QR-кода: {ex.Message}", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static string CreateQRCodeData(MedicationInfo info)
|
||||||
|
{
|
||||||
|
var qrData = new
|
||||||
|
{
|
||||||
|
id = info.Id,
|
||||||
|
name = info.Name,
|
||||||
|
price = info.Price,
|
||||||
|
stock = info.StockQuantity,
|
||||||
|
supplier = info.Supplier,
|
||||||
|
status = info.DispensingStatus,
|
||||||
|
instructions = info.Instructions,
|
||||||
|
analogs = info.Analogs,
|
||||||
|
generated = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonConvert.SerializeObject(qrData, Newtonsoft.Json.Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static MedicationInfo GetMedicationInfo(int medicationId)
|
||||||
|
{
|
||||||
|
var query = @"SELECT
|
||||||
|
m.id,
|
||||||
|
m.medication_name,
|
||||||
|
m.price,
|
||||||
|
m.stock_quantity,
|
||||||
|
m.instructions,
|
||||||
|
m.has_analog,
|
||||||
|
s.supplier_name,
|
||||||
|
ds.status_name,
|
||||||
|
(SELECT GROUP_CONCAT(m2.medication_name SEPARATOR ', ')
|
||||||
|
FROM medications m2
|
||||||
|
WHERE m2.id != m.id
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1 FROM medications m3
|
||||||
|
WHERE m3.medication_name LIKE CONCAT('%', SUBSTRING_INDEX(m.medication_name, ' ', 1), '%')
|
||||||
|
AND m3.id = m2.id
|
||||||
|
)
|
||||||
|
) as analogs
|
||||||
|
FROM medications m
|
||||||
|
LEFT JOIN suppliers s ON m.supplier_id = s.id
|
||||||
|
LEFT JOIN dispensing_statuses ds ON m.dispensing_status_id = ds.id
|
||||||
|
WHERE m.id = @id";
|
||||||
|
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@id", medicationId)
|
||||||
|
};
|
||||||
|
var table = DB.ExecuteQuery(query, parameters);
|
||||||
|
|
||||||
|
if (table.Rows.Count == 0)
|
||||||
|
throw new Exception("Товар не найден");
|
||||||
|
var row = table.Rows[0];
|
||||||
|
return new MedicationInfo
|
||||||
|
{
|
||||||
|
Id = Convert.ToInt32(row["id"]),
|
||||||
|
Name = row["medication_name"].ToString(),
|
||||||
|
Price = Convert.ToDecimal(row["price"]),
|
||||||
|
StockQuantity = Convert.ToInt32(row["stock_quantity"]),
|
||||||
|
Supplier = row["supplier_name"]?.ToString(),
|
||||||
|
DispensingStatus = row["status_name"]?.ToString(),
|
||||||
|
Instructions = row["instructions"]?.ToString() ?? "Инструкция не указана",
|
||||||
|
Analogs = row["analogs"] != DBNull.Value ? row["analogs"].ToString() : "Аналоги не найдены"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveQRCodePath(int medicationId, string filePath)
|
||||||
|
{
|
||||||
|
var query = @"UPDATE medications SET qr_code_path = @path WHERE id = @id";
|
||||||
|
var parameters = new MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySqlParameter("@path", filePath),
|
||||||
|
new MySqlParameter("@id", medicationId)
|
||||||
|
};
|
||||||
|
|
||||||
|
DB.ExecuteCommand(query, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void GenerateAllQRCodes()
|
||||||
|
{
|
||||||
|
var query = "SELECT id, medication_name FROM medications";
|
||||||
|
var medications = DB.ExecuteQuery(query);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
foreach (System.Data.DataRow row in medications.Rows)
|
||||||
|
{
|
||||||
|
int id = Convert.ToInt32(row["id"]);
|
||||||
|
string name = row["medication_name"].ToString();
|
||||||
|
|
||||||
|
GenerateQRCodeForMedication(id, name);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show($"Сгенерировано QR-кодов: {count}", "Готово",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowQRCodeInfo(string qrCodePath)
|
||||||
|
{
|
||||||
|
if (!File.Exists(qrCodePath))
|
||||||
|
{
|
||||||
|
MessageBox.Show("QR-код не найден", "Ошибка",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string fileName = Path.GetFileName(qrCodePath);
|
||||||
|
if (fileName.StartsWith("medication_") && fileName.EndsWith(".png"))
|
||||||
|
{
|
||||||
|
string idStr = fileName.Replace("medication_", "").Replace(".png", "");
|
||||||
|
if (int.TryParse(idStr, out int medicationId))
|
||||||
|
{
|
||||||
|
var info = GetMedicationInfo(medicationId);
|
||||||
|
DisplayMedicationInfo(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DisplayMedicationInfo(MedicationInfo info)
|
||||||
|
{
|
||||||
|
string message = $@"
|
||||||
|
💊 {info.Name}
|
||||||
|
|
||||||
|
💰 Цена: {info.Price} ₽
|
||||||
|
📦 На складе: {info.StockQuantity} шт.
|
||||||
|
🏢 Поставщик: {info.Supplier}
|
||||||
|
📋 Отпуск: {info.DispensingStatus}
|
||||||
|
|
||||||
|
📖 Инструкция:
|
||||||
|
{info.Instructions}
|
||||||
|
|
||||||
|
🔄 Аналоги:
|
||||||
|
{info.Analogs}
|
||||||
|
";
|
||||||
|
MessageBox.Show(message, "Информация о препарате",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class MedicationInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public decimal Price { get; set; }
|
||||||
|
public int StockQuantity { get; set; }
|
||||||
|
public string Supplier { get; set; }
|
||||||
|
public string DispensingStatus { get; set; }
|
||||||
|
public string Instructions { get; set; }
|
||||||
|
public string Analogs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
102
QRCodeViewerForm.Designer.cs
generated
Normal file
102
QRCodeViewerForm.Designer.cs
generated
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
partial class QRCodeViewerForm
|
||||||
|
{
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
private System.Windows.Forms.PictureBox pictureBoxQR;
|
||||||
|
private System.Windows.Forms.Button btnPrint;
|
||||||
|
private System.Windows.Forms.Button btnSave;
|
||||||
|
private System.Windows.Forms.Button btnClose;
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
components.Dispose();
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QRCodeViewerForm));
|
||||||
|
this.pictureBoxQR = new System.Windows.Forms.PictureBox();
|
||||||
|
this.btnPrint = new System.Windows.Forms.Button();
|
||||||
|
this.btnSave = new System.Windows.Forms.Button();
|
||||||
|
this.btnClose = new System.Windows.Forms.Button();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxQR)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBoxQR
|
||||||
|
//
|
||||||
|
this.pictureBoxQR.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||||
|
this.pictureBoxQR.Location = new System.Drawing.Point(50, 20);
|
||||||
|
this.pictureBoxQR.Name = "pictureBoxQR";
|
||||||
|
this.pictureBoxQR.Size = new System.Drawing.Size(300, 300);
|
||||||
|
this.pictureBoxQR.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||||
|
this.pictureBoxQR.TabIndex = 0;
|
||||||
|
this.pictureBoxQR.TabStop = false;
|
||||||
|
//
|
||||||
|
// btnPrint
|
||||||
|
//
|
||||||
|
this.btnPrint.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(91)))), ((int)(((byte)(209)))), ((int)(((byte)(45)))));
|
||||||
|
this.btnPrint.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnPrint.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnPrint.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnPrint.Location = new System.Drawing.Point(50, 340);
|
||||||
|
this.btnPrint.Name = "btnPrint";
|
||||||
|
this.btnPrint.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnPrint.TabIndex = 1;
|
||||||
|
this.btnPrint.Text = "Печать";
|
||||||
|
this.btnPrint.UseVisualStyleBackColor = false;
|
||||||
|
this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
this.btnSave.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
this.btnSave.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnSave.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnSave.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnSave.Location = new System.Drawing.Point(160, 340);
|
||||||
|
this.btnSave.Name = "btnSave";
|
||||||
|
this.btnSave.Size = new System.Drawing.Size(80, 35);
|
||||||
|
this.btnSave.TabIndex = 2;
|
||||||
|
this.btnSave.Text = "Сохр.";
|
||||||
|
this.btnSave.UseVisualStyleBackColor = false;
|
||||||
|
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
|
||||||
|
//
|
||||||
|
// btnClose
|
||||||
|
//
|
||||||
|
this.btnClose.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(176)))), ((int)(((byte)(253)))), ((int)(((byte)(161)))));
|
||||||
|
this.btnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnClose.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.btnClose.ForeColor = System.Drawing.Color.Black;
|
||||||
|
this.btnClose.Location = new System.Drawing.Point(250, 340);
|
||||||
|
this.btnClose.Name = "btnClose";
|
||||||
|
this.btnClose.Size = new System.Drawing.Size(100, 35);
|
||||||
|
this.btnClose.TabIndex = 4;
|
||||||
|
this.btnClose.Text = "✖ Закрыть";
|
||||||
|
this.btnClose.UseVisualStyleBackColor = false;
|
||||||
|
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||||
|
//
|
||||||
|
// QRCodeViewerForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
|
||||||
|
this.ClientSize = new System.Drawing.Size(400, 450);
|
||||||
|
this.Controls.Add(this.pictureBoxQR);
|
||||||
|
this.Controls.Add(this.btnPrint);
|
||||||
|
this.Controls.Add(this.btnSave);
|
||||||
|
this.Controls.Add(this.btnClose);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "QRCodeViewerForm";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
this.Text = "QR-код товара";
|
||||||
|
this.Load += new System.EventHandler(this.QRCodeViewerForm_Load);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBoxQR)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
QRCodeViewerForm.cs
Normal file
121
QRCodeViewerForm.cs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Printing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Neshina1703
|
||||||
|
{
|
||||||
|
public partial class QRCodeViewerForm : Form
|
||||||
|
{
|
||||||
|
private int medicationId;
|
||||||
|
private string qrCodePath;
|
||||||
|
|
||||||
|
public QRCodeViewerForm(int medicationId)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.medicationId = medicationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void QRCodeViewerForm_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
LoadQRCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadQRCode()
|
||||||
|
{
|
||||||
|
// Получить путь к QR-коду из БД
|
||||||
|
var query = "SELECT qr_code_path, medication_name FROM medications WHERE id = @id";
|
||||||
|
var parameters = new MySql.Data.MySqlClient.MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySql.Data.MySqlClient.MySqlParameter("@id", medicationId)
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = DB.ExecuteQuery(query, parameters);
|
||||||
|
|
||||||
|
if (table.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
string name = table.Rows[0]["medication_name"].ToString();
|
||||||
|
qrCodePath = table.Rows[0]["qr_code_path"]?.ToString();
|
||||||
|
|
||||||
|
this.Text = $"QR-код: {name}";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(qrCodePath) && File.Exists(qrCodePath))
|
||||||
|
{
|
||||||
|
pictureBoxQR.Image = Image.FromFile(qrCodePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Сгенерировать если не существует
|
||||||
|
qrCodePath = QRCodeHelper.GenerateQRCodeForMedication(medicationId, name);
|
||||||
|
if (!string.IsNullOrEmpty(qrCodePath))
|
||||||
|
pictureBoxQR.Image = Image.FromFile(qrCodePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnPrint_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (pictureBoxQR.Image != null)
|
||||||
|
{
|
||||||
|
PrintDocument printDoc = new PrintDocument();
|
||||||
|
printDoc.PrintPage += (s, ev) =>
|
||||||
|
{
|
||||||
|
ev.Graphics.DrawImage(pictureBoxQR.Image,
|
||||||
|
new Rectangle(100, 100, 400, 400));
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintDialog printDialog = new PrintDialog();
|
||||||
|
printDialog.Document = printDoc;
|
||||||
|
|
||||||
|
if (printDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
printDoc.Print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (pictureBoxQR.Image != null)
|
||||||
|
{
|
||||||
|
SaveFileDialog saveDialog = new SaveFileDialog();
|
||||||
|
saveDialog.Filter = "PNG Images|*.png|JPEG Images|*.jpg";
|
||||||
|
saveDialog.Title = "Сохранить QR-код";
|
||||||
|
|
||||||
|
if (saveDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
pictureBoxQR.Image.Save(saveDialog.FileName);
|
||||||
|
MessageBox.Show("QR-код сохранен!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnGenerateNew_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var query = "SELECT medication_name FROM medications WHERE id = @id";
|
||||||
|
var parameters = new MySql.Data.MySqlClient.MySqlParameter[]
|
||||||
|
{
|
||||||
|
new MySql.Data.MySqlClient.MySqlParameter("@id", medicationId)
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = DB.ExecuteQuery(query, parameters);
|
||||||
|
if (table.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
string name = table.Rows[0]["medication_name"].ToString();
|
||||||
|
qrCodePath = QRCodeHelper.GenerateQRCodeForMedication(medicationId, name);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(qrCodePath))
|
||||||
|
{
|
||||||
|
pictureBoxQR.Image = Image.FromFile(qrCodePath);
|
||||||
|
MessageBox.Show("QR-код перегенерирован!", "Успех",
|
||||||
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnClose_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1253
QRCodeViewerForm.resx
Normal file
1253
QRCodeViewerForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/Debug/MySql.Data.dll
Normal file
BIN
bin/Debug/MySql.Data.dll
Normal file
Binary file not shown.
BIN
bin/Debug/Neshina1703.exe
Normal file
BIN
bin/Debug/Neshina1703.exe
Normal file
Binary file not shown.
6
bin/Debug/Neshina1703.exe.config
Normal file
6
bin/Debug/Neshina1703.exe.config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
BIN
bin/Debug/Neshina1703.pdb
Normal file
BIN
bin/Debug/Neshina1703.pdb
Normal file
Binary file not shown.
BIN
bin/Debug/Newtonsoft.Json.dll
Normal file
BIN
bin/Debug/Newtonsoft.Json.dll
Normal file
Binary file not shown.
11698
bin/Debug/Newtonsoft.Json.xml
Normal file
11698
bin/Debug/Newtonsoft.Json.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/Debug/QRCoder.dll
Normal file
BIN
bin/Debug/QRCoder.dll
Normal file
Binary file not shown.
5590
bin/Debug/QRCoder.xml
Normal file
5590
bin/Debug/QRCoder.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/Debug/QRCodes/medication_15.png
Normal file
BIN
bin/Debug/QRCodes/medication_15.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
bin/Debug/QRCodes/medication_16.png
Normal file
BIN
bin/Debug/QRCodes/medication_16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
bin/Debug/QRCodes/medication_26.png
Normal file
BIN
bin/Debug/QRCodes/medication_26.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
bin/Debug/QRCodes/medication_31.png
Normal file
BIN
bin/Debug/QRCodes/medication_31.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||||
BIN
obj/Debug/DesignTimeResolveAssemblyReferences.cache
Normal file
BIN
obj/Debug/DesignTimeResolveAssemblyReferences.cache
Normal file
Binary file not shown.
BIN
obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
Normal file
BIN
obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.AdminForm.resources
Normal file
BIN
obj/Debug/Neshina1703.AdminForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.EmployeeForm.resources
Normal file
BIN
obj/Debug/Neshina1703.EmployeeForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.LoginForm.resources
Normal file
BIN
obj/Debug/Neshina1703.LoginForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.MessengerForm.resources
Normal file
BIN
obj/Debug/Neshina1703.MessengerForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.OrderForm.resources
Normal file
BIN
obj/Debug/Neshina1703.OrderForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.ProductForm.resources
Normal file
BIN
obj/Debug/Neshina1703.ProductForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.Properties.Resources.resources
Normal file
BIN
obj/Debug/Neshina1703.Properties.Resources.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.QRCodeViewerForm.resources
Normal file
BIN
obj/Debug/Neshina1703.QRCodeViewerForm.resources
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.csproj.AssemblyReference.cache
Normal file
BIN
obj/Debug/Neshina1703.csproj.AssemblyReference.cache
Normal file
Binary file not shown.
0
obj/Debug/Neshina1703.csproj.CopyComplete
Normal file
0
obj/Debug/Neshina1703.csproj.CopyComplete
Normal file
1
obj/Debug/Neshina1703.csproj.CoreCompileInputs.cache
Normal file
1
obj/Debug/Neshina1703.csproj.CoreCompileInputs.cache
Normal file
@ -0,0 +1 @@
|
|||||||
|
6a8573826ab569b5b5838a2076561373d6ed42120d7437c1fc1e2ac46fafbec4
|
||||||
22
obj/Debug/Neshina1703.csproj.FileListAbsolute.txt
Normal file
22
obj/Debug/Neshina1703.csproj.FileListAbsolute.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.csproj.AssemblyReference.cache
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.AdminForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.EmployeeForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.LoginForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.OrderForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.ProductForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.Properties.Resources.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.csproj.GenerateResource.cache
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.csproj.CoreCompileInputs.cache
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\Neshina1703.exe.config
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\Neshina1703.exe
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\Neshina1703.pdb
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\MySql.Data.dll
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.csproj.CopyComplete
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.exe
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.pdb
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\Newtonsoft.Json.dll
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\QRCoder.dll
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\Newtonsoft.Json.xml
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\bin\Debug\QRCoder.xml
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.QRCodeViewerForm.resources
|
||||||
|
C:\Users\Student\ISP31\Neshina1703\obj\Debug\Neshina1703.MessengerForm.resources
|
||||||
BIN
obj/Debug/Neshina1703.csproj.GenerateResource.cache
Normal file
BIN
obj/Debug/Neshina1703.csproj.GenerateResource.cache
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.exe
Normal file
BIN
obj/Debug/Neshina1703.exe
Normal file
Binary file not shown.
BIN
obj/Debug/Neshina1703.pdb
Normal file
BIN
obj/Debug/Neshina1703.pdb
Normal file
Binary file not shown.
5
packages.config
Normal file
5
packages.config
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
|
||||||
|
<package id="QRCoder" version="1.7.0" targetFramework="net472" />
|
||||||
|
</packages>
|
||||||
BIN
packages/Newtonsoft.Json.13.0.4/.signature.p7s
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/.signature.p7s
vendored
Normal file
Binary file not shown.
20
packages/Newtonsoft.Json.13.0.4/LICENSE.md
vendored
Normal file
20
packages/Newtonsoft.Json.13.0.4/LICENSE.md
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2007 James Newton-King
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
BIN
packages/Newtonsoft.Json.13.0.4/Newtonsoft.Json.13.0.4.nupkg
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/Newtonsoft.Json.13.0.4.nupkg
vendored
Normal file
Binary file not shown.
71
packages/Newtonsoft.Json.13.0.4/README.md
vendored
Normal file
71
packages/Newtonsoft.Json.13.0.4/README.md
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#  Json.NET
|
||||||
|
|
||||||
|
[](https://www.nuget.org/packages/Newtonsoft.Json/)
|
||||||
|
[](https://dev.azure.com/jamesnk/Public/_build/latest?definitionId=8)
|
||||||
|
|
||||||
|
Json.NET is a popular high-performance JSON framework for .NET
|
||||||
|
|
||||||
|
## Serialize JSON
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
Product product = new Product();
|
||||||
|
product.Name = "Apple";
|
||||||
|
product.Expiry = new DateTime(2008, 12, 28);
|
||||||
|
product.Sizes = new string[] { "Small" };
|
||||||
|
|
||||||
|
string json = JsonConvert.SerializeObject(product);
|
||||||
|
// {
|
||||||
|
// "Name": "Apple",
|
||||||
|
// "Expiry": "2008-12-28T00:00:00",
|
||||||
|
// "Sizes": [
|
||||||
|
// "Small"
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deserialize JSON
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
string json = @"{
|
||||||
|
'Name': 'Bad Boys',
|
||||||
|
'ReleaseDate': '1995-4-7T00:00:00',
|
||||||
|
'Genres': [
|
||||||
|
'Action',
|
||||||
|
'Comedy'
|
||||||
|
]
|
||||||
|
}";
|
||||||
|
|
||||||
|
Movie m = JsonConvert.DeserializeObject<Movie>(json);
|
||||||
|
|
||||||
|
string name = m.Name;
|
||||||
|
// Bad Boys
|
||||||
|
```
|
||||||
|
|
||||||
|
## LINQ to JSON
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
JArray array = new JArray();
|
||||||
|
array.Add("Manual text");
|
||||||
|
array.Add(new DateTime(2000, 5, 23));
|
||||||
|
|
||||||
|
JObject o = new JObject();
|
||||||
|
o["MyArray"] = array;
|
||||||
|
|
||||||
|
string json = o.ToString();
|
||||||
|
// {
|
||||||
|
// "MyArray": [
|
||||||
|
// "Manual text",
|
||||||
|
// "2000-05-23T00:00:00"
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Homepage](https://www.newtonsoft.com/json)
|
||||||
|
- [Documentation](https://www.newtonsoft.com/json/help)
|
||||||
|
- [NuGet Package](https://www.nuget.org/packages/Newtonsoft.Json)
|
||||||
|
- [Release Notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
|
||||||
|
- [Contributing Guidelines](https://github.com/JamesNK/Newtonsoft.Json/blob/master/CONTRIBUTING.md)
|
||||||
|
- [License](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
|
||||||
|
- [Stack Overflow](https://stackoverflow.com/questions/tagged/json.net)
|
||||||
BIN
packages/Newtonsoft.Json.13.0.4/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/net20/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
10713
packages/Newtonsoft.Json.13.0.4/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
10713
packages/Newtonsoft.Json.13.0.4/lib/net20/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/net35/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
9861
packages/Newtonsoft.Json.13.0.4/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
9861
packages/Newtonsoft.Json.13.0.4/lib/net35/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/net40/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
10061
packages/Newtonsoft.Json.13.0.4/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
10061
packages/Newtonsoft.Json.13.0.4/lib/net40/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/net45/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
11698
packages/Newtonsoft.Json.13.0.4/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
11698
packages/Newtonsoft.Json.13.0.4/lib/net45/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/net6.0/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/net6.0/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
11431
packages/Newtonsoft.Json.13.0.4/lib/net6.0/Newtonsoft.Json.xml
vendored
Normal file
11431
packages/Newtonsoft.Json.13.0.4/lib/net6.0/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.0/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.0/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
11386
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.0/Newtonsoft.Json.xml
vendored
Normal file
11386
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.0/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.3/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.3/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
11508
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.3/Newtonsoft.Json.xml
vendored
Normal file
11508
packages/Newtonsoft.Json.13.0.4/lib/netstandard1.3/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard2.0/Newtonsoft.Json.dll
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/lib/netstandard2.0/Newtonsoft.Json.dll
vendored
Normal file
Binary file not shown.
11673
packages/Newtonsoft.Json.13.0.4/lib/netstandard2.0/Newtonsoft.Json.xml
vendored
Normal file
11673
packages/Newtonsoft.Json.13.0.4/lib/netstandard2.0/Newtonsoft.Json.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/Newtonsoft.Json.13.0.4/packageIcon.png
vendored
Normal file
BIN
packages/Newtonsoft.Json.13.0.4/packageIcon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
BIN
packages/QRCoder.1.7.0/.signature.p7s
vendored
Normal file
BIN
packages/QRCoder.1.7.0/.signature.p7s
vendored
Normal file
Binary file not shown.
BIN
packages/QRCoder.1.7.0/QRCoder.1.7.0.nupkg
vendored
Normal file
BIN
packages/QRCoder.1.7.0/QRCoder.1.7.0.nupkg
vendored
Normal file
Binary file not shown.
195
packages/QRCoder.1.7.0/README.md
vendored
Normal file
195
packages/QRCoder.1.7.0/README.md
vendored
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# QRCoder
|
||||||
|
|
||||||
|
[](LICENSE.txt)
|
||||||
|
[](https://www.nuget.org/packages/QRCoder/)
|
||||||
|
[](https://www.nuget.org/packages/QRCoder)
|
||||||
|
[](https://codecov.io/gh/Shane32/QRCoder)
|
||||||
|
[](https://github.com/Shane32/QRCoder/graphs/contributors)
|
||||||
|
|
||||||
|
QRCoder is a simple C# library originally created by [Raffael Herrmann](https://raffaelherrmann.de) for generating QR codes and Micro QR codes.
|
||||||
|
|
||||||
|
- 📚 [Documentation & Wiki](https://github.com/Shane32/QRCoder/wiki)
|
||||||
|
- 📋 [Release notes / Changelog](https://github.com/Shane32/QRCoder/releases)
|
||||||
|
- 🚀 [Upcoming features](https://github.com/Shane32/QRCoder/milestones)
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- 🚀 **Zero dependencies** - No external libraries required (framework dependencies only)
|
||||||
|
- ⚡ **Fast performance** - Optimized QR code generation with low memory footprint
|
||||||
|
- 🎨 **Multiple output formats** - PNG, SVG, PDF, ASCII, Bitmap, PostScript, and more
|
||||||
|
- 📱 **23+ payload generators** - WiFi, vCard, URLs, payments, and many more
|
||||||
|
- 🔧 **Highly configurable** - Error correction levels, custom colors, logos, and styling
|
||||||
|
- 🌐 **Cross-platform** - Supports .NET 5+, .NET Framework 3.5+, .NET Core 1.0+, and .NET Standard 1.3+
|
||||||
|
- 📦 **Micro QR codes** - Smaller QR codes for space-constrained applications
|
||||||
|
|
||||||
|
## 📦 Installation
|
||||||
|
|
||||||
|
Install via NuGet Package Manager:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PM> Install-Package QRCoder
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
Generate a QR code with just a few lines of code, either using a renderer's static helper method, or by creating a QR code first and then passing it to a renderer:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
// Generate a simple black and white PNG QR code
|
||||||
|
byte[] qrCodeImage = PngByteQRCodeHelper.GetQRCode("Hello World", QRCodeGenerator.ECCLevel.Q, 20);
|
||||||
|
|
||||||
|
// Generate a scalable black and white SVG QR code
|
||||||
|
using var qrCodeData = QRCodeGenerator.GenerateQrCode("Hello World", QRCodeGenerator.ECCLevel.Q);
|
||||||
|
using var svgRenderer = new SvgQRCode(qrCodeData);
|
||||||
|
string svg = svgRenderer.GetGraphic();
|
||||||
|
```
|
||||||
|
|
||||||
|
For more examples and detailed usage instructions, see: [Wiki: How to use QRCoder](https://github.com/Shane32/QRCoder/wiki/How-to-use-QRCoder)
|
||||||
|
|
||||||
|
## 📱 Payload Generators
|
||||||
|
|
||||||
|
QR codes can encode structured data that triggers specific actions when scanned (e.g., WiFi credentials, contact information, URLs). QRCoder includes payload generators that create properly formatted strings for these common use cases.
|
||||||
|
|
||||||
|
### Usage Example
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
// Create a bookmark payload
|
||||||
|
var bookmarkPayload = new PayloadGenerator.Bookmark("https://github.com/Shane32/QRCoder", "QRCoder Repository");
|
||||||
|
|
||||||
|
// Generate the QR code data from the payload
|
||||||
|
using var qrCodeData = QRCodeGenerator.GenerateQrCode(bookmarkPayload);
|
||||||
|
|
||||||
|
// Or override the ECC level
|
||||||
|
using var qrCodeData2 = QRCodeGenerator.GenerateQrCode(bookmarkPayload, QRCodeGenerator.ECCLevel.H);
|
||||||
|
|
||||||
|
// Render the QR code
|
||||||
|
using var pngRenderer = new PngByteQRCode(qrCodeData);
|
||||||
|
byte[] qrCodeImage = pngRenderer.GetGraphic(20);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Available Payload Types
|
||||||
|
|
||||||
|
| Payload Type | Usage Example | Description |
|
||||||
|
|--------------|---------------|-------------|
|
||||||
|
| [**WiFi**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#321-wifi) | `new PayloadGenerator.WiFi(ssid, password, auth)` | WiFi network credentials |
|
||||||
|
| [**URL**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#319-url) | `new PayloadGenerator.Url("https://example.com")` | Website URL |
|
||||||
|
| [**Bookmark**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#33-bookmark) | `new PayloadGenerator.Bookmark(url, title)` | Browser bookmark |
|
||||||
|
| [**Mail**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#38-mail) | `new PayloadGenerator.Mail(email, subject, body)` | Email with pre-filled fields |
|
||||||
|
| [**SMS**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#317-sms) | `new PayloadGenerator.SMS(number, message)` | SMS message |
|
||||||
|
| [**MMS**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#39-mms) | `new PayloadGenerator.MMS(number, subject)` | MMS message |
|
||||||
|
| [**Geolocation**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#36-geolocation) | `new PayloadGenerator.Geolocation(lat, lng)` | GPS coordinates |
|
||||||
|
| [**PhoneNumber**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#312-phonenumber) | `new PayloadGenerator.PhoneNumber(number)` | Phone number for calling |
|
||||||
|
| [**SkypeCall**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#315-skype-call) | `new PayloadGenerator.SkypeCall(username)` | Skype call |
|
||||||
|
| [**WhatsAppMessage**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#320-whatsappmessage) | `new PayloadGenerator.WhatsAppMessage(number, msg)` | WhatsApp message |
|
||||||
|
| [**ContactData**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#35-contactdata-mecardvcard) | `new PayloadGenerator.ContactData(...)` | vCard/MeCard contact |
|
||||||
|
| [**CalendarEvent**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#34-calendar-events-icalvevent) | `new PayloadGenerator.CalendarEvent(...)` | iCal/vEvent |
|
||||||
|
| [**OneTimePassword**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#311-one-time-password) | `new PayloadGenerator.OneTimePassword(...)` | TOTP/HOTP for 2FA |
|
||||||
|
| [**BitcoinAddress**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#32-bitcoin-like-crypto-currency-payment-address) | `new PayloadGenerator.BitcoinAddress(address)` | Bitcoin payment |
|
||||||
|
| [**BitcoinCashAddress**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#32-bitcoin-like-crypto-currency-payment-address) | `new PayloadGenerator.BitcoinCashAddress(address)` | Bitcoin Cash payment |
|
||||||
|
| [**LitecoinAddress**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#32-bitcoin-like-crypto-currency-payment-address) | `new PayloadGenerator.LitecoinAddress(address)` | Litecoin payment |
|
||||||
|
| [**MoneroTransaction**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#310-monero-addresspayment) | `new PayloadGenerator.MoneroTransaction(...)` | Monero payment |
|
||||||
|
| [**SwissQrCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#318-swissqrcode-iso-20022) | `new PayloadGenerator.SwissQrCode(...)` | Swiss QR bill (ISO-20022) |
|
||||||
|
| [**Girocode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#37-girocode) | `new PayloadGenerator.Girocode(...)` | SEPA payment (EPC QR) |
|
||||||
|
| [**BezahlCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#31-bezahlcode) | `new PayloadGenerator.BezahlCode(...)` | German payment code |
|
||||||
|
| [**RussiaPaymentOrder**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#313-russiapaymentorder) | `new PayloadGenerator.RussiaPaymentOrder(...)` | Russian payment (ГОСТ Р 56042-2014) |
|
||||||
|
| [**SlovenianUpnQr**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#316-slovenianupnqr) | `new PayloadGenerator.SlovenianUpnQr(...)` | Slovenian UPN payment |
|
||||||
|
| [**ShadowSocksConfig**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators#314-shadowsocks-configuration) | `new PayloadGenerator.ShadowSocksConfig(...)` | Shadowsocks proxy config |
|
||||||
|
|
||||||
|
For detailed information about payload generators, see: [Wiki: Advanced usage - Payload generators](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---Payload-generators)
|
||||||
|
|
||||||
|
## 🎨 QR Code Renderers
|
||||||
|
|
||||||
|
QRCoder provides multiple renderers for different output formats and use cases. Each renderer has specific capabilities and framework requirements.
|
||||||
|
|
||||||
|
| Renderer | Output Format | Requires | Usage Example |
|
||||||
|
|----------|---------------|----------|---------------|
|
||||||
|
| [**PngByteQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#25-pngbyteqrcode-renderer-in-detail) | PNG byte array | — | `new PngByteQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**SvgQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#26-svgqrcode-renderer-in-detail) | SVG string | — | `new SvgQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**QRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#21-qrcode-renderer-in-detail) | System.Drawing.Bitmap | Windows¹ | `new QRCode(data).GetGraphic(20)` |
|
||||||
|
| [**ArtQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#211-artqrcode-renderer-in-detail) | Artistic bitmap with custom images | Windows¹ | `new ArtQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**AsciiQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#22-asciiqrcode-renderer-in-detail) | ASCII art string | — | `new AsciiQRCode(data).GetGraphic(1)`<br/>`new AsciiQRCode(data).GetGraphicSmall()` |
|
||||||
|
| [**Base64QRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#23-base64qrcode-renderer-in-detail) | Base64 encoded image | — | `new Base64QRCode(data).GetGraphic(20)` |
|
||||||
|
| [**BitmapByteQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#24-bitmapbyteqrcode-renderer-in-detail) | BMP byte array | — | `new BitmapByteQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**PdfByteQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#210-pdfbyteqrcode-renderer-in-detail) | PDF byte array | — | `new PdfByteQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**PostscriptQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#29-postscriptqrcode-renderer-in-detail) | PostScript/EPS string | — | `new PostscriptQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**XamlQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#28-xamlqrcode-renderer-in-detail) | XAML DrawingImage | XAML² | `new XamlQRCode(data).GetGraphic(20)` |
|
||||||
|
| [**UnityQRCode**](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#27-unityqrcode-renderer-in-detail) | Unity Texture2D | Unity³ | `new UnityQRCode(data).GetGraphic(20)` |
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- ¹ Requires Windows or System.Drawing.Common package (uses GDI+)
|
||||||
|
- ² Requires the [QRCoder.Xaml](https://www.nuget.org/packages/QRCoder.Xaml) package
|
||||||
|
- ³ Requires the [QRCoder.Unity](https://www.nuget.org/packages/QRCoder.Unity) package
|
||||||
|
|
||||||
|
**Framework Compatibility:** Not all renderers are available on all target frameworks. Check the [compatibility table](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers#2-overview-of-the-different-renderers) for details.
|
||||||
|
|
||||||
|
For comprehensive information about renderers, see: [Wiki: Advanced usage - QR Code renderers](https://github.com/Shane32/QRCoder/wiki/Advanced-usage---QR-Code-renderers)
|
||||||
|
|
||||||
|
## 🔧 Advanced Features
|
||||||
|
|
||||||
|
### Micro QR Codes
|
||||||
|
|
||||||
|
QRCoder supports Micro QR codes, which are smaller versions of standard QR codes suitable for applications with limited space. Micro QR codes have significantly limited storage capacity—as few as 5 numeric digits (M1) or as many as 35 numeric digits (M4), with alphanumeric and byte data storing considerably less.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
// Generate a Micro QR code (versions M1-M4, represented as -1 to -4)
|
||||||
|
using var qrCodeData = QRCodeGenerator.GenerateMicroQrCode("Hello", QRCodeGenerator.ECCLevel.L, requestedVersion: -2);
|
||||||
|
using var qrCode = new PngByteQRCode(qrCodeData);
|
||||||
|
byte[] qrCodeImage = qrCode.GetGraphic(20);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Micro QR codes have limitations on data capacity and error correction levels. They support versions M1 through M4 (specified as -1 to -4), and not all ECC levels are available for all versions. M1 only supports detection (no ECC), M2 and M3 support L and M levels, and M4 supports L, M, and Q levels. For detailed capacity tables, see the [Micro QR Code specification](https://www.qrcode.com/en/codes/microqr.html).
|
||||||
|
|
||||||
|
### Working with QRCodeData
|
||||||
|
|
||||||
|
`QRCodeData` is the core data structure that represents a QR code's module matrix. It contains a `List<BitArray>` called `ModuleMatrix`, where each `BitArray` represents a row of modules in the QR code. A module is set to `true` for dark/black modules and `false` for light/white modules.
|
||||||
|
|
||||||
|
You can access the `ModuleMatrix` directly to read or manipulate the QR code data at the module level. This is useful for custom rendering implementations or analyzing QR code structure.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using QRCoder;
|
||||||
|
|
||||||
|
// Generate QR code data
|
||||||
|
using var qrCodeData = QRCodeGenerator.GenerateQrCode("Hello World", QRCodeGenerator.ECCLevel.Q);
|
||||||
|
|
||||||
|
// Access the module matrix
|
||||||
|
var moduleMatrix = qrCodeData.ModuleMatrix;
|
||||||
|
int size = moduleMatrix.Count; // Size of the QR code (includes quiet zone)
|
||||||
|
|
||||||
|
// Manually render as ASCII (versus the included ASCII renderer)
|
||||||
|
for (int y = 0; y < size; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < size; x++)
|
||||||
|
{
|
||||||
|
// Check if module is dark (true) or light (false)
|
||||||
|
bool isDark = moduleMatrix[y][x];
|
||||||
|
Console.Write(isDark ? "██" : " ");
|
||||||
|
}
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 CI Builds
|
||||||
|
|
||||||
|
The NuGet feed contains only **major/stable** releases. If you want the latest functions and features, you can use the CI builds [via Github packages](https://github.com/Shane32/qrcoder/packages).
|
||||||
|
|
||||||
|
_(More information on how to use Github Packages in Nuget Package Manager can be [found here](https://samlearnsazure.blog/2021/08/08/consuming-a-nuget-package-from-github-packages/).)_
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
QRCoder is a project originally by [Raffael Herrmann](https://raffaelherrmann.de) and was first released in 10/2013. It's licensed under the [MIT license](https://github.com/Shane32/QRCoder/blob/master/LICENSE.txt).
|
||||||
|
|
||||||
|
Since 2025, QRCoder has been maintained by [Shane32](https://github.com/Shane32) with contributions from the community.
|
||||||
|
|
||||||
|
## 🙏 Credits
|
||||||
|
|
||||||
|
Glory to Jehovah, Lord of Lords and King of Kings, creator of Heaven and Earth, who through his Son Jesus Christ, has redeemed me to become a child of God. -[Shane32](https://github.com/Shane32)
|
||||||
BIN
packages/QRCoder.1.7.0/lib/net35/QRCoder.dll
vendored
Normal file
BIN
packages/QRCoder.1.7.0/lib/net35/QRCoder.dll
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user