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); } } }