AppCore.Helpers 1.0.7

There is a newer version of this package available.
See the version list below for details.
dotnet add package AppCore.Helpers --version 1.0.7
                    
NuGet\Install-Package AppCore.Helpers -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AppCore.Helpers" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AppCore.Helpers" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="AppCore.Helpers" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AppCore.Helpers --version 1.0.7
                    
#r "nuget: AppCore.Helpers, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AppCore.Helpers@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AppCore.Helpers&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=AppCore.Helpers&version=1.0.7
                    
Install as a Cake Tool
DatabaseService.Configure(
    "Server=ИМЯ_СЕРВЕРА;Database=toy_shop;User ID=ЛОГИН;Password=ПАРОЛЬ;TrustServerCertificate=True;");

UserSession.cs

    public static class UserSession
    {
        public static int UserId { get; set; }

        public static string Login { get; set; } = string.Empty;

        public static string FullName { get; set; } = "Гость";

        public static string Role { get; set; } = "Гость";

        public static void SetUser(int userId, string login, string fullName, string role)
        {
            UserId = userId;
            Login = login;
            FullName = fullName;
            Role = role;
        }

        public static void SetGuest()
        {
            UserId = 0;
            Login = "guest";
        }

        public static void Clear()
        {
            UserId = 0;
            Login = string.Empty;
            FullName = "Гость";
            Role = "Гость";
        }
    }

AuthService.cs

using AppCore.Helpers;
using Demo_Ex_8.Models;
using System.Data;

namespace Demo_Ex_8.Services
{
    public static class AuthService
    {
        public static bool Login(string login, string password)
        {
            try
            {
                if (!ValidationHelper.ValidateRequiredFields(new()
                {
                    { "Логин", login },
                    { "Пароль", password }
                }))
                {
                    return false;
                }

                string query = """
                    SELECT
                        u.id,
                        u.full_name,
                        u.login,
                        r.role_name
                    FROM users u
                    JOIN roles r ON r.id = u.role_id
                    WHERE u.login = @login
                      AND u.password = @password
                    """;

                DataTable table = DatabaseService.ExecuteSelect(
                    query,
                    new Dictionary<string, object>
                    {
                        { "@login", login },
                        { "@password", password }
                    });

                if (table.Rows.Count == 0)
                {
                    MessageBoxHelper.Warning("Неверный логин или пароль");
                    return false;
                }

                DataRow row = table.Rows[0];

                UserSession.SetUser(
                    Convert.ToInt32(row["id"]),
                    row["login"].ToString(),
                    row["full_name"].ToString(),
                    row["role_name"].ToString());

                return true;
            }
            catch (Exception ex)
            {
                MessageBoxHelper.ShowException(ex);
                return false;
            }
        }

        public static void LoginAsGuest()
        {
            UserSession.SetGuest();
        }

        public static void Logout()
        {
            UserSession.Clear();
        }
    }
}

ProductsService.cs

using AppCore.Helpers;
using System.Data;
using System.Text;

namespace Demo_Ex_8.Services
{
    public static class ProductsService
    {
        public static DataTable GetSuppliers()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, supplier_name FROM suppliers ORDER BY supplier_name");
        }

        public static DataTable GetManufacturers()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, manufacturer_name FROM manufacturers ORDER BY manufacturer_name");
        }

        public static DataTable GetUnits()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, unit_name FROM units ORDER BY unit_name");
        }

        public static DataTable GetCategories()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, category_name FROM categories ORDER BY category_name");
        }

        public static DataTable GetProductById(int productId)
        {
            return DatabaseService.ExecuteSelect(
                "SELECT * FROM products WHERE id = @id",
                new Dictionary<string, object>
                {
                    { "@id", productId }
                });
        }

        public static DataTable GetProducts(
            string search = "",
            int supplierId = 0,
            string sortType = "")
        {
            StringBuilder query = new("""
                SELECT
                    p.id,
                    p.article,
                    p.title,
                    u.unit_name,
                    p.price,
                    s.supplier_name,
                    m.manufacturer_name,
                    c.category_name,
                    p.discount,
                    p.quantity,
                    p.description,
                    p.picture_path
                FROM products p
                JOIN units u ON p.unit_id = u.id
                JOIN suppliers s ON p.supplier_id = s.id
                JOIN manufacturers m ON p.manufacturer_id = m.id
                JOIN categories c ON p.category_id = c.id
                WHERE 1 = 1
                """);

            Dictionary<string, object> parameters = new();

            QueryBuilderHelper.AddTextSearch(
                query,
                parameters,
                search,
                "p.title",
                "p.article",
                "p.description",
                "s.supplier_name",
                "m.manufacturer_name",
                "c.category_name");

            QueryBuilderHelper.AddExactFilter(
                query,
                parameters,
                "p.supplier_id",
                "@supplierId",
                supplierId,
                0);

            QueryBuilderHelper.AddOrderBy(
                query,
                sortType,
                new Dictionary<string, string>
                {
                    { "Цена по возрастанию", "p.price ASC" },
                    { "Цена по убыванию", "p.price DESC" },
                    { "Количество по возрастанию", "p.quantity ASC" },
                    { "Количество по убыванию", "p.quantity DESC" },
                    { "Скидка по возрастанию", "p.discount ASC" },
                    { "Скидка по убыванию", "p.discount DESC" },
                    { "Название А-Я", "p.title ASC" },
                    { "Название Я-А", "p.title DESC" }
                },
                "p.id ASC");

            return DatabaseService.ExecuteSelect(query.ToString(), parameters);
        }

        public static bool CreateProduct(
            string article,
            string title,
            int unitId,
            decimal price,
            int supplierId,
            int manufacturerId,
            int categoryId,
            int discount,
            int quantity,
            string description,
            string picturePath)
        {
            string query = """
                INSERT INTO products
                (
                    article,
                    title,
                    unit_id,
                    price,
                    supplier_id,
                    manufacturer_id,
                    category_id,
                    discount,
                    quantity,
                    description,
                    picture_path
                )
                VALUES
                (
                    @article,
                    @title,
                    @unitId,
                    @price,
                    @supplierId,
                    @manufacturerId,
                    @categoryId,
                    @discount,
                    @quantity,
                    @description,
                    @picturePath
                )
                """;

            return DatabaseService.ExecuteNonQuery(
                query,
                new Dictionary<string, object>
                {
                    { "@article", article },
                    { "@title", title },
                    { "@unitId", unitId },
                    { "@price", price },
                    { "@supplierId", supplierId },
                    { "@manufacturerId", manufacturerId },
                    { "@categoryId", categoryId },
                    { "@discount", discount },
                    { "@quantity", quantity },
                    { "@description", description },
                    { "@picturePath", picturePath }
                });
        }

        public static bool UpdateProduct(
            int id,
            string article,
            string title,
            int unitId,
            decimal price,
            int supplierId,
            int manufacturerId,
            int categoryId,
            int discount,
            int quantity,
            string description,
            string picturePath)
        {
            string query = """
                UPDATE products
                SET
                    article = @article,
                    title = @title,
                    unit_id = @unitId,
                    price = @price,
                    supplier_id = @supplierId,
                    manufacturer_id = @manufacturerId,
                    category_id = @categoryId,
                    discount = @discount,
                    quantity = @quantity,
                    description = @description,
                    picture_path = @picturePath
                WHERE id = @id
                """;

            return DatabaseService.ExecuteNonQuery(
                query,
                new Dictionary<string, object>
                {
                    { "@id", id },
                    { "@article", article },
                    { "@title", title },
                    { "@unitId", unitId },
                    { "@price", price },
                    { "@supplierId", supplierId },
                    { "@manufacturerId", manufacturerId },
                    { "@categoryId", categoryId },
                    { "@discount", discount },
                    { "@quantity", quantity },
                    { "@description", description },
                    { "@picturePath", picturePath }
                });
        }

        public static bool DeleteProduct(int id)
        {
            return DatabaseService.ExecuteNonQuery(
                "DELETE FROM products WHERE id = @id",
                new Dictionary<string, object>
                {
                    { "@id", id }
                });
        }

        public static bool ProductExistsInOrders(int productId)
        {
            object? result = DatabaseService.ExecuteScalar(
                """
                SELECT COUNT(*)
                FROM order_items
                WHERE product_id = @productId
                """,
                new Dictionary<string, object>
                {
                    { "@productId", productId }
                });

            return Convert.ToInt32(result) > 0;
        }
    }
}

OrdersService.cs

using AppCore.Helpers;
using System.Data;

namespace Demo_Ex_8.Services
{
    public static class OrdersService
    {
        public static DataTable GetOrders()
        {
            string query = """
                SELECT
                    o.id,
                    o.order_date,
                    o.delivery_date,
                    o.pickup_point_id,
                    o.user_id,
                    o.receipt_code,
                    o.status_id,
                    s.status_name,
                    u.full_name,
                    CONCAT(
                        pp.postal_code,
                        ', г. ',
                        c.city_name,
                        ', ',
                        pp.street,
                        ', ',
                        pp.house
                    ) AS pickup_point
                FROM orders o
                JOIN statuses s ON s.id = o.status_id
                JOIN users u ON u.id = o.user_id
                JOIN pickup_points pp ON pp.id = o.pickup_point_id
                JOIN cities c ON c.id = pp.city_id
                ORDER BY o.id DESC
                """;

            return DatabaseService.ExecuteSelect(query);
        }

        public static DataTable GetOrderById(int orderId)
        {
            string query = """
                SELECT
                    id,
                    order_date,
                    delivery_date,
                    pickup_point_id,
                    user_id,
                    receipt_code,
                    status_id
                FROM orders
                WHERE id = @id
                """;

            return DatabaseService.ExecuteSelect(
                query,
                new Dictionary<string, object>
                {
                    { "@id", orderId }
                });
        }

        public static DataTable GetStatuses()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, status_name FROM statuses ORDER BY status_name");
        }

        public static DataTable GetUsers()
        {
            return DatabaseService.ExecuteSelect(
                "SELECT id, full_name FROM users ORDER BY full_name");
        }

        public static DataTable GetPickupPoints()
        {
            string query = """
                SELECT
                    pp.id,
                    CONCAT(
                        pp.postal_code,
                        ', г. ',
                        c.city_name,
                        ', ',
                        pp.street,
                        ', ',
                        pp.house
                    ) AS pickup_point
                FROM pickup_points pp
                JOIN cities c ON c.id = pp.city_id
                ORDER BY pp.id
                """;

            return DatabaseService.ExecuteSelect(query);
        }

        public static bool CreateOrder(
            DateTime orderDate,
            DateTime deliveryDate,
            int pickupPointId,
            int userId,
            string receiptCode,
            int statusId)
        {
            string query = """
                INSERT INTO orders
                (
                    order_date,
                    delivery_date,
                    pickup_point_id,
                    user_id,
                    receipt_code,
                    status_id
                )
                VALUES
                (
                    @orderDate,
                    @deliveryDate,
                    @pickupPointId,
                    @userId,
                    @receiptCode,
                    @statusId
                )
                """;

            return DatabaseService.ExecuteNonQuery(
                query,
                new Dictionary<string, object>
                {
                    { "@orderDate", orderDate },
                    { "@deliveryDate", deliveryDate },
                    { "@pickupPointId", pickupPointId },
                    { "@userId", userId },
                    { "@receiptCode", receiptCode },
                    { "@statusId", statusId }
                });
        }

        public static bool UpdateOrder(
            int id,
            DateTime orderDate,
            DateTime deliveryDate,
            int pickupPointId,
            int userId,
            string receiptCode,
            int statusId)
        {
            string query = """
                UPDATE orders
                SET
                    order_date = @orderDate,
                    delivery_date = @deliveryDate,
                    pickup_point_id = @pickupPointId,
                    user_id = @userId,
                    receipt_code = @receiptCode,
                    status_id = @statusId
                WHERE id = @id
                """;

            return DatabaseService.ExecuteNonQuery(
                query,
                new Dictionary<string, object>
                {
                    { "@id", id },
                    { "@orderDate", orderDate },
                    { "@deliveryDate", deliveryDate },
                    { "@pickupPointId", pickupPointId },
                    { "@userId", userId },
                    { "@receiptCode", receiptCode },
                    { "@statusId", statusId }
                });
        }

        public static bool DeleteOrder(int id)
        {
            string query = """
                DELETE FROM order_items WHERE order_id = @id;
                DELETE FROM orders WHERE id = @id;
                """;

            return DatabaseService.ExecuteNonQuery(
                query,
                new Dictionary<string, object>
                {
                    { "@id", id }
                });
        }
    }
}

ProductCard.cs

	public partial class ProductCard : UserControl
	{
			public int ProductId { get; private set; }

			private readonly int _discountLimit;
			private readonly Color _defaultColor;
			private readonly Color _discountColor;
			private readonly Color _outOfStockColor;

			public event EventHandler<int>? CardClicked;

			public ProductCard(
					DataRow row,
					int discountLimit,
					Color defaultColor,
					Color discountColor,
					Color outOfStockColor)
			{
					InitializeComponent();

					_discountLimit = discountLimit;
					_defaultColor = defaultColor;
					_discountColor = discountColor;
					_outOfStockColor = outOfStockColor;

					FillCard(row);
					AttachClickEvent(this);
			}

			private void ProductCard_Click(object? sender, EventArgs e)
			{
					CardClicked?.Invoke(this, ProductId);
			}

			public void FillCard(DataRow row)
			{
					try
					{
							ProductId = Convert.ToInt32(row["id"]);

							decimal price = Convert.ToDecimal(row["price"]);
							int discount = Convert.ToInt32(row["discount"]);
							int quantity = Convert.ToInt32(row["quantity"]);

							CategoryLabel.Text = row["category_name"].ToString();
							TitleLabel.Text = row["title"].ToString();
							DescriptionLabel.Text = row["description"].ToString();
							ManufacturerLabel.Text = row["manufacturer_name"].ToString();
							SupplierLabel.Text = row["supplier_name"].ToString();
							UnitLabel.Text = row["unit_name"].ToString();
							QuantityLabel.Text = quantity.ToString();
							DiscountLabel.Text = ProductViewHelper.FormatDiscount(discount);

							ProductPicture.Image = ImageHelper.LoadImageOrDefault(
									row["picture_path"].ToString(),
									@"C:Resourse\picture.png");

							ProductPicture.SizeMode = PictureBoxSizeMode.Zoom;

							ProductViewHelper.ApplyProductBackground(
									this,
									quantity,
									discount,
									_discountLimit,
									_defaultColor,
									_discountColor,
									_outOfStockColor);

							ProductViewHelper.ApplyPriceLabels(
									PriceLabel,
									FinalPriceLabel,
									price,
									discount,
									Color.Red,
									Color.Black);
					}
					catch (Exception ex)
					{
							MessageBoxHelper.ShowException(ex);
					}
			}

			private void AttachClickEvent(Control control)
			{
					control.Click -= ProductCard_Click;
					control.Click += ProductCard_Click;

					control.Cursor = Cursors.Hand;

					foreach (Control child in control.Controls)
					{
							AttachClickEvent(child);
					}
			}
	}


OrderCard.cs

	public partial class OrderCard : UserControl
	{
			public int OrderId { get; private set; }

			public event EventHandler<int>? CardClicked;

			public OrderCard(DataRow row)
			{
					InitializeComponent();

					FillCard(row);
					AttachClickEvent(this);
			}

			private void FillCard(DataRow row)
			{
					try
					{
							OrderId = Convert.ToInt32(row["id"]);

							string status = row["status_name"].ToString();
							string pickupPoint = row["pickup_point"].ToString();

							DateTime orderDate = Convert.ToDateTime(row["order_date"]);
							DateTime deliveryDate = Convert.ToDateTime(row["delivery_date"]);

							ArticleLabel.Text = "Артикул заказа: " + OrderId;
							StatusLabel.Text = "Статус заказа: " + status;
							PickupPointLabel.Text = "Адрес пункта выдачи: " + pickupPoint;
							OrderDateLabel.Text = "Дата заказа: " + orderDate.ToString("dd.MM.yyyy");
							DeliveryDateLabel.Text = "Дата доставки: " + deliveryDate.ToString("dd.MM.yyyy");
					}
					catch (Exception ex)
					{
							MessageBoxHelper.ShowException(ex);
					}
			}

			private void AttachClickEvent(Control control)
			{
					control.Click -= OrderCard_Click;
					control.Click += OrderCard_Click;

					control.Cursor = Cursors.Hand;

					foreach (Control child in control.Controls)
					{
							AttachClickEvent(child);
					}
			}

			private void OrderCard_Click(object? sender, EventArgs e)
			{
					CardClicked?.Invoke(this, OrderId);
			}
	}


CatalogForm.cs

	public partial class CatalogForm : Form
	{
			private bool _isLoading = false;

			public CatalogForm()
			{
					InitializeComponent();

					FormHelper.Configure(this, "Каталог", "C:Resourse\\icon.ico");

					LoadData();
			}

			private void LoadData()
			{
					_isLoading = true;

					LoadUserInfo();
					LoadSuppliers();
					LoadSortTypes();

					_isLoading = false;

					LoadProducts();
			}

			private void LoadUserInfo()
			{
					FullNameLabel.Text = UserSession.FullName;
					RoleLabel.Text = UserSession.Role;
			}

			private void LoadSuppliers()
			{
					ComboBoxHelper.LoadWithDefaultItem(
							SupplierComboBox,
							ProductsService.GetSuppliers(),
							"supplier_name",
							"id",
							"Все поставщики");
			}

			private void LoadSortTypes()
			{
					SortComboBox.Items.Clear();

					SortComboBox.Items.Add("По умолчанию");
					SortComboBox.Items.Add("Цена по возрастанию");
					SortComboBox.Items.Add("Цена по убыванию");
					SortComboBox.Items.Add("Количество по возрастанию");
					SortComboBox.Items.Add("Количество по убыванию");
					SortComboBox.Items.Add("Скидка по возрастанию");
					SortComboBox.Items.Add("Скидка по убыванию");
					SortComboBox.Items.Add("Название А-Я");
					SortComboBox.Items.Add("Название Я-А");

					SortComboBox.SelectedIndex = 0;
			}

			private void LoadProducts()
			{
					try
					{
							string search = SearchTextBox.Text.Trim();
							string sortType = SortComboBox.Text;

							int supplierId = 0;

							if (ComboBoxHelper.HasSelectedValue(SupplierComboBox))
							{
									supplierId = ComboBoxHelper.GetSelectedIntValue(SupplierComboBox);
							}

							DataTable table = ProductsService.GetProducts(
									search,
									supplierId,
									sortType);

							CardPanelHelper.Clear(ProductsPanel);

							foreach (DataRow row in table.Rows)
							{
									ProductCard card = new(
											row,
											17,
											Color.White,
											Color.FromArgb(255, 222, 173),
											Color.LightBlue);

									card.CardClicked += Product_Click;

									CardPanelHelper.AddCard(ProductsPanel, card);
							}

							if (!CardPanelHelper.HasCards(ProductsPanel))
							{
									CardPanelHelper.ShowEmptyMessage(
											ProductsPanel,
											"Товары не найдены");
							}
					}
					catch (Exception ex)
					{
							MessageBoxHelper.ShowException(ex);
					}
			}

			private void Product_Click(object? sender, int productId)
			{
					FormHelper.OpenSingleDialog(
							() => new ProductEditForm(productId),
							LoadProducts);
			}

			private void SearchTextBox_TextChanged(object sender, EventArgs e)
			{
					if (_isLoading)
							return;

					LoadProducts();
			}

			private void SupplierComboBox_SelectedIndexChanged(object sender, EventArgs e)
			{
					if (_isLoading)
							return;

					LoadProducts();
			}

			private void SortComboBox_SelectedIndexChanged(object sender, EventArgs e)
			{
					if (_isLoading)
							return;

					LoadProducts();
			}

			private void AddProductBtn_Click(object sender, EventArgs e)
			{
					FormHelper.OpenSingleDialog(
							() => new ProductEditForm(),
							LoadProducts);
			}

			private void OrdersBtn_Click(object sender, EventArgs e)
			{
					FormHelper.OpenSingleDialog(
							() => new OrderForm());
			}

			private void ExitBtn_Click(object sender, EventArgs e)
			{
					AuthService.Logout();
					Close();
			}
	}


CatalogForm.designer

	partial class CatalogForm
	{
			/// <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()
			{
					System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CatalogForm));
					RoleLabel = new Label();
					FullNameLabel = new Label();
					SortComboBox = new ComboBox();
					SupplierComboBox = new ComboBox();
					SearchTextBox = new TextBox();
					LogoutBtn = new Button();
					ProductsPanel = new FlowLayoutPanel();
					CreateProductBtn = new Button();
					pictureBox1 = new PictureBox();
					label2 = new Label();
					groupBox1 = new GroupBox();
					label3 = new Label();
					label1 = new Label();
					OrdersForm = new Button();
					((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
					groupBox1.SuspendLayout();
					SuspendLayout();
					//
					// RoleLabel
					//
					RoleLabel.AutoSize = true;
					RoleLabel.Location = new Point(1415, 35);
					RoleLabel.Margin = new Padding(4, 0, 4, 0);
					RoleLabel.Name = "RoleLabel";
					RoleLabel.Size = new Size(49, 21);
					RoleLabel.TabIndex = 1;
					RoleLabel.Text = "Гость";
					//
					// FullNameLabel
					//
					FullNameLabel.AutoSize = true;
					FullNameLabel.Location = new Point(1415, 9);
					FullNameLabel.Margin = new Padding(4, 0, 4, 0);
					FullNameLabel.Name = "FullNameLabel";
					FullNameLabel.Size = new Size(49, 21);
					FullNameLabel.TabIndex = 0;
					FullNameLabel.Text = "Гость";
					//
					// SortComboBox
					//
					SortComboBox.FormattingEnabled = true;
					SortComboBox.Location = new Point(7, 50);
					SortComboBox.Margin = new Padding(4);
					SortComboBox.Name = "SortComboBox";
					SortComboBox.Size = new Size(275, 29);
					SortComboBox.TabIndex = 2;
					SortComboBox.SelectedIndexChanged += SortComboBox_SelectedIndexChanged;
					//
					// SupplierComboBox
					//
					SupplierComboBox.FormattingEnabled = true;
					SupplierComboBox.Location = new Point(7, 123);
					SupplierComboBox.Margin = new Padding(4);
					SupplierComboBox.Name = "SupplierComboBox";
					SupplierComboBox.Size = new Size(275, 29);
					SupplierComboBox.TabIndex = 1;
					SupplierComboBox.SelectedIndexChanged += SupplierComboBox_SelectedIndexChanged;
					//
					// SearchTextBox
					//
					SearchTextBox.Location = new Point(645, 21);
					SearchTextBox.Margin = new Padding(4);
					SearchTextBox.Name = "SearchTextBox";
					SearchTextBox.PlaceholderText = "Поиск товаров по названию, поставщику, ";
					SearchTextBox.Size = new Size(709, 29);
					SearchTextBox.TabIndex = 0;
					SearchTextBox.TextChanged += SearchTextBox_TextChanged;
					//
					// LogoutBtn
					//
					LogoutBtn.Location = new Point(1697, 13);
					LogoutBtn.Margin = new Padding(4);
					LogoutBtn.Name = "LogoutBtn";
					LogoutBtn.Size = new Size(96, 43);
					LogoutBtn.TabIndex = 3;
					LogoutBtn.Text = "Выход";
					LogoutBtn.UseVisualStyleBackColor = true;
					LogoutBtn.Click += ExitBtn_Click;
					//
					// ProductsPanel
					//
					ProductsPanel.AutoScroll = true;
					ProductsPanel.Location = new Point(311, 115);
					ProductsPanel.Margin = new Padding(4);
					ProductsPanel.Name = "ProductsPanel";
					ProductsPanel.Size = new Size(1491, 881);
					ProductsPanel.TabIndex = 4;
					//
					// CreateProductBtn
					//
					CreateProductBtn.Location = new Point(7, 218);
					CreateProductBtn.Margin = new Padding(4);
					CreateProductBtn.Name = "CreateProductBtn";
					CreateProductBtn.Size = new Size(275, 41);
					CreateProductBtn.TabIndex = 5;
					CreateProductBtn.Text = "Добавить товар";
					CreateProductBtn.UseVisualStyleBackColor = true;
					CreateProductBtn.Click += AddProductBtn_Click;
					//
					// pictureBox1
					//
					pictureBox1.Image = (Image)resources.GetObject("pictureBox1.Image");
					pictureBox1.Location = new Point(13, 9);
					pictureBox1.Margin = new Padding(4);
					pictureBox1.Name = "pictureBox1";
					pictureBox1.Size = new Size(102, 99);
					pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
					pictureBox1.TabIndex = 6;
					pictureBox1.TabStop = false;
					//
					// label2
					//
					label2.AutoSize = true;
					label2.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point, 204);
					label2.Location = new Point(123, 9);
					label2.Margin = new Padding(4, 0, 4, 0);
					label2.Name = "label2";
					label2.Size = new Size(171, 30);
					label2.TabIndex = 7;
					label2.Text = "Каталог товаров";
					//
					// groupBox1
					//
					groupBox1.Controls.Add(label3);
					groupBox1.Controls.Add(label1);
					groupBox1.Controls.Add(SortComboBox);
					groupBox1.Controls.Add(SupplierComboBox);
					groupBox1.Controls.Add(CreateProductBtn);
					groupBox1.Location = new Point(12, 115);
					groupBox1.Name = "groupBox1";
					groupBox1.Size = new Size(292, 268);
					groupBox1.TabIndex = 8;
					groupBox1.TabStop = false;
					//
					// label3
					//
					label3.AutoSize = true;
					label3.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
					label3.Location = new Point(7, 98);
					label3.Margin = new Padding(4, 0, 4, 0);
					label3.Name = "label3";
					label3.Size = new Size(90, 21);
					label3.TabIndex = 10;
					label3.Text = "Поставщик";
					//
					// label1
					//
					label1.AutoSize = true;
					label1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
					label1.Location = new Point(7, 25);
					label1.Margin = new Padding(4, 0, 4, 0);
					label1.Name = "label1";
					label1.Size = new Size(96, 21);
					label1.TabIndex = 9;
					label1.Text = "Сортировка";
					//
					// OrdersForm
					//
					OrdersForm.Location = new Point(12, 956);
					OrdersForm.Margin = new Padding(4);
					OrdersForm.Name = "OrdersForm";
					OrdersForm.Size = new Size(184, 33);
					OrdersForm.TabIndex = 11;
					OrdersForm.Text = "Форма с заказами";
					OrdersForm.UseVisualStyleBackColor = true;
					OrdersForm.Click += OrdersBtn_Click;
					//
					// CatalogForm
					//
					AutoScaleDimensions = new SizeF(9F, 21F);
					AutoScaleMode = AutoScaleMode.Font;
					ClientSize = new Size(1815, 1002);
					Controls.Add(OrdersForm);
					Controls.Add(groupBox1);
					Controls.Add(label2);
					Controls.Add(RoleLabel);
					Controls.Add(FullNameLabel);
					Controls.Add(pictureBox1);
					Controls.Add(ProductsPanel);
					Controls.Add(SearchTextBox);
					Controls.Add(LogoutBtn);
					Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
					Icon = (Icon)resources.GetObject("$this.Icon");
					Margin = new Padding(4);
					Name = "CatalogForm";
					Text = "CatalogForm";
					((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
					groupBox1.ResumeLayout(false);
					groupBox1.PerformLayout();
					ResumeLayout(false);
					PerformLayout();
			}

			#endregion
			private Label RoleLabel;
			private Label FullNameLabel;
			private TextBox SearchTextBox;
			private Button LogoutBtn;
			private ComboBox SupplierComboBox;
			private ComboBox SortComboBox;
			private FlowLayoutPanel ProductsPanel;
			private Button CreateProductBtn;
			private PictureBox pictureBox1;
			private Label label2;
			private GroupBox groupBox1;
			private Label label3;
			private Label label1;
			private Button OrdersForm;
	}

LoginForm.cs

public partial class Login : Form
{
    public Login()
    {
        InitializeComponent();
        FormHelper.Configure(this, "Форма входа", "C:Resourse\\icon.ico");
    }

    private void loginBtn_Click(object sender, EventArgs e)
    {
        bool isLoginSuccess = AuthService.Login(LoginTextBox.Text, PasswordTextBox.Text);

        if (!isLoginSuccess)
        {
            return;
        }

        OpenCatalogForm();
    }

    private void loginAsGuestBtn_Click(object sender, EventArgs e)
    {
        AuthService.LoginAsGuest();

        OpenCatalogForm();
    }

    public void OpenCatalogForm()
    {
        FormHelper.HideCurrentAndOpen(this, new CatalogForm());
    }
}

ProductEditForm.cs

using AppCore.Helpers;
using Demo_Ex_8.Services;
using System.Data;

namespace Demo_Ex_8.Forms
{

    public partial class ProductEditForm : Form
    {
        private readonly int? _productId;

        private string _picturePath = string.Empty;

        private const string DefaultPicturePath =
            @"C:Resourse\picture.png";

        private const string IconPath =
            @"C:Resourse\icon.ico";

        public bool IsSaved { get; private set; }

        public ProductEditForm()
        {
            FormHelper.Configure(this, "Создание товара", IconPath);
            InitializeComponent();


            ConfigureCreateMode();
        }

        public ProductEditForm(int productId)
        {
            InitializeComponent();

            _productId = productId;

            FormHelper.Configure(this, "Редактирование товара", IconPath);

            ConfigureEditMode();
        }

        private void ProductEditForm_Load(object sender, EventArgs e)
        {
            LoadComboBoxes();

            if (_productId.HasValue)
            {
                LoadProductData(_productId.Value);
            }
            else
            {
                ProductPictureBox.Image = ImageHelper.LoadImageOrDefault(
                    string.Empty,
                    DefaultPicturePath);
            }
        }

        private void ConfigureCreateMode()
        {
            CreateBtn.Visible = true;
            SaveBtn.Visible = false;
            DeleteBtn.Visible = false;
        }

        private void ConfigureEditMode()
        {
            CreateBtn.Visible = false;
            SaveBtn.Visible = true;
            DeleteBtn.Visible = true;
        }

        private void LoadComboBoxes()
        {
            ComboBoxHelper.Load(
                UnitComboBox,
                ProductsService.GetUnits(),
                "unit_name",
                "id");

            ComboBoxHelper.Load(
                SupplierComboBox,
                ProductsService.GetSuppliers(),
                "supplier_name",
                "id");

            ComboBoxHelper.Load(
                ManufacturerComboBox,
                ProductsService.GetManufacturers(),
                "manufacturer_name",
                "id");

            ComboBoxHelper.Load(
                CategoryComboBox,
                ProductsService.GetCategories(),
                "category_name",
                "id");
        }

        private void LoadProductData(int productId)
        {
            DataTable table = ProductsService.GetProductById(productId);

            if (table.Rows.Count == 0)
            {
                MessageBoxHelper.Warning("Товар не найден");
                Close();
                return;
            }

            DataRow row = table.Rows[0];

            ArticleTextBox.Text = row["article"].ToString();
            TitleTextBox.Text = row["title"].ToString();
            PriceTextBox.Text = row["price"].ToString();
            QuantityTextBox.Text = row["quantity"].ToString();
            DiscountTextBox.Text = row["discount"].ToString();
            DescriptionTextBox.Text = row["description"].ToString();

            UnitComboBox.SelectedValue = Convert.ToInt32(row["unit_id"]);
            SupplierComboBox.SelectedValue = Convert.ToInt32(row["supplier_id"]);
            ManufacturerComboBox.SelectedValue = Convert.ToInt32(row["manufacturer_id"]);
            CategoryComboBox.SelectedValue = Convert.ToInt32(row["category_id"]);

            _picturePath = row["picture_path"].ToString();

            ProductPictureBox.Image = ImageHelper.LoadImageOrDefault(
                _picturePath,
                DefaultPicturePath);
        }

        private bool ValidateForm(
            out decimal price,
            out int quantity,
            out int discount)
        {
            price = 0;
            quantity = 0;
            discount = 0;

            if (!ValidationHelper.ValidateRequiredFields(new()
            {
                { "Артикул", ArticleTextBox.Text },
                { "Название", TitleTextBox.Text },
                { "Цена", PriceTextBox.Text },
                { "Количество на складе", QuantityTextBox.Text },
                { "Скидка", DiscountTextBox.Text },
                { "Описание", DescriptionTextBox.Text }
            }))
            {
                return false;
            }

            if (!ValidationHelper.TryGetDecimal(PriceTextBox.Text, "Цена", out price))
            {
                return false;
            }

            if (price < 0)
            {
                MessageBoxHelper.Warning("Цена не может быть меньше нуля");
                return false;
            }

            if (!ValidationHelper.TryGetInt(QuantityTextBox.Text, "Количество на складе", out quantity))
            {
                return false;
            }

            if (quantity < 0)
            {
                MessageBoxHelper.Warning("Количество на складе не может быть меньше нуля");
                return false;
            }

            if (!ValidationHelper.TryGetInt(DiscountTextBox.Text, "Скидка", out discount))
            {
                return false;
            }

            if (discount < 0 || discount > 100)
            {
                MessageBoxHelper.Warning("Скидка должна быть от 0 до 100");
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(UnitComboBox, "Единица измерения"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(SupplierComboBox, "Поставщик"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(ManufacturerComboBox, "Производитель"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(CategoryComboBox, "Категория"))
            {
                return false;
            }

            return true;
        }

        private void CreateBtn_Click(object sender, EventArgs e)
        {
            if (!ValidateForm(out decimal price, out int quantity, out int discount))
            {
                return;
            }

            bool result = ProductsService.CreateProduct(
                ArticleTextBox.Text.Trim(),
                TitleTextBox.Text.Trim(),
                ComboBoxHelper.GetSelectedIntValue(UnitComboBox),
                price,
                ComboBoxHelper.GetSelectedIntValue(SupplierComboBox),
                ComboBoxHelper.GetSelectedIntValue(ManufacturerComboBox),
                ComboBoxHelper.GetSelectedIntValue(CategoryComboBox),
                discount,
                quantity,
                DescriptionTextBox.Text.Trim(),
                _picturePath);

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Товар успешно создан");
                Close();
            }
        }

        private void SaveBtn_Click(object sender, EventArgs e)
        {
            if (!_productId.HasValue)
            {
                MessageBoxHelper.Warning("Не выбран товар для редактирования");
                return;
            }

            if (!ValidateForm(out decimal price, out int quantity, out int discount))
            {
                return;
            }

            bool result = ProductsService.UpdateProduct(
                _productId.Value,
                ArticleTextBox.Text.Trim(),
                TitleTextBox.Text.Trim(),
                ComboBoxHelper.GetSelectedIntValue(UnitComboBox),
                price,
                ComboBoxHelper.GetSelectedIntValue(SupplierComboBox),
                ComboBoxHelper.GetSelectedIntValue(ManufacturerComboBox),
                ComboBoxHelper.GetSelectedIntValue(CategoryComboBox),
                discount,
                quantity,
                DescriptionTextBox.Text.Trim(),
                _picturePath);

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Товар успешно сохранён");
                Close();
            }
        }

        private void DeleteBtn_Click(object sender, EventArgs e)
        {
            if (!_productId.HasValue)
            {
                MessageBoxHelper.Warning("Не выбран товар для удаления");
                return;
            }

            if (!MessageBoxHelper.Confirm("Удалить выбранный товар?"))
            {
                return;
            }

            if (ProductsService.ProductExistsInOrders(_productId.Value))
            {
                MessageBoxHelper.Warning("Нельзя удалить товар, который присутствует в заказе");
                return;
            }

            bool result = ProductsService.DeleteProduct(_productId.Value);

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Товар успешно удалён");
                Close();
            }
        }

        private void ProductPictureBox_Click(object sender, EventArgs e)
        {
            string selectedPath = ImageHelper.SelectImageFile();

            if (string.IsNullOrWhiteSpace(selectedPath))
            {
                return;
            }

            _picturePath = selectedPath;

            ProductPictureBox.Image = ImageHelper.LoadImageOrDefault(
                _picturePath,
                DefaultPicturePath);

            ProductPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
        }
    }
}

OrdersForm.cs

using AppCore.Helpers;
using Demo_Ex_8.Cards;
using Demo_Ex_8.Services;
using System.Data;

namespace Demo_Ex_8.Forms
{
    public partial class OrderForm : Form
    {
        private const string IconPath =
            @"C:Resourse\icon.ico";

        public OrderForm()
        {
            InitializeComponent();

            FormHelper.Configure(this, "Заказы", IconPath);

            LoadOrders();
        }

        private void LoadOrders()
        {
            DataTable table = OrdersService.GetOrders();

            CardPanelHelper.Clear(OrdersPanel);

            foreach (DataRow row in table.Rows)
            {
                OrderCard card = new(row);

                card.Width = OrdersPanel.Width - 25;
                card.CardClicked += OrderCard_Click;

                CardPanelHelper.AddCard(OrdersPanel, card);
            }

            if (!CardPanelHelper.HasCards(OrdersPanel))
            {
                CardPanelHelper.ShowEmptyMessage(
                    OrdersPanel,
                    "Заказы не найдены");
            }
        }

        private void OrderCard_Click(object? sender, int orderId)
        {
            FormHelper.OpenSingleDialog(
                () => new OrderEditForm(orderId),
                LoadOrders);
        }

        private void AddOrderBtn_Click(object sender, EventArgs e)
        {
            FormHelper.OpenSingleDialog(
                () => new OrderEditForm(),
                LoadOrders);
        }
    }
}

OrderEditForm.cs

using AppCore.Helpers;
using Demo_Ex_8.Services;
using System.Data;

namespace Demo_Ex_8.Forms
{
    public partial class OrderEditForm : Form
    {
        private readonly int? _orderId;

        private const string IconPath =
            @"C:Resourse\icon.ico";

        public bool IsSaved { get; private set; }

        public OrderEditForm()
        {
            InitializeComponent();

            FormHelper.Configure(this, "Создание заказа", IconPath);

            ConfigureCreateMode();
            LoadComboBoxes();
        }

        public OrderEditForm(int orderId)
        {
            InitializeComponent();

            _orderId = orderId;

            FormHelper.Configure(this, "Редактирование заказа", IconPath);

            ConfigureEditMode();
            LoadComboBoxes();
            LoadOrderData(orderId);
        }

        private void ConfigureCreateMode()
        {
            OrderNumber.Text = "Новый";

            CreateBtn.Visible = true;
            SaveBtn.Visible = false;
            DeleteBtn.Visible = false;

            OrderDate.Value = DateTime.Today;
            DeliveryDate.Value = DateTime.Today;
        }

        private void ConfigureEditMode()
        {
            CreateBtn.Visible = false;
            SaveBtn.Visible = true;
            DeleteBtn.Visible = true;
        }

        private void LoadComboBoxes()
        {
            ComboBoxHelper.Load(
                StatusComboBox,
                OrdersService.GetStatuses(),
                "status_name",
                "id");

            ComboBoxHelper.Load(
                PickupPointAddressComboBox,
                OrdersService.GetPickupPoints(),
                "pickup_point",
                "id");

            ComboBoxHelper.Load(
                UserComboBox,
                OrdersService.GetUsers(),
                "full_name",
                "id");
        }

        private void LoadOrderData(int orderId)
        {
            DataTable table = OrdersService.GetOrderById(orderId);

            if (table.Rows.Count == 0)
            {
                MessageBoxHelper.Warning("Заказ не найден");
                Close();
                return;
            }

            DataRow row = table.Rows[0];

            OrderNumber.Text = row["id"].ToString();

            OrderDate.Value = Convert.ToDateTime(row["order_date"]);
            DeliveryDate.Value = Convert.ToDateTime(row["delivery_date"]);

            ReceiptCode.Text = row["receipt_code"].ToString();

            PickupPointAddressComboBox.SelectedValue = Convert.ToInt32(row["pickup_point_id"]);
            UserComboBox.SelectedValue = Convert.ToInt32(row["user_id"]);
            StatusComboBox.SelectedValue = Convert.ToInt32(row["status_id"]);
        }

        private bool ValidateForm()
        {
            if (!ValidationHelper.ValidateRequiredField(ReceiptCode.Text, "Код получения"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(StatusComboBox, "Статус заказа"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(PickupPointAddressComboBox, "Адрес пункта выдачи"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateComboBoxSelected(UserComboBox, "Пользователь"))
            {
                return false;
            }

            if (!ValidationHelper.ValidateDateRange(
                OrderDate.Value.Date,
                DeliveryDate.Value.Date))
            {
                return false;
            }

            return true;
        }

        private void CreateBtn_Click(object sender, EventArgs e)
        {
            if (!ValidateForm())
            {
                return;
            }

            bool result = OrdersService.CreateOrder(
                OrderDate.Value.Date,
                DeliveryDate.Value.Date,
                ComboBoxHelper.GetSelectedIntValue(PickupPointAddressComboBox),
                ComboBoxHelper.GetSelectedIntValue(UserComboBox),
                ReceiptCode.Text.Trim(),
                ComboBoxHelper.GetSelectedIntValue(StatusComboBox));

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Заказ успешно создан");
                Close();
            }
        }

        private void SaveBtn_Click(object sender, EventArgs e)
        {
            if (!_orderId.HasValue)
            {
                MessageBoxHelper.Warning("Не выбран заказ для редактирования");
                return;
            }

            if (!ValidateForm())
            {
                return;
            }

            bool result = OrdersService.UpdateOrder(
                _orderId.Value,
                OrderDate.Value.Date,
                DeliveryDate.Value.Date,
                ComboBoxHelper.GetSelectedIntValue(PickupPointAddressComboBox),
                ComboBoxHelper.GetSelectedIntValue(UserComboBox),
                ReceiptCode.Text.Trim(),
                ComboBoxHelper.GetSelectedIntValue(StatusComboBox));

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Заказ успешно сохранён");
                Close();
            }
        }

        private void DeleteBtn_Click(object sender, EventArgs e)
        {
            if (!_orderId.HasValue)
            {
                MessageBoxHelper.Warning("Не выбран заказ для удаления");
                return;
            }

            if (!MessageBoxHelper.Confirm("Удалить выбранный заказ?"))
            {
                return;
            }

            bool result = OrdersService.DeleteOrder(_orderId.Value);

            if (result)
            {
                IsSaved = true;
                MessageBoxHelper.Info("Заказ успешно удалён");
                Close();
            }
        }
    }
}
Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.13 130 6/14/2026
1.0.12 106 6/14/2026
1.0.11 110 6/13/2026
1.0.10 111 6/13/2026
1.0.9 105 6/13/2026
1.0.8 114 6/13/2026
1.0.7 117 6/12/2026
1.0.6 109 6/10/2026
1.0.5 107 6/8/2026
1.0.4 114 6/7/2026
1.0.3 110 6/6/2026
1.0.2 110 6/6/2026
1.0.1 113 6/4/2026