using Npgsql; using RestaurantApp.Models; using System; using System.Collections.Generic; using System.Data; using System.Windows.Forms; namespace RestaurantApp.DAL { public class DishRepository { public List GetAll(string search = "", int categoryId = 0, bool? available = null) { var list = new List(); using (var conn = Database.GetConnection()) { var sql = @"SELECT d.dish_id, d.category_id, dc.name as cat_name, d.name, d.description, d.price, d.weight_g, d.cook_time_min, d.is_available FROM dish d JOIN dish_category dc ON dc.category_id = d.category_id WHERE 1=1 "; if (!string.IsNullOrWhiteSpace(search)) sql += " AND (LOWER(d.name) LIKE LOWER(@search) OR LOWER(d.description) LIKE LOWER(@search))"; if (categoryId > 0) sql += " AND d.category_id = @cat"; if (available.HasValue) sql += " AND d.is_available = @avail"; sql += " ORDER BY dc.name, d.name"; using (var cmd = new NpgsqlCommand(sql, conn)) { if (!string.IsNullOrWhiteSpace(search)) cmd.Parameters.AddWithValue("search", $"%{search}%"); if (categoryId > 0) cmd.Parameters.AddWithValue("cat", categoryId); if (available.HasValue) cmd.Parameters.AddWithValue("avail", available.Value); using (var r = cmd.ExecuteReader()) { while (r.Read()) list.Add(MapDish(r)); } } } return list; } public Dish GetById(int id) { using (var conn = Database.GetConnection()) using (var cmd = new NpgsqlCommand( @"SELECT d.dish_id, d.category_id, dc.name, d.name, d.description, d.price, d.weight_g, d.cook_time_min, d.is_available FROM dish d JOIN dish_category dc ON dc.category_id=d.category_id WHERE d.dish_id=@id", conn)) { cmd.Parameters.AddWithValue("id", id); using (var r = cmd.ExecuteReader()) if (r.Read()) return MapDish(r); } return null; } public void Insert(Dish d) { using (var conn = Database.GetConnection()) using (var cmd = new NpgsqlCommand( @"INSERT INTO dish(category_id, name, description, price, weight_g, cook_time_min, is_available) VALUES(@cat, @name, @desc, @price, @w, @ct, @avail)", conn)) { // Здесь НЕ должно быть параметра dish_id cmd.Parameters.AddWithValue("cat", d.CategoryId); cmd.Parameters.AddWithValue("name", d.Name); cmd.Parameters.AddWithValue("desc", (object)d.Description ?? DBNull.Value); cmd.Parameters.AddWithValue("price", d.Price); cmd.Parameters.AddWithValue("w", d.WeightG.HasValue ? (object)d.WeightG.Value : DBNull.Value); cmd.Parameters.AddWithValue("ct", d.CookTimeMin.HasValue ? (object)d.CookTimeMin.Value : DBNull.Value); cmd.Parameters.AddWithValue("avail", d.IsAvailable); cmd.ExecuteNonQuery(); } } public void Update(Dish d) { using (var conn = Database.GetConnection()) using (var cmd = new NpgsqlCommand( @"UPDATE dish SET category_id=@cat,name=@name,description=@desc,price=@price, weight_g=@w,cook_time_min=@ct,is_available=@avail WHERE dish_id=@id", conn)) { cmd.Parameters.AddWithValue("id", d.DishId); cmd.Parameters.AddWithValue("cat", d.CategoryId); cmd.Parameters.AddWithValue("name", d.Name); cmd.Parameters.AddWithValue("desc", (object)d.Description ?? DBNull.Value); cmd.Parameters.AddWithValue("price", d.Price); cmd.Parameters.AddWithValue("w", d.WeightG.HasValue ? (object)d.WeightG.Value : DBNull.Value); cmd.Parameters.AddWithValue("ct", d.CookTimeMin.HasValue ? (object)d.CookTimeMin.Value : DBNull.Value); cmd.Parameters.AddWithValue("avail", d.IsAvailable); cmd.ExecuteNonQuery(); } } public void Delete(int id) { using (var conn = Database.GetConnection()) { using (var checkCmd = new NpgsqlCommand( "SELECT COUNT(*) FROM order_item WHERE dish_id = @id", conn)) { checkCmd.Parameters.AddWithValue("id", id); long count = (long)checkCmd.ExecuteScalar(); if (count > 0) { using (var updateCmd = new NpgsqlCommand( "UPDATE dish SET is_available = false WHERE dish_id = @id", conn)) { updateCmd.Parameters.AddWithValue("id", id); updateCmd.ExecuteNonQuery(); } MessageBox.Show("Блюдо используется в заказах. Оно помечено как недоступное.", "Информация", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { using (var deleteCmd = new NpgsqlCommand( "DELETE FROM dish WHERE dish_id = @id", conn)) { deleteCmd.Parameters.AddWithValue("id", id); deleteCmd.ExecuteNonQuery(); } } } } } public DataTable GetCategories() { var dt = new DataTable(); using (var conn = Database.GetConnection()) using (var cmd = new NpgsqlCommand("SELECT category_id, name FROM dish_category ORDER BY name", conn)) using (var da = new NpgsqlDataAdapter(cmd)) da.Fill(dt); return dt; } private Dish MapDish(NpgsqlDataReader r) => new Dish { DishId = r.GetInt32(0), CategoryId = r.GetInt32(1), CategoryName = r.GetString(2), Name = r.GetString(3), Description = r.IsDBNull(4) ? "" : r.GetString(4), Price = r.GetDecimal(5), WeightG = r.IsDBNull(6) ? (int?)null : r.GetInt32(6), CookTimeMin = r.IsDBNull(7) ? (int?)null : r.GetInt32(7), IsAvailable = r.GetBoolean(8) }; } }