Загрузка данных


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using VasilisaSalon.Models;

namespace VasilisaSalon
{
    public partial class Form1 : Form
    {
        // ===== КЛИЕНТЫ =====
        private List<ClientDisplayItem> displayClients = new List<ClientDisplayItem>();
        private List<ClientDisplayItem> newClients = new List<ClientDisplayItem>();
        private List<ClientDisplayItem> changedClients = new List<ClientDisplayItem>();
        private List<ClientDisplayItem> deletedClients = new List<ClientDisplayItem>();

        private class ClientDisplayItem
        {
            public int ClientId { get; set; }
            public string FullName { get; set; }
            public string Phone { get; set; }
            public string Email { get; set; }
        }

        // ===== ПЕРСОНАЛ =====
        private List<EmployeeDisplayItem> displayEmployees = new List<EmployeeDisplayItem>();
        private List<EmployeeDisplayItem> newEmployees = new List<EmployeeDisplayItem>();
        private List<EmployeeDisplayItem> changedEmployees = new List<EmployeeDisplayItem>();
        private List<EmployeeDisplayItem> deletedEmployees = new List<EmployeeDisplayItem>();

        private class EmployeeDisplayItem
        {
            public int EmployeeId { get; set; }
            public string FullName { get; set; }
            public string Phone { get; set; }
            public string Email { get; set; }
            public string PositionName { get; set; }
            public int PositionId { get; set; }
        }

        // ===== РАСХОДНИКИ =====
        private List<MaterialDisplayItem> displayMaterials = new List<MaterialDisplayItem>();
        private List<MaterialDisplayItem> newMaterials = new List<MaterialDisplayItem>();
        private List<MaterialDisplayItem> changedMaterials = new List<MaterialDisplayItem>();
        private List<MaterialDisplayItem> deletedMaterials = new List<MaterialDisplayItem>();

        private class MaterialDisplayItem
        {
            public int MaterialId { get; set; }
            public string MaterialName { get; set; }
            public string UnitName { get; set; }
            public int UnitId { get; set; }
            public int StockQty { get; set; }
            public int MinStockQty { get; set; }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            LoadClientsData();
            LoadEmployeesData();
            LoadMaterialsData();
            InitializeContextMenus();
            dataGridViewClients.CellValueChanged += dataGridViewClients_CellValueChanged;
            dataGridViewEmployees.CellValueChanged += dataGridViewEmployees_CellValueChanged;
            dataGridViewMaterials.CellValueChanged += dataGridViewMaterials_CellValueChanged;

            cmbSort.Items.AddRange(new[] { "По ФИО", "По телефону" });
            cmbSort.SelectedIndex = 0;
            txtSearch.TextChanged += cmbSort_SelectedIndexChanged;
            cmbSort.SelectedIndexChanged += cmbSort_SelectedIndexChanged;
        }

        // ============================================================
        // КЛИЕНТЫ
        // ============================================================

        private void LoadClientsData()
        {
            try
            {
                using (var db = new VasilisaSalonEntities())
                {
                    displayClients = db.client
                        .Select(c => new ClientDisplayItem
                        {
                            ClientId = c.client_id,
                            FullName = c.full_name,
                            Phone = c.phone,
                            Email = c.email ?? ""
                        }).ToList();
                }
                dataGridViewClients.DataSource = displayClients;
                FormatClientsGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка загрузки клиентов: " + ex.Message);
            }
        }

        private void FormatClientsGrid()
        {
            dataGridViewClients.ReadOnly = false;
            dataGridViewClients.AutoGenerateColumns = false;
            dataGridViewClients.Columns.Clear();

            dataGridViewClients.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "ClientId", HeaderText = "ID", ReadOnly = true, Width = 40 });
            dataGridViewClients.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "FullName", HeaderText = "ФИО", Width = 200 });
            dataGridViewClients.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "Phone", HeaderText = "Телефон", Width = 130 });
            dataGridViewClients.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "Email", HeaderText = "Email", Width = 160 });
        }

        private void AddClient()
        {
            var item = new ClientDisplayItem
            { ClientId = -1, FullName = "Новый клиент", Phone = "+7", Email = "" };
            newClients.Add(item);
            displayClients.Add(item);
            dataGridViewClients.DataSource = displayClients;
            FormatClientsGrid();
            ShowSaveButtons();
        }

        private void DeleteClient()
        {
            var rows = dataGridViewClients.SelectedRows;
            if (rows.Count > 0)
            {
                foreach (DataGridViewRow row in rows)
                {
                    var item = displayClients[row.Index];
                    if (!newClients.Contains(item))
                        deletedClients.Add(item);
                    displayClients.Remove(item);
                    newClients.Remove(item);
                    changedClients.Remove(item);
                }
                dataGridViewClients.DataSource = displayClients;
                FormatClientsGrid();
                ShowSaveButtons();
            }
            else
                MessageBox.Show("Выберите строку", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void dataGridViewClients_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                var item = displayClients[e.RowIndex];
                if (!newClients.Contains(item) && !changedClients.Contains(item))
                    changedClients.Add(item);
                var value = dataGridViewClients.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString();
                switch (e.ColumnIndex)
                {
                    case 1: item.FullName = value; break;
                    case 2: item.Phone = value; break;
                    case 3: item.Email = value; break;
                }
                ShowSaveButtons();
            }
        }

        private void SaveClients()
        {
            using (var db = new VasilisaSalonEntities())
            {
                // сохраняем изменения существующих
                foreach (var item in changedClients)
                {
                    var dbItem = db.client.Find(item.ClientId);
                    if (dbItem != null)
                    {
                        dbItem.full_name = item.FullName;
                        dbItem.phone = item.Phone;
                        dbItem.email = item.Email;
                    }
                }

                // удаляем
                foreach (var item in deletedClients)
                {
                    var dbItem = db.client.Find(item.ClientId);
                    if (dbItem != null) db.client.Remove(dbItem);
                }

                // добавляем новых — Find не нужен, просто Add
                foreach (var item in newClients)
                {
                    db.client.Add(new client
                    {
                        full_name = item.FullName,
                        phone = item.Phone,
                        email = item.Email,
                        reg_date = DateTime.Now,
                        pd_consent = true
                    });
                }

                db.SaveChanges();
            }

            newClients.Clear();
            changedClients.Clear();
            deletedClients.Clear();
            LoadClientsData();
        }

        // ============================================================
        // ПЕРСОНАЛ
        // ============================================================

        private void LoadEmployeesData()
        {
            try
            {
                using (var db = new VasilisaSalonEntities())
                {
                    displayEmployees = db.employee
                        .Select(e => new EmployeeDisplayItem
                        {
                            EmployeeId = e.employee_id,
                            FullName = e.full_name,
                            Phone = e.phone,
                            Email = e.email ?? "",
                            PositionName = e.position_ref.position_name,
                            PositionId = e.position_id
                        }).ToList();
                }
                dataGridViewEmployees.DataSource = displayEmployees;
                FormatEmployeesGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка загрузки персонала: " + ex.Message);
            }
        }

        private void FormatEmployeesGrid()
        {
            dataGridViewEmployees.ReadOnly = false;
            dataGridViewEmployees.AutoGenerateColumns = false;
            dataGridViewEmployees.Columns.Clear();

            dataGridViewEmployees.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "EmployeeId", HeaderText = "ID", ReadOnly = true, Width = 40 });
            dataGridViewEmployees.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "FullName", HeaderText = "ФИО", Width = 200 });
            dataGridViewEmployees.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "Phone", HeaderText = "Телефон", Width = 130 });
            dataGridViewEmployees.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "Email", HeaderText = "Email", Width = 160 });
            dataGridViewEmployees.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "PositionName", HeaderText = "Должность", ReadOnly = true, Width = 130 });
        }

        private void AddEmployee()
        {
            var item = new EmployeeDisplayItem
            { EmployeeId = -1, FullName = "Новый сотрудник", Phone = "+7", Email = "", PositionName = "", PositionId = 1 };
            newEmployees.Add(item);
            displayEmployees.Add(item);
            dataGridViewEmployees.DataSource = displayEmployees;
            FormatEmployeesGrid();
            ShowSaveButtons();
        }

        private void DeleteEmployee()
        {
            var rows = dataGridViewEmployees.SelectedRows;
            if (rows.Count > 0)
            {
                foreach (DataGridViewRow row in rows)
                {
                    var item = displayEmployees[row.Index];
                    if (!newEmployees.Contains(item))
                        deletedEmployees.Add(item);
                    displayEmployees.Remove(item);
                    newEmployees.Remove(item);
                    changedEmployees.Remove(item);
                }
                dataGridViewEmployees.DataSource = displayEmployees;
                FormatEmployeesGrid();
                ShowSaveButtons();
            }
            else
                MessageBox.Show("Выберите строку", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void dataGridViewEmployees_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                var item = displayEmployees[e.RowIndex];
                if (!newEmployees.Contains(item) && !changedEmployees.Contains(item))
                    changedEmployees.Add(item);
                var value = dataGridViewEmployees.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString();
                switch (e.ColumnIndex)
                {
                    case 1: item.FullName = value; break;
                    case 2: item.Phone = value; break;
                    case 3: item.Email = value; break;
                }
                ShowSaveButtons();
            }
        }

        private void SaveEmployees()
        {
            using (var db = new VasilisaSalonEntities())
            {
                foreach (var item in changedEmployees)
                {
                    var dbItem = db.employee.Find(item.EmployeeId);
                    if (dbItem != null)
                    {
                        dbItem.full_name = item.FullName;
                        dbItem.phone = item.Phone;
                        dbItem.email = item.Email;
                    }
                }
                foreach (var item in deletedEmployees)
                {
                    var dbItem = db.employee.Find(item.EmployeeId);
                    if (dbItem != null) db.employee.Remove(dbItem);
                }
                foreach (var item in newEmployees)
                {
                    db.employee.Add(new employee
                    {
                        full_name = item.FullName,
                        phone = item.Phone,
                        email = item.Email,
                        position_id = item.PositionId,
                        hire_date = DateTime.Now,
                        is_active = true
                    });
                }
                db.SaveChanges();
            }
            newEmployees.Clear(); changedEmployees.Clear(); deletedEmployees.Clear();
            LoadEmployeesData();
        }

        // ============================================================
        // РАСХОДНИКИ
        // ============================================================

        private void LoadMaterialsData()
        {
            try
            {
                using (var db = new VasilisaSalonEntities())
                {
                    displayMaterials = db.material
                        .Select(m => new MaterialDisplayItem
                        {
                            MaterialId = m.material_id,
                            MaterialName = m.material_name,
                            UnitName = m.unit_ref.unit_name,
                            UnitId = m.unit_id,
                            StockQty = m.stock_qty,
                            MinStockQty = m.min_stock_qty
                        }).ToList();
                }
                dataGridViewMaterials.DataSource = displayMaterials;
                FormatMaterialsGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка загрузки расходников: " + ex.Message);
            }
        }

        private void FormatMaterialsGrid()
        {
            dataGridViewMaterials.ReadOnly = false;
            dataGridViewMaterials.AutoGenerateColumns = false;
            dataGridViewMaterials.Columns.Clear();

            dataGridViewMaterials.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "MaterialId", HeaderText = "ID", ReadOnly = true, Width = 40 });
            dataGridViewMaterials.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "MaterialName", HeaderText = "Название", Width = 200 });
            dataGridViewMaterials.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "UnitName", HeaderText = "Единица", ReadOnly = true, Width = 80 });
            dataGridViewMaterials.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "StockQty", HeaderText = "Остаток", Width = 80 });
            dataGridViewMaterials.Columns.Add(new DataGridViewTextBoxColumn
            { DataPropertyName = "MinStockQty", HeaderText = "Минимум", Width = 80 });
        }

        private void AddMaterial()
        {
            var item = new MaterialDisplayItem
            { MaterialId = -1, MaterialName = "Новый материал", UnitName = "шт", UnitId = 3, StockQty = 0, MinStockQty = 0 };
            newMaterials.Add(item);
            displayMaterials.Add(item);
            dataGridViewMaterials.DataSource = displayMaterials;
            FormatMaterialsGrid();
            ShowSaveButtons();
        }

        private void DeleteMaterial()
        {
            var rows = dataGridViewMaterials.SelectedRows;
            if (rows.Count > 0)
            {
                foreach (DataGridViewRow row in rows)
                {
                    var item = displayMaterials[row.Index];
                    if (!newMaterials.Contains(item))
                        deletedMaterials.Add(item);
                    displayMaterials.Remove(item);
                    newMaterials.Remove(item);
                    changedMaterials.Remove(item);
                }
                dataGridViewMaterials.DataSource = displayMaterials;
                FormatMaterialsGrid();
                ShowSaveButtons();
            }
            else
                MessageBox.Show("Выберите строку", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void dataGridViewMaterials_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                var item = displayMaterials[e.RowIndex];
                if (!newMaterials.Contains(item) && !changedMaterials.Contains(item))
                    changedMaterials.Add(item);
                var value = dataGridViewMaterials.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString();
                switch (e.ColumnIndex)
                {
                    case 1: item.MaterialName = value; break;
                    case 3: item.StockQty = int.TryParse(value, out int qty) ? qty : 0; break;
                    case 4: item.MinStockQty = int.TryParse(value, out int min) ? min : 0; break;
                }
                ShowSaveButtons();
            }
        }

        private void SaveMaterials()
        {
            using (var db = new VasilisaSalonEntities())
            {
                foreach (var item in changedMaterials)
                {
                    var dbItem = db.material.Find(item.MaterialId);
                    if (dbItem != null)
                    {
                        dbItem.material_name = item.MaterialName;
                        dbItem.stock_qty = item.StockQty;
                        dbItem.min_stock_qty = item.MinStockQty;
                    }
                }
                foreach (var item in deletedMaterials)
                {
                    var dbItem = db.material.Find(item.MaterialId);
                    if (dbItem != null) db.material.Remove(dbItem);
                }
                foreach (var item in newMaterials)
                {
                    db.material.Add(new material
                    {
                        material_name = item.MaterialName,
                        unit_id = item.UnitId,
                        stock_qty = item.StockQty,
                        min_stock_qty = item.MinStockQty
                    });
                }
                db.SaveChanges();
            }
            newMaterials.Clear(); changedMaterials.Clear(); deletedMaterials.Clear();
            LoadMaterialsData();
        }

        // ============================================================
        // КОНТЕКСТНЫЕ МЕНЮ
        // ============================================================

        private void InitializeContextMenus()
        {
            // меню для клиентов
            var addClient = new ToolStripMenuItem("Добавить");
            var delClient = new ToolStripMenuItem("Удалить");
            contextMenuStrip1.Items.AddRange(new[] { addClient, delClient });
            dataGridViewClients.ContextMenuStrip = contextMenuStrip1;
            addClient.Click += (s, e) => AddClient();
            delClient.Click += (s, e) => DeleteClient();

            // меню для персонала
            var addEmp = new ToolStripMenuItem("Добавить");
            var delEmp = new ToolStripMenuItem("Удалить");
            contextMenuStrip2.Items.AddRange(new[] { addEmp, delEmp });
            dataGridViewEmployees.ContextMenuStrip = contextMenuStrip2;
            addEmp.Click += (s, e) => AddEmployee();
            delEmp.Click += (s, e) => DeleteEmployee();

            // меню для расходников
            var addMat = new ToolStripMenuItem("Добавить");
            var delMat = new ToolStripMenuItem("Удалить");
            contextMenuStrip3.Items.AddRange(new[] { addMat, delMat });
            dataGridViewMaterials.ContextMenuStrip = contextMenuStrip3;
            addMat.Click += (s, e) => AddMaterial();
            delMat.Click += (s, e) => DeleteMaterial();
        }

        // ============================================================
        // СОХРАНЕНИЕ / ОТМЕНА
        // ============================================================

        private void ShowSaveButtons()
        {
            SaveButton.Visible = true;
            CancelButton.Visible = true;
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            try
            {
                // Принудительно завершаем редактирование всех таблиц
                dataGridViewClients.EndEdit();
                dataGridViewEmployees.EndEdit();
                dataGridViewMaterials.EndEdit();

                SaveClients();
                SaveEmployees();
                SaveMaterials();

                SaveButton.Visible = false;
                CancelButton.Visible = false;
                MessageBox.Show("Данные сохранены!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.InnerException?.Message ?? ex.Message);
            }
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            newClients.Clear(); changedClients.Clear(); deletedClients.Clear();
            newEmployees.Clear(); changedEmployees.Clear(); deletedEmployees.Clear();
            newMaterials.Clear(); changedMaterials.Clear(); deletedMaterials.Clear();
            LoadClientsData();
            LoadEmployeesData();
            LoadMaterialsData();
            SaveButton.Visible = false;
            CancelButton.Visible = false;
        }

        private void txtSearch_TextChanged(object sender, EventArgs e)
        {
            cmbSort_SelectedIndexChanged(sender, e);
        }

        private void cmbSort_SelectedIndexChanged(object sender, EventArgs e)
        {
            string search = txtSearch.Text.Trim().ToLower();
            string sort = cmbSort.SelectedItem?.ToString();

            if (tabControl1.SelectedTab == tabClients)
            {
                var filtered = displayClients.AsQueryable();
                if (!string.IsNullOrEmpty(search))
                    filtered = filtered.Where(c =>
                        c.FullName.ToLower().Contains(search) ||
                        c.Phone.Contains(search));
                if (sort == "По ФИО") filtered = filtered.OrderBy(c => c.FullName);
                else if (sort == "По телефону") filtered = filtered.OrderBy(c => c.Phone);
                dataGridViewClients.DataSource = filtered.ToList();
            }
            else if (tabControl1.SelectedTab == tabEmployees)
            {
                var filtered = displayEmployees.AsQueryable();
                if (!string.IsNullOrEmpty(search))
                    filtered = filtered.Where(c =>
                        c.FullName.ToLower().Contains(search) ||
                        c.Phone.Contains(search));
                if (sort == "По ФИО") filtered = filtered.OrderBy(c => c.FullName);
                else if (sort == "По телефону") filtered = filtered.OrderBy(c => c.Phone);
                dataGridViewEmployees.DataSource = filtered.ToList();
            }
            else if (tabControl1.SelectedTab == tabMaterials)
            {
                var filtered = displayMaterials.AsQueryable();
                if (!string.IsNullOrEmpty(search))
                    filtered = filtered.Where(c =>
                        c.MaterialName.ToLower().Contains(search));
                dataGridViewMaterials.DataSource = filtered.ToList();
            }
        }
    }
}