From 719445fe814b7c9a3276ca79f369873a09d018f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D0=B0=D0=BB=D0=B8=D0=BD=D0=B0=20=D0=A4=D0=B5=D0=B4?= =?UTF-8?q?=D0=BE=D1=80=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 19 Apr 2024 13:46:01 +0400 Subject: [PATCH] =?UTF-8?q?5=20=D0=BB=D0=B0=D0=B1=D0=B0=201=20=D1=8D=D1=82?= =?UTF-8?q?=D0=B0=D0=BF=20+=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20rest?= =?UTF-8?q?=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CarpentryWorkshop/CarpentryWorkshop.sln | 8 +- .../CarpentryWorkshop/FormClients.Designer.cs | 100 ++++++++ .../CarpentryWorkshop/FormClients.cs | 84 +++++++ .../CarpentryWorkshop/FormClients.resx | 120 ++++++++++ .../CarpentryWorkshop/FormMain.Designer.cs | 11 +- .../CarpentryWorkshop/FormMain.cs | 11 + .../CarpentryWorkshop/Program.cs | 3 + .../BusinessLogics/ClientLogic.cs | 112 +++++++++ .../BindingModels/ClientBindingModel.cs | 12 + .../BindingModels/OrderBindingModel.cs | 1 + .../BusinessLogicsContracts/IClientLogic.cs | 15 ++ .../SearchModels/ClientSearchModel.cs | 10 + .../SearchModels/OrderSearchModel.cs | 1 + .../StoragesContracts/IClientStorage.cs | 16 ++ .../ViewModels/ClientViewModel.cs | 16 ++ .../ViewModels/OrderViewModel.cs | 3 + .../Models/IClientModel.cs | 9 + .../CarpentryWorkshopDatabase.cs | 1 + .../Implements/ClientStorage.cs | 80 +++++++ .../Implements/OrderStorage.cs | 13 +- .../20240419085157_MbLab5.Designer.cs | 214 ++++++++++++++++++ .../Migrations/20240419085157_MbLab5.cs | 69 ++++++ .../CarpentryWorkshopDatabaseModelSnapshot.cs | 43 ++++ .../Models/Client.cs | 59 +++++ .../Models/Order.cs | 4 +- .../DataFileSingleton.cs | 6 + .../Implements/ClientStorage.cs | 81 +++++++ .../Models/Client.cs | 74 ++++++ .../DataListSingleton.cs | 2 + .../Implements/ClientStorage.cs | 99 ++++++++ .../Models/Client.cs | 51 +++++ .../CarpentryWorkshopRestApi.csproj | 23 ++ .../CarpentryWorkshopRestApi/Program.cs | 46 ++++ .../Properties/launchSettings.json | 31 +++ .../appsettings.Development.json | 8 + .../CarpentryWorkshopRestApi/appsettings.json | 9 + .../CarpentryWorkshopRestApi/log4net.config | 16 ++ 37 files changed, 1452 insertions(+), 9 deletions(-) create mode 100644 CarpentryWorkshop/CarpentryWorkshop/FormClients.Designer.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshop/FormClients.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshop/FormClients.resx create mode 100644 CarpentryWorkshop/CarpentryWorkshopBusinessLogic/BusinessLogics/ClientLogic.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/ClientBindingModel.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopContracts/BusinessLogicsContracts/IClientLogic.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/ClientSearchModel.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopContracts/StoragesContracts/IClientStorage.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/ClientViewModel.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopDataModels/Models/IClientModel.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/ClientStorage.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.Designer.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Client.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopFileImplement/Implements/ClientStorage.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopFileImplement/Models/Client.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopListImplement/Implements/ClientStorage.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopListImplement/Models/Client.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/CarpentryWorkshopRestApi.csproj create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/Program.cs create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/Properties/launchSettings.json create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.Development.json create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.json create mode 100644 CarpentryWorkshop/CarpentryWorkshopRestApi/log4net.config diff --git a/CarpentryWorkshop/CarpentryWorkshop.sln b/CarpentryWorkshop/CarpentryWorkshop.sln index ad24eb6..5cbf275 100644 --- a/CarpentryWorkshop/CarpentryWorkshop.sln +++ b/CarpentryWorkshop/CarpentryWorkshop.sln @@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarpentryWorkshopBusinessLo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarpentryWorkshopFileImplement", "CarpentryWorkshopFileImplement\CarpentryWorkshopFileImplement.csproj", "{6EFF6C01-263D-4D25-806A-1DC593820AB1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CarpentryWorkshopDatabaseImplement", "CarpentryWorkshopDatabaseImplement\CarpentryWorkshopDatabaseImplement.csproj", "{249894CF-B596-4AFD-8EB7-F167056920A1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarpentryWorkshopDatabaseImplement", "CarpentryWorkshopDatabaseImplement\CarpentryWorkshopDatabaseImplement.csproj", "{249894CF-B596-4AFD-8EB7-F167056920A1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CarpentryWorkshopRestApi", "CarpentryWorkshopRestApi\CarpentryWorkshopRestApi.csproj", "{D9D18CB0-4068-43B6-92F9-85905E53FF95}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -51,6 +53,10 @@ Global {249894CF-B596-4AFD-8EB7-F167056920A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {249894CF-B596-4AFD-8EB7-F167056920A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {249894CF-B596-4AFD-8EB7-F167056920A1}.Release|Any CPU.Build.0 = Release|Any CPU + {D9D18CB0-4068-43B6-92F9-85905E53FF95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9D18CB0-4068-43B6-92F9-85905E53FF95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9D18CB0-4068-43B6-92F9-85905E53FF95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9D18CB0-4068-43B6-92F9-85905E53FF95}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CarpentryWorkshop/CarpentryWorkshop/FormClients.Designer.cs b/CarpentryWorkshop/CarpentryWorkshop/FormClients.Designer.cs new file mode 100644 index 0000000..84dd57d --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/FormClients.Designer.cs @@ -0,0 +1,100 @@ +using System.Windows.Forms; + +namespace CarpentryWorkshopView +{ + partial class FormClients + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + dataGridView = new DataGridView(); + buttonUpd = new Button(); + buttonDel = new Button(); + ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); + SuspendLayout(); + // + // dataGridView + // + dataGridView.AllowUserToAddRows = false; + dataGridView.AllowUserToDeleteRows = false; + dataGridView.BackgroundColor = SystemColors.ControlLightLight; + dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridView.Dock = DockStyle.Left; + dataGridView.Location = new Point(0, 0); + dataGridView.Margin = new Padding(4, 3, 4, 3); + dataGridView.MultiSelect = false; + dataGridView.Name = "dataGridView"; + dataGridView.ReadOnly = true; + dataGridView.RowHeadersVisible = false; + dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dataGridView.Size = new Size(408, 360); + dataGridView.TabIndex = 1; + // + // buttonUpd + // + buttonUpd.Location = new Point(430, 59); + buttonUpd.Margin = new Padding(4, 3, 4, 3); + buttonUpd.Name = "buttonUpd"; + buttonUpd.Size = new Size(88, 27); + buttonUpd.TabIndex = 8; + buttonUpd.Text = "Обновить"; + buttonUpd.UseVisualStyleBackColor = true; + buttonUpd.Click += ButtonUpd_Click; + // + // buttonDel + // + buttonDel.Location = new Point(430, 12); + buttonDel.Margin = new Padding(4, 3, 4, 3); + buttonDel.Name = "buttonDel"; + buttonDel.Size = new Size(88, 27); + buttonDel.TabIndex = 7; + buttonDel.Text = "Удалить"; + buttonDel.UseVisualStyleBackColor = true; + buttonDel.Click += ButtonDel_Click; + // + // FormClients + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(541, 360); + Controls.Add(buttonUpd); + Controls.Add(buttonDel); + Controls.Add(dataGridView); + Name = "FormClients"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Клиенты"; + Load += FormClients_Load; + ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView dataGridView; + private Button buttonUpd; + private Button buttonDel; + } +} \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/FormClients.cs b/CarpentryWorkshop/CarpentryWorkshop/FormClients.cs new file mode 100644 index 0000000..6ffc595 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/FormClients.cs @@ -0,0 +1,84 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CarpentryWorkshopView +{ + public partial class FormClients : Form + { + private readonly ILogger _logger; + + private readonly IClientLogic _logic; + + public FormClients(ILogger logger, IClientLogic logic) + { + InitializeComponent(); + _logger = logger; + _logic = logic; + } + + private void FormClients_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + try + { + var list = _logic.ReadList(null); + if (list != null) + { + dataGridView.DataSource = list; + dataGridView.Columns["Id"].Visible = false; + dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + _logger.LogInformation("Clients loading"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Clients loading error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonDel_Click(object sender, EventArgs e) + { + if (dataGridView.SelectedRows.Count == 1) + { + if (MessageBox.Show("Удалить клиента?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); + _logger.LogInformation("Deletion of client"); + try + { + if (!_logic.Delete(new ClientBindingModel { Id = id })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + LoadData(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Client deletion error"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } + + private void ButtonUpd_Click(object sender, EventArgs e) + { + LoadData(); + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshop/FormClients.resx b/CarpentryWorkshop/CarpentryWorkshop/FormClients.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshop/FormClients.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/FormMain.Designer.cs b/CarpentryWorkshop/CarpentryWorkshop/FormMain.Designer.cs index 865c038..069bfa2 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/FormMain.Designer.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/FormMain.Designer.cs @@ -32,6 +32,7 @@ справочникиToolStripMenuItem = new ToolStripMenuItem(); КомпонентыToolStripMenuItem = new ToolStripMenuItem(); ИзделияToolStripMenuItem = new ToolStripMenuItem(); + клиентыToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem(); списокИзделийToolStripMenuItem = new ToolStripMenuItem(); компонентыПоИзделиямToolStripMenuItem = new ToolStripMenuItem(); @@ -57,7 +58,7 @@ // // справочникиToolStripMenuItem // - справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, ИзделияToolStripMenuItem }); + справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, ИзделияToolStripMenuItem, клиентыToolStripMenuItem }); справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; справочникиToolStripMenuItem.Size = new Size(94, 20); справочникиToolStripMenuItem.Text = "Справочники"; @@ -76,6 +77,13 @@ ИзделияToolStripMenuItem.Text = "Изделия"; ИзделияToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click; // + // клиентыToolStripMenuItem + // + клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem"; + клиентыToolStripMenuItem.Size = new Size(224, 26); + клиентыToolStripMenuItem.Text = "Клиенты"; + клиентыToolStripMenuItem.Click += КлиентыToolStripMenuItem_Click; + // // отчётыToolStripMenuItem // отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { списокИзделийToolStripMenuItem, компонентыПоИзделиямToolStripMenuItem, списокЗаказовToolStripMenuItem }); @@ -210,5 +218,6 @@ private ToolStripMenuItem списокИзделийToolStripMenuItem; private ToolStripMenuItem компонентыПоИзделиямToolStripMenuItem; private ToolStripMenuItem списокЗаказовToolStripMenuItem; + private ToolStripMenuItem клиентыToolStripMenuItem; } } \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshop/FormMain.cs b/CarpentryWorkshop/CarpentryWorkshop/FormMain.cs index c283592..42d7a83 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/FormMain.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/FormMain.cs @@ -33,6 +33,8 @@ namespace CarpentryWorkshopView dataGridView.DataSource = list; dataGridView.Columns["WoodId"].Visible = false; dataGridView.Columns["WoodName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + dataGridView.Columns["ClientId"].Visible = false; + dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } _logger.LogInformation("Загрузка изделий"); @@ -60,6 +62,15 @@ namespace CarpentryWorkshopView form.ShowDialog(); } } + + private void КлиентыToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormClients)); + if (service is FormClients form) + { + form.ShowDialog(); + } + } private void ButtonCreateOrder_Click(object sender, EventArgs e) { var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); diff --git a/CarpentryWorkshop/CarpentryWorkshop/Program.cs b/CarpentryWorkshop/CarpentryWorkshop/Program.cs index 462ded6..495d12f 100644 --- a/CarpentryWorkshop/CarpentryWorkshop/Program.cs +++ b/CarpentryWorkshop/CarpentryWorkshop/Program.cs @@ -38,10 +38,12 @@ namespace CarpentryWorkshop option.SetMinimumLevel(LogLevel.Information); option.AddNLog("nlog.config"); }); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -54,6 +56,7 @@ namespace CarpentryWorkshop services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/CarpentryWorkshop/CarpentryWorkshopBusinessLogic/BusinessLogics/ClientLogic.cs b/CarpentryWorkshop/CarpentryWorkshopBusinessLogic/BusinessLogics/ClientLogic.cs new file mode 100644 index 0000000..24a3edb --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopBusinessLogic/BusinessLogics/ClientLogic.cs @@ -0,0 +1,112 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.BusinessLogicsContracts; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.StoragesContracts; +using CarpentryWorkshopContracts.ViewModels; +using Microsoft.Extensions.Logging; + +namespace CarpentryWorkshopBusinessLogic.BusinessLogics +{ + public class ClientLogic : IClientLogic + { + private readonly ILogger _logger; + private readonly IClientStorage _clientStorage; + public ClientLogic(ILogger logger, IClientStorage clientStorage) + { + _logger = logger; + _clientStorage = clientStorage; + } + + public bool Create(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + public bool Update(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + public bool Delete(ClientBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_clientStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Email:{Email}.Id:{ Id}", model.Email, model.Id); + var element = _clientStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public List? ReadList(ClientSearchModel? model) + { + _logger.LogInformation("ReadList. Email:{Email}.Id:{ Id} ", model?.Email, model?.Id); + var list = (model == null) ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + private void CheckModel(ClientBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ClientFIO)) + { + throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Нет логина(почты) клиента", nameof(model.Email)); + } + _logger.LogInformation("Client. Id: {Id}, FIO: {fio}, email: {email}", model.Id, model.ClientFIO, model.Email); + var element = _clientStorage.GetElement(new ClientSearchModel + { + Email = model.Email, + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Клиент с таким логином(почтой) уже есть"); + } + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/ClientBindingModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..48fda50 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,12 @@ +using CarpentryWorkshopDataModels.Models; + +namespace CarpentryWorkshopContracts.BindingModels +{ + public class ClientBindingModel : IClientModel + { + public int Id { get; set; } + public string ClientFIO { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/OrderBindingModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/OrderBindingModel.cs index 5421843..1e8a96a 100644 --- a/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/OrderBindingModel.cs +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/BindingModels/OrderBindingModel.cs @@ -7,6 +7,7 @@ namespace CarpentryWorkshopContracts.BindingModels { public int Id { get; set; } public int WoodId { get; set; } + public int ClientId { get; set; } public int Count { get; set; } public double Sum { get; set; } public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/BusinessLogicsContracts/IClientLogic.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/BusinessLogicsContracts/IClientLogic.cs new file mode 100644 index 0000000..e9c7a0f --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/BusinessLogicsContracts/IClientLogic.cs @@ -0,0 +1,15 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.ViewModels; + +namespace CarpentryWorkshopContracts.BusinessLogicsContracts +{ + public interface IClientLogic + { + List? ReadList(ClientSearchModel? model); + ClientViewModel? ReadElement(ClientSearchModel model); + bool Create(ClientBindingModel model); + bool Update(ClientBindingModel model); + bool Delete(ClientBindingModel model); + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/ClientSearchModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..74b4604 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,10 @@ +namespace CarpentryWorkshopContracts.SearchModels +{ + public class ClientSearchModel + { + public int? Id { get; set; } + public string? ClientFIO { get; set; } + public string? Email { get; set; } + public string? Password { get; set; } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/OrderSearchModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/OrderSearchModel.cs index a38f7b2..39520f2 100644 --- a/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/OrderSearchModel.cs +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/SearchModels/OrderSearchModel.cs @@ -5,5 +5,6 @@ public int? Id { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } + public int? ClientId { get; set; } } } \ No newline at end of file diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/StoragesContracts/IClientStorage.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/StoragesContracts/IClientStorage.cs new file mode 100644 index 0000000..989f3ba --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/StoragesContracts/IClientStorage.cs @@ -0,0 +1,16 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.ViewModels; + +namespace CarpentryWorkshopContracts.StoragesContracts +{ + public interface IClientStorage + { + List GetFullList(); + List GetFilteredList(ClientSearchModel model); + ClientViewModel? GetElement(ClientSearchModel model); + ClientViewModel? Insert(ClientBindingModel model); + ClientViewModel? Update(ClientBindingModel model); + ClientViewModel? Delete(ClientBindingModel model); + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/ClientViewModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..b74fb7a --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,16 @@ +using CarpentryWorkshopDataModels.Models; +using System.ComponentModel; + +namespace CarpentryWorkshopContracts.ViewModels +{ + public class ClientViewModel : IClientModel + { + public int Id { get; set; } + [DisplayName("Client's FIO")] + public string ClientFIO { get; set; } = string.Empty; + [DisplayName("Login (Email)")] + public string Email { get; set; } = string.Empty; + [DisplayName("Password")] + public string Password { get; set; } = string.Empty; + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/OrderViewModel.cs b/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/OrderViewModel.cs index 64235bc..6466268 100644 --- a/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/OrderViewModel.cs +++ b/CarpentryWorkshop/CarpentryWorkshopContracts/ViewModels/OrderViewModel.cs @@ -11,6 +11,9 @@ namespace CarpentryWorkshopContracts.ViewModels public int WoodId { get; set; } [DisplayName("Изделие")] public string WoodName { get; set; } = string.Empty; + public int ClientId { get; set; } + [DisplayName("Клиент")] + public string ClientFIO { get; set; } = string.Empty; [DisplayName("Количество")] public int Count { get; set; } [DisplayName("Сумма")] diff --git a/CarpentryWorkshop/CarpentryWorkshopDataModels/Models/IClientModel.cs b/CarpentryWorkshop/CarpentryWorkshopDataModels/Models/IClientModel.cs new file mode 100644 index 0000000..e290c5e --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopDataModels/Models/IClientModel.cs @@ -0,0 +1,9 @@ +namespace CarpentryWorkshopDataModels.Models +{ + public interface IClientModel : IId + { + string ClientFIO { get; } + string Email { get; } + string Password { get; } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/CarpentryWorkshopDatabase.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/CarpentryWorkshopDatabase.cs index 194ce4c..1a399d1 100644 --- a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/CarpentryWorkshopDatabase.cs +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/CarpentryWorkshopDatabase.cs @@ -17,5 +17,6 @@ namespace CarpentryWorkshopDatabaseImplement public virtual DbSet Woods { set; get; } public virtual DbSet WoodComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Clients { set; get; } } } diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/ClientStorage.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..581fe03 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,80 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.StoragesContracts; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopDatabaseImplement.Models; + +namespace CarpentryWorkshopDatabaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) + { + return null; + } + using var context = new CarpentryWorkshopDatabase(); + return context.Clients.FirstOrDefault(x => + (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) + || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email)) + { + return new(); + } + using var context = new CarpentryWorkshopDatabase(); + return context.Clients + .Where(x => x.Email.Contains(model.Email)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() + { + using var context = new CarpentryWorkshopDatabase(); + return context.Clients.Select(x => x.GetViewModel).ToList(); + } + + public ClientViewModel? Insert(ClientBindingModel model) + { + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + using var context = new CarpentryWorkshopDatabase(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new CarpentryWorkshopDatabase(); + var client = context.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + client.Update(model); + context.SaveChanges(); + return client.GetViewModel; + } + public ClientViewModel? Delete(ClientBindingModel model) + { + using var context = new CarpentryWorkshopDatabase(); + var client = context.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + context.Clients.Remove(client); + context.SaveChanges(); + return client.GetViewModel; + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/OrderStorage.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/OrderStorage.cs index 266d6f2..ef8187b 100644 --- a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/OrderStorage.cs +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Implements/OrderStorage.cs @@ -16,19 +16,20 @@ namespace CarpentryWorkshopDatabaseImplement.Implements return null; } using var context = new CarpentryWorkshopDatabase(); - return context.Orders.Include(x => x.Wood).FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + return context.Orders.Include(x => x.Wood).Include(x => x.Client).FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; } public List GetFilteredList(OrderSearchModel model) { - if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue) + if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue) { return new(); } using var context = new CarpentryWorkshopDatabase(); return context.Orders - .Where(x => x.Id == model.Id || model.DateFrom <= x.DateCreate && x.DateCreate <= model.DateTo) + .Where(x => x.Id == model.Id || model.DateFrom <= x.DateCreate && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId) .Include(x => x.Wood) + .Include(x => x.Client) .Select(x => x.GetViewModel) .ToList(); } @@ -36,7 +37,7 @@ namespace CarpentryWorkshopDatabaseImplement.Implements public List GetFullList() { using var context = new CarpentryWorkshopDatabase(); - return context.Orders.Include(x => x.Wood).Select(x => x.GetViewModel).ToList(); + return context.Orders.Include(x => x.Wood).Include(x => x.Client).Select(x => x.GetViewModel).ToList(); ; } public OrderViewModel? Insert(OrderBindingModel model) @@ -49,7 +50,7 @@ namespace CarpentryWorkshopDatabaseImplement.Implements using var context = new CarpentryWorkshopDatabase(); context.Orders.Add(newOrder); context.SaveChanges(); - return context.Orders.Include(x => x.Wood).FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel; + return context.Orders.Include(x => x.Wood).Include(x => x.Client).FirstOrDefault(x => x.Id == newOrder.Id)?.GetViewModel; } public OrderViewModel? Update(OrderBindingModel model) @@ -62,7 +63,7 @@ namespace CarpentryWorkshopDatabaseImplement.Implements } order.Update(model); context.SaveChanges(); - return context.Orders.Include(x => x.Wood).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; + return context.Orders.Include(x => x.Wood).Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; } public OrderViewModel? Delete(OrderBindingModel model) { diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.Designer.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.Designer.cs new file mode 100644 index 0000000..02381f2 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.Designer.cs @@ -0,0 +1,214 @@ +// +using System; +using CarpentryWorkshopDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace CarpentryWorkshopDatabaseImplement.Migrations +{ + [DbContext(typeof(CarpentryWorkshopDatabase))] + [Migration("20240419085157_MbLab5")] + partial class MbLab5 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.17") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("DateImplement") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.Property("WoodId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("WoodId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Wood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("WoodName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Woods"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.WoodComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("WoodId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("WoodId"); + + b.ToTable("WoodComponents"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Order", b => + { + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Wood", "Wood") + .WithMany("Orders") + .HasForeignKey("WoodId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Client"); + + b.Navigation("Wood"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.WoodComponent", b => + { + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Component", "Component") + .WithMany("WoodComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Wood", "Wood") + .WithMany("Components") + .HasForeignKey("WoodId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Wood"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Component", b => + { + b.Navigation("WoodComponents"); + }); + + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Wood", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.cs new file mode 100644 index 0000000..ceaadb3 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/20240419085157_MbLab5.cs @@ -0,0 +1,69 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace CarpentryWorkshopDatabaseImplement.Migrations +{ + /// + public partial class MbLab5 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("DELETE FROM [dbo].[Orders]"); + migrationBuilder.AddColumn( + name: "ClientId", + table: "Orders", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ClientFIO = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + Password = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ClientId", + table: "Orders", + column: "ClientId"); + + migrationBuilder.AddForeignKey( + name: "FK_Orders_Clients_ClientId", + table: "Orders", + column: "ClientId", + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Orders_Clients_ClientId", + table: "Orders"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropIndex( + name: "IX_Orders_ClientId", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ClientId", + table: "Orders"); + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/CarpentryWorkshopDatabaseModelSnapshot.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/CarpentryWorkshopDatabaseModelSnapshot.cs index 912c18b..dae0eab 100644 --- a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/CarpentryWorkshopDatabaseModelSnapshot.cs +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Migrations/CarpentryWorkshopDatabaseModelSnapshot.cs @@ -22,6 +22,31 @@ namespace CarpentryWorkshopDatabaseImplement.Migrations SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -50,6 +75,9 @@ namespace CarpentryWorkshopDatabaseImplement.Migrations SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("ClientId") + .HasColumnType("int"); + b.Property("Count") .HasColumnType("int"); @@ -70,6 +98,8 @@ namespace CarpentryWorkshopDatabaseImplement.Migrations b.HasKey("Id"); + b.HasIndex("ClientId"); + b.HasIndex("WoodId"); b.ToTable("Orders"); @@ -123,12 +153,20 @@ namespace CarpentryWorkshopDatabaseImplement.Migrations modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Order", b => { + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.HasOne("CarpentryWorkshopDatabaseImplement.Models.Wood", "Wood") .WithMany("Orders") .HasForeignKey("WoodId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Client"); + b.Navigation("Wood"); }); @@ -151,6 +189,11 @@ namespace CarpentryWorkshopDatabaseImplement.Migrations b.Navigation("Wood"); }); + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("CarpentryWorkshopDatabaseImplement.Models.Component", b => { b.Navigation("WoodComponents"); diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Client.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Client.cs new file mode 100644 index 0000000..6c5386b --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Client.cs @@ -0,0 +1,59 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace CarpentryWorkshopDatabaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + + [Required] + public string ClientFIO { get; private set; } = string.Empty; + + [Required] + public string Email { get; private set; } = string.Empty; + + [Required] + public string Password { get; private set; } = string.Empty; + + [ForeignKey("ClientId")] + public virtual List Orders { get; set; } = new(); + + public static Client? Create(ClientBindingModel model) + { + if (model == null) + { + return null; + } + return new() + { + Id = model.Id, + ClientFIO = model.ClientFIO, + Email = model.Email, + Password = model.Password + }; + } + + public void Update(ClientBindingModel model) + { + if (model == null) + { + return; + } + ClientFIO = model.ClientFIO; + Email = model.Email; + Password = model.Password; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientFIO = ClientFIO, + Email = Email, + Password = Password, + }; + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Order.cs b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Order.cs index 94135d5..bcbd24c 100644 --- a/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Order.cs +++ b/CarpentryWorkshop/CarpentryWorkshopDatabaseImplement/Models/Order.cs @@ -11,7 +11,8 @@ namespace CarpentryWorkshopDatabaseImplement.Models public int Id { get; private set; } [Required] public int WoodId { get; private set; } - + [Required] + public int ClientId { get; private set; } [Required] public int Count { get; private set; } [Required] @@ -23,6 +24,7 @@ namespace CarpentryWorkshopDatabaseImplement.Models public DateTime? DateImplement { get; private set; } public virtual Wood Wood { get; private set; } + public virtual Client Client { get; set; } public static Order? Create(OrderBindingModel? model) { diff --git a/CarpentryWorkshop/CarpentryWorkshopFileImplement/DataFileSingleton.cs b/CarpentryWorkshop/CarpentryWorkshopFileImplement/DataFileSingleton.cs index 3d9819c..a0f6b03 100644 --- a/CarpentryWorkshop/CarpentryWorkshopFileImplement/DataFileSingleton.cs +++ b/CarpentryWorkshop/CarpentryWorkshopFileImplement/DataFileSingleton.cs @@ -9,9 +9,11 @@ namespace CarpentryWorkshopFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string WoodFileName = "Wood.xml"; + private readonly string ClientFileName = "Client.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Woods { get; private set; } + public List Clients { get; private set; } public static DataFileSingleton GetInstance() { if (instance == null) @@ -26,6 +28,8 @@ namespace CarpentryWorkshopFileImplement "Woods", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveClients() => SaveData(Clients, ClientFileName, + "Clients", x => x.GetXElement); private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => @@ -34,6 +38,8 @@ namespace CarpentryWorkshopFileImplement Wood.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + Clients = LoadData(ClientFileName, "Client", x => + Client.Create(x)!)!; } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) diff --git a/CarpentryWorkshop/CarpentryWorkshopFileImplement/Implements/ClientStorage.cs b/CarpentryWorkshop/CarpentryWorkshopFileImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..788ea99 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopFileImplement/Implements/ClientStorage.cs @@ -0,0 +1,81 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.StoragesContracts; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopFileImplement.Models; + +namespace CarpentryWorkshopFileImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataFileSingleton source; + public ClientStorage() + { + source = DataFileSingleton.GetInstance(); + } + + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) + { + return null; + } + return source.Clients + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email)) + { + return new(); + } + return source.Clients + .Where(x => x.Email.Contains(model.Email)) + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() + { + return source.Clients.Select(x => x.GetViewModel).ToList(); + } + + public ClientViewModel? Insert(ClientBindingModel model) + { + model.Id = source.Clients.Count > 0 ? source.Clients.Max(x => x.Id) + 1 : 1; + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + source.Clients.Add(newClient); + source.SaveClients(); + return newClient.GetViewModel; + } + + public ClientViewModel? Update(ClientBindingModel model) + { + var client = source.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + client.Update(model); + source.SaveClients(); + return client?.GetViewModel; + } + + public ClientViewModel? Delete(ClientBindingModel model) + { + var client = source.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + source.Clients.Remove(client); + source.SaveClients(); + return client?.GetViewModel; + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopFileImplement/Models/Client.cs b/CarpentryWorkshop/CarpentryWorkshopFileImplement/Models/Client.cs new file mode 100644 index 0000000..5c29975 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopFileImplement/Models/Client.cs @@ -0,0 +1,74 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopDataModels.Models; +using System.Xml.Linq; + +namespace CarpentryWorkshopFileImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + + public string ClientFIO { get; private set; } = string.Empty; + + public string Email { get; private set; } = string.Empty; + + public string Password { get; private set; } = string.Empty; + + public static Client? Create(ClientBindingModel model) + { + if (model == null) + { + return null; + } + return new() + { + Id = model.Id, + ClientFIO = model.ClientFIO, + Email = model.Email, + Password = model.Password + }; + } + public static Client? Create(XElement element) + { + if (element == null) + { + return null; + } + return new() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ClientFIO = element.Element("FIO")!.Value, + Email = element.Element("Email")!.Value, + Password = element.Element("Password")!.Value, + }; + } + + + public void Update(ClientBindingModel model) + { + if (model == null) + { + return; + } + ClientFIO = model.ClientFIO; + Email = model.Email; + Password = model.Password; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientFIO = ClientFIO, + Email = Email, + Password = Password, + }; + + public XElement GetXElement => new("Client", + new XAttribute("Id", Id), + new XElement("FIO", ClientFIO), + new XElement("Email", Email), + new XElement("Password", Password) + ); + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopListImplement/DataListSingleton.cs b/CarpentryWorkshop/CarpentryWorkshopListImplement/DataListSingleton.cs index 9813b2a..41c3e5e 100644 --- a/CarpentryWorkshop/CarpentryWorkshopListImplement/DataListSingleton.cs +++ b/CarpentryWorkshop/CarpentryWorkshopListImplement/DataListSingleton.cs @@ -8,11 +8,13 @@ namespace CarpentryWorkshopListImplement public List Components { get; set; } public List Orders { get; set; } public List Woods { get; set; } + public List Clients { get; set; } private DataListSingleton() { Components = new List(); Orders = new List(); Woods = new List(); + Clients = new List(); } public static DataListSingleton GetInstance() { diff --git a/CarpentryWorkshop/CarpentryWorkshopListImplement/Implements/ClientStorage.cs b/CarpentryWorkshop/CarpentryWorkshopListImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..34687a4 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopListImplement/Implements/ClientStorage.cs @@ -0,0 +1,99 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.SearchModels; +using CarpentryWorkshopContracts.StoragesContracts; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopListImplement.Models; + +namespace CarpentryWorkshopListImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataListSingleton _source; + public ClientStorage() + { + _source = DataListSingleton.GetInstance(); + } + + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) + { + return null; + } + foreach (var client in _source.Clients) + { + if ((!string.IsNullOrEmpty(model.Email) && client.Email == model.Email) || (model.Id.HasValue && client.Id == model.Id)) + { + return client.GetViewModel; + } + } + return null; + } + + public List GetFilteredList(ClientSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.Email)) + { + return result; + } + var client = GetElement(model); + if (client != null) result.Add(client); + return result; + } + + public List GetFullList() + { + var result = new List(); + foreach (var client in _source.Clients) + { + result.Add(client.GetViewModel); + } + return result; + } + + public ClientViewModel? Insert(ClientBindingModel model) + { + model.Id = 1; + foreach (var client in _source.Clients) + { + if (model.Id <= client.Id) + { + model.Id = client.Id + 1; + } + } + var res = Client.Create(model); + if (res != null) + { + _source.Clients.Add(res); + } + return res?.GetViewModel; + } + + public ClientViewModel? Update(ClientBindingModel model) + { + foreach (var client in _source.Clients) + { + if (client.Id == model.Id) + { + client.Update(model); + return client.GetViewModel; + } + } + return null; + } + public ClientViewModel? Delete(ClientBindingModel model) + { + for (int i = 0; i < _source.Clients.Count; ++i) + { + if (_source.Clients[i].Id == model.Id) + { + var element = _source.Clients[i]; + _source.Clients.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopListImplement/Models/Client.cs b/CarpentryWorkshop/CarpentryWorkshopListImplement/Models/Client.cs new file mode 100644 index 0000000..57588d7 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopListImplement/Models/Client.cs @@ -0,0 +1,51 @@ +using CarpentryWorkshopContracts.BindingModels; +using CarpentryWorkshopContracts.ViewModels; +using CarpentryWorkshopDataModels.Models; + +namespace CarpentryWorkshopListImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + + public string ClientFIO { get; private set; } = string.Empty; + + public string Email { get; private set; } = string.Empty; + + public string Password { get; private set; } = string.Empty; + + public static Client? Create(ClientBindingModel model) + { + if (model == null) + { + return null; + } + return new() + { + Id = model.Id, + ClientFIO = model.ClientFIO, + Email = model.Email, + Password = model.Password + }; + } + + public void Update(ClientBindingModel model) + { + if (model == null) + { + return; + } + ClientFIO = model.ClientFIO; + Email = model.Email; + Password = model.Password; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientFIO = ClientFIO, + Email = Email, + Password = Password, + }; + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/CarpentryWorkshopRestApi.csproj b/CarpentryWorkshop/CarpentryWorkshopRestApi/CarpentryWorkshopRestApi.csproj new file mode 100644 index 0000000..6cbf777 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/CarpentryWorkshopRestApi.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/Program.cs b/CarpentryWorkshop/CarpentryWorkshopRestApi/Program.cs new file mode 100644 index 0000000..f2ec57a --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/Program.cs @@ -0,0 +1,46 @@ +using CarpentryWorkshopBusinessLogic.BusinessLogics; +using CarpentryWorkshopContracts.BusinessLogicsContracts; +using CarpentryWorkshopContracts.StoragesContracts; +using CarpentryWorkshopDatabaseImplement.Implements; + +using Microsoft.OpenApi.Models; + +var builder = WebApplication.CreateBuilder(args); +builder.Logging.SetMinimumLevel(LogLevel.Trace); +builder.Logging.AddLog4Net("log4net.config"); +// Add services to the container. +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at +https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo + { + Title = "CarpentryWorkshopRestApi", + Version = "v1" + }); +}); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CarpentryWorkshopRestApi v1")); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/Properties/launchSettings.json b/CarpentryWorkshop/CarpentryWorkshopRestApi/Properties/launchSettings.json new file mode 100644 index 0000000..a47e038 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:58874", + "sslPort": 44387 + } + }, + "profiles": { + "CarpentryWorkshopRestApi": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7115;http://localhost:5073", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.Development.json b/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.json b/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/CarpentryWorkshop/CarpentryWorkshopRestApi/log4net.config b/CarpentryWorkshop/CarpentryWorkshopRestApi/log4net.config new file mode 100644 index 0000000..0495745 --- /dev/null +++ b/CarpentryWorkshop/CarpentryWorkshopRestApi/log4net.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file