diff --git a/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj b/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj index e5042c8..443db72 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj +++ b/CarpentryWorkshop/CarpentryWorkshop/CarpentryWorkshop.csproj @@ -13,7 +13,18 @@ + + + + + + + + + + + @@ -31,4 +42,10 @@ + + + PreserveNewest + + + \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Entities/MaterialReplenishment.cs b/CarpentryWorkshop/CarpentryWorkshop/Entities/MaterialReplenishment.cs index a74839a..74eeab3 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Entities/MaterialReplenishment.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Entities/MaterialReplenishment.cs @@ -3,6 +3,7 @@ public class MaterialReplenishment { public int Id { get; private set; } + public DateTime DateReplenishment { get; private set; } public string Name { get; private set; } = string.Empty; public int Count { get; private set; } public static MaterialReplenishment CreateOperation(int id, string name, int count) @@ -10,6 +11,7 @@ public class MaterialReplenishment return new MaterialReplenishment { Id = id, + DateReplenishment = DateTime.Now, Name = name, Count = count }; diff --git a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.Designer.cs b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.Designer.cs index aeacb08..0ad34bd 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.Designer.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.Designer.cs @@ -34,14 +34,17 @@ labelCount = new Label(); textBoxName = new TextBox(); numericUpDownCount = new NumericUpDown(); + comboBoxMaterial = new ComboBox(); + labelMaterial = new Label(); ((System.ComponentModel.ISupportInitialize)numericUpDownCount).BeginInit(); SuspendLayout(); // // buttonAdd // - buttonAdd.Location = new Point(33, 164); + buttonAdd.Location = new Point(38, 219); + buttonAdd.Margin = new Padding(3, 4, 3, 4); buttonAdd.Name = "buttonAdd"; - buttonAdd.Size = new Size(75, 23); + buttonAdd.Size = new Size(86, 31); buttonAdd.TabIndex = 1; buttonAdd.Text = "Add"; buttonAdd.UseVisualStyleBackColor = true; @@ -49,9 +52,10 @@ // // buttonCancel // - buttonCancel.Location = new Point(199, 164); + buttonCancel.Location = new Point(227, 219); + buttonCancel.Margin = new Padding(3, 4, 3, 4); buttonCancel.Name = "buttonCancel"; - buttonCancel.Size = new Size(75, 23); + buttonCancel.Size = new Size(86, 31); buttonCancel.TabIndex = 2; buttonCancel.Text = "Cancel"; buttonCancel.UseVisualStyleBackColor = true; @@ -60,47 +64,71 @@ // labelName // labelName.AutoSize = true; - labelName.Location = new Point(33, 46); + labelName.Location = new Point(38, 25); labelName.Name = "labelName"; - labelName.Size = new Size(39, 15); + labelName.Size = new Size(49, 20); labelName.TabIndex = 3; labelName.Text = "Name"; // // labelCount // labelCount.AutoSize = true; - labelCount.Location = new Point(33, 97); + labelCount.Location = new Point(38, 129); labelCount.Name = "labelCount"; - labelCount.Size = new Size(40, 15); + labelCount.Size = new Size(48, 20); labelCount.TabIndex = 4; labelCount.Text = "Count"; // // textBoxName // - textBoxName.Location = new Point(124, 46); + textBoxName.Location = new Point(142, 22); + textBoxName.Margin = new Padding(3, 4, 3, 4); textBoxName.Name = "textBoxName"; - textBoxName.Size = new Size(120, 23); + textBoxName.Size = new Size(137, 27); textBoxName.TabIndex = 7; // // numericUpDownCount // - numericUpDownCount.Location = new Point(124, 97); + numericUpDownCount.Location = new Point(142, 129); + numericUpDownCount.Margin = new Padding(3, 4, 3, 4); numericUpDownCount.Name = "numericUpDownCount"; - numericUpDownCount.Size = new Size(120, 23); + numericUpDownCount.Size = new Size(137, 27); numericUpDownCount.TabIndex = 8; // - // FormMaterialSpent + // comboBoxMaterial // - AutoScaleDimensions = new SizeF(7F, 15F); + comboBoxMaterial.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxMaterial.FormattingEnabled = true; + comboBoxMaterial.Location = new Point(142, 70); + comboBoxMaterial.Margin = new Padding(3, 4, 3, 4); + comboBoxMaterial.Name = "comboBoxMaterial"; + comboBoxMaterial.Size = new Size(137, 28); + comboBoxMaterial.TabIndex = 9; + // + // labelMaterial + // + labelMaterial.AutoSize = true; + labelMaterial.Location = new Point(37, 73); + labelMaterial.Name = "labelMaterial"; + labelMaterial.Size = new Size(64, 20); + labelMaterial.TabIndex = 10; + labelMaterial.Text = "Material"; + // + // FormMaterialReplenishment + // + AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(304, 204); + ClientSize = new Size(347, 272); + Controls.Add(labelMaterial); + Controls.Add(comboBoxMaterial); Controls.Add(numericUpDownCount); Controls.Add(textBoxName); Controls.Add(labelCount); Controls.Add(labelName); Controls.Add(buttonCancel); Controls.Add(buttonAdd); - Name = "FormMaterialSpent"; + Margin = new Padding(3, 4, 3, 4); + Name = "FormMaterialReplenishment"; Text = "FormMaterialSpent"; ((System.ComponentModel.ISupportInitialize)numericUpDownCount).EndInit(); ResumeLayout(false); @@ -115,5 +143,7 @@ private Label labelCount; private TextBox textBoxName; private NumericUpDown numericUpDownCount; + private ComboBox comboBoxMaterial; + private Label labelMaterial; } } \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.cs b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.cs index 434654e..52b4012 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormMaterialReplenishment.cs @@ -1,6 +1,5 @@ using CarpentryWorkshop.Entities; using CarpentryWorkshop.Repositories; -using System.Windows.Forms; namespace CarpentryWorkshop.Forms { @@ -30,10 +29,13 @@ namespace CarpentryWorkshop.Forms } } } - public FormMaterialReplenishment(IMaterialReplenishmentRepository materialSpentRepository) + public FormMaterialReplenishment(IMaterialReplenishmentRepository materialSpentRepository, IMaterialRepository materialRepository) { InitializeComponent(); _materialSpentRepository = materialSpentRepository ?? throw new ArgumentNullException(nameof(materialSpentRepository)); + comboBoxMaterial.DataSource = materialRepository.ReadMaterials() ?? throw new ArgumentNullException(nameof(materialRepository)); + comboBoxMaterial.DisplayMember = "Name"; + comboBoxMaterial.ValueMember = "Id"; } private MaterialReplenishment CreateMaterialSpent(int id) => MaterialReplenishment.CreateOperation(id, textBoxName.Text, Convert.ToInt32(numericUpDownCount.Value)); private void buttonAdd_Click_1(object sender, EventArgs e) diff --git a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormProductMaterial.cs b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormProductMaterial.cs index e399428..d566e82 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Forms/FormProductMaterial.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Forms/FormProductMaterial.cs @@ -11,6 +11,7 @@ namespace CarpentryWorkshop.Forms public partial class FormProductMaterial : Form { private readonly IProductRepository _productRepository; + private readonly IMaterialRepository _materialRepository; private int? _productId; private ProductType selectedProducts = ProductType.None; @@ -33,6 +34,20 @@ namespace CarpentryWorkshop.Forms checkedListBox1.SetItemChecked(0, product.Type.HasFlag(ProductType.Wardrobe)); checkedListBox1.SetItemChecked(1, product.Type.HasFlag(ProductType.Table)); checkedListBox1.SetItemChecked(2, product.Type.HasFlag(ProductType.Bench)); + + dataGridView.Rows.Clear(); + var rows = new List(); + foreach (var productMaterial in product.ProductMaterial) + { + var material = _materialRepository.ReadMaterialById(productMaterial.MaterialId); + if (material != null) + { + var row = new DataGridViewRow(); + row.CreateCells(dataGridView, material.Id, productMaterial.Count); + rows.Add(row); + } + } + dataGridView.Rows.AddRange(rows.ToArray()); } catch (Exception ex) { @@ -46,6 +61,7 @@ namespace CarpentryWorkshop.Forms { InitializeComponent(); _productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository)); + _materialRepository = materialRepository ?? throw new ArgumentNullException(nameof(materialRepository)); ColumnMaterials.DataSource = materialRepository.ReadMaterials(); ColumnMaterials.DisplayMember = "Name"; diff --git a/CarpentryWorkshop/CarpentryWorkshop/Program.cs b/CarpentryWorkshop/CarpentryWorkshop/Program.cs index 0d4eaf5..c962f01 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Program.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Program.cs @@ -1,4 +1,8 @@ using Unity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Serilog; +using Unity.Microsoft.Logging; using CarpentryWorkshop.Repositories; using CarpentryWorkshop.Repositories.Implementations; @@ -20,12 +24,26 @@ namespace CarpentryWorkshop private static IUnityContainer CreateContainer() { var container = new UnityContainer(); + + container.AddExtension(new LoggingExtension(CreateLoggerFactory())); + container.RegisterType(); container.RegisterType(); container.RegisterType(); container.RegisterType(); + container.RegisterType(); return container; } - + private static LoggerFactory CreateLoggerFactory() + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddSerilog(new LoggerConfiguration() + .ReadFrom.Configuration(new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build()) + .CreateLogger()); + return loggerFactory; + } } } \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs new file mode 100644 index 0000000..b95132a --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IConnectionString.cs @@ -0,0 +1,6 @@ +namespace CarpentryWorkshop.Repositories; + +public interface IConnectionString +{ + public string ConnectionString { get; } +} diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs index a1b56f3..7e478ef 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/IOrderRepository.cs @@ -5,7 +5,6 @@ namespace CarpentryWorkshop.Repositories; public interface IOrderRepository { IEnumerable ReadOrders(DateTime? dateForm = null, DateTime? dateTo = null, int? orderStatus = null, int? orderId = null); - Order ReadOrderById(int orderId); void CreateOrder(Order order); void DeleteOrder(int id); } diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs new file mode 100644 index 0000000..aaf72db --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ConnectionString.cs @@ -0,0 +1,6 @@ +namespace CarpentryWorkshop.Repositories.Implementations; + +public class ConnectionString : IConnectionString +{ + string IConnectionString.ConnectionString => "Server=localhost;Port=5432;Database=carpentryworkshopp;"; +} \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs index d86e94c..aa26fcb 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialReplenishmentRepository.cs @@ -1,24 +1,100 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class MaterialReplenishmentRepository : IMaterialReplenishmentRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public MaterialReplenishmentRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } public void CreateMaterialSpent(MaterialReplenishment material) { - } - - public MaterialReplenishment ReadMaterialSpentById(int id) - { - return MaterialReplenishment.CreateOperation(0, string.Empty, 0); - } - - public IEnumerable ReadMaterialsSpent() - { - return []; + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO MaterialReplenishment (Name, Count) + VALUES (@Name, @Count)"; + connection.Execute(queryInsert, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void UpdateMaterialSpent(MaterialReplenishment material) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE MaterialReplenishment + SET + Name=@Name, + Count=@Count + WHERE Id=@Id"; + connection.Execute(queryUpdate, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } -} + + public MaterialReplenishment ReadMaterialSpentById(int id) + { + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM MaterialReplenishment + WHERE Id=@id"; + var material = connection.QueryFirst(querySelect, new + { + id + }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(material)); + return material; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } + } + + public IEnumerable ReadMaterialsSpent() + { + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = "SELECT * FROM MaterialReplenishment"; + var materials = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(materials)); + return materials; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } + } +} \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs index fa8864a..0903bdb 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/MaterialRepository.cs @@ -1,28 +1,120 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class MaterialRepository : IMaterialRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public MaterialRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } + public void CreateMaterial(Material material) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryInsert = @" + INSERT INTO Materials (Name, Count, ReservInWarehouse) + VALUES (@Name, @Count, @ReservInWarehouse)"; + connection.Execute(queryInsert, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } + } + public void UpdateMaterial(Material material) + { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(material)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryUpdate = @" + UPDATE Materials + SET + Name=@Name, + Count=@Count, + ReservInWarehouse=@ReservInWarehouse + WHERE Id=@Id"; + connection.Execute(queryUpdate, material); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } public void DeleteMaterial(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Materials + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadMaterials() { - return []; + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = "SELECT * FROM Materials"; + var materials = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(materials)); + return materials; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public Material ReadMaterialById(int id) { - return Material.CreateEntity(id, string.Empty, 0, 0); - } - - public void UpdateMaterial(Material material) - { + _logger.LogInformation("Получение объекта по идентификатору"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Materials + WHERE Id=@id"; + var material = connection.QueryFirst(querySelect, new + { + id + }); + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(material)); + return material; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при поиске объекта"); + throw; + } } } diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs index b3cfeae..62a3663 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/OrderRepository.cs @@ -1,23 +1,90 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class OrderRepository : IOrderRepository { - public void CreateOrder(Order feedReplenishment) + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public OrderRepository(IConnectionString connectionString, ILogger logger) { + _connectionString = connectionString; + _logger = logger; + } + public void CreateOrder(Order order) + { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(order)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + var queryInsert = @" + INSERT INTO Orders (Status, Description) + VALUES (@Status, @Description); + SELECT MAX(Id) FROM Orders"; + var orderId = connection.QueryFirst(queryInsert, order, transaction); + var querySubInsert = @" + INSERT INTO Orders_Products (OrderId, ProductId, Count) + VALUES (@OrderId, @ProductId, @Count)"; + foreach (var elem in order.OrderProduct) + { + connection.Execute(querySubInsert, new + { + orderId, + elem.ProductId, + elem.Count + }, transaction); + } + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteOrder(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Orders + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadOrders(DateTime? dateForm = null, DateTime? dateTo = null, int? orderStatus = null, int? orderId = null) { - return []; - } - public Order ReadOrderById(int id) - { - return Order.CreateOperation(id, 0, string.Empty, []); + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @"SELECT * FROM Orders"; + var order = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(order)); + return order; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } } + diff --git a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs index 2a50786..e2de0a3 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Repositories/Implementations/ProductRepository.cs @@ -1,28 +1,164 @@ using CarpentryWorkshop.Entities; +using Dapper; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Npgsql; namespace CarpentryWorkshop.Repositories.Implementations; public class ProductRepository : IProductRepository { + private readonly IConnectionString _connectionString; + private readonly ILogger _logger; + public ProductRepository(IConnectionString connectionString, ILogger logger) + { + _connectionString = connectionString; + _logger = logger; + } public void CreateProduct(Product product) { + _logger.LogInformation("Добавление объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + var queryInsert = @" + INSERT INTO Products (Name, Type, CountInWarehouse) + VALUES (@Name, @Type, @CountInWarehouse); + SELECT MAX(Id) FROM Products"; + var productId = connection.QueryFirst(queryInsert, product, transaction); + var querySubInsert = @" + INSERT INTO Products_Materials (ProductId, MaterialId, Count) + VALUES (@ProductId, @MaterialId, @Count)"; + foreach (var elem in product.ProductMaterial) + { + connection.Execute(querySubInsert, new + { + productId, + elem.MaterialId, + elem.Count + }, transaction); + } + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при добавлении объекта"); + throw; + } } public void DeleteProduct(int id) { + _logger.LogInformation("Удаление объекта"); + _logger.LogDebug("Объект: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var queryDelete = @" + DELETE FROM Products + WHERE Id=@id"; + connection.Execute(queryDelete, new { id }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при удалении объекта"); + throw; + } } public IEnumerable ReadProducts() { - return []; + _logger.LogInformation("Получение всех объектов"); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @"SELECT * FROM Products"; + var product = connection.Query(querySelect); + _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(product)); + return product; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объектов"); + throw; + } } public Product ReadProductById(int id) { - return Product.CreateEntity(id, string.Empty, 0, 0, []); + _logger.LogInformation("Получение объекта по ID: {id}", id); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + var querySelect = @" + SELECT * FROM Products WHERE Id = @Id; + SELECT m.*, pm.Count FROM Materials m + JOIN Products_Materials pm ON m.Id = pm.MaterialId + WHERE pm.ProductId = @Id"; + using var multi = connection.QueryMultiple(querySelect, new { Id = id }); + var product = multi.Read().FirstOrDefault(); + if (product != null) + { + var materials = multi.Read().ToList(); + product.ProductMaterial = materials.Select(m => new ProductMaterial + { + MaterialId = m.Id, + Count = m.Count + }).ToList(); + } + _logger.LogDebug("Найденный объект: {json}", JsonConvert.SerializeObject(product)); + return product; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при чтении объекта по ID: {id}", id); + throw; + } } public void UpdateProduct(Product product) { + _logger.LogInformation("Редактирование объекта"); + _logger.LogDebug("Объект: {json}", JsonConvert.SerializeObject(product)); + try + { + using var connection = new NpgsqlConnection(_connectionString.ConnectionString); + connection.Open(); + using var transaction = connection.BeginTransaction(); + + var queryUpdate = @" + UPDATE Products + SET Name = @Name, Type = @Type, CountInWarehouse = @CountInWarehouse + WHERE Id = @Id"; + connection.Execute(queryUpdate, product, transaction); + + var queryDelete = @" + DELETE FROM Products_Materials + WHERE ProductId = @ProductId"; + connection.Execute(queryDelete, new { ProductId = product.Id }, transaction); + + var querySubInsert = @" + INSERT INTO Products_Materials (ProductId, MaterialId, Count) + VALUES (@ProductId, @MaterialId, @Count)"; + foreach (var elem in product.ProductMaterial) + { + connection.Execute(querySubInsert, new + { + ProductId = product.Id, + elem.MaterialId, + elem.Count + }, transaction); + } + + transaction.Commit(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при редактировании объекта"); + throw; + } } } diff --git a/CarpentryWorkshop/CarpentryWorkshop/appsettings.json b/CarpentryWorkshop/CarpentryWorkshop/appsettings.json new file mode 100644 index 0000000..540cd04 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/appsettings.json @@ -0,0 +1,15 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Debug", + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs.txt", + "rollingInterval": "Day" + } + } + ] + } +} \ No newline at end of file