From 54321a5daa14d9f47558282498e2d83559bb5f6b Mon Sep 17 00:00:00 2001 From: "ityurner02@mail.ru" Date: Tue, 4 Apr 2023 19:52:14 +0400 Subject: [PATCH] =?UTF-8?q?1=20=D1=8D=D1=82=D0=B0=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlumbingRepair/FormClients.Designer.cs | 94 ++++++++ PlumbingRepair/PlumbingRepair/FormClients.cs | 69 ++++++ .../PlumbingRepair/FormClients.resx | 120 ++++++++++ .../PlumbingRepair/FormMain.Designer.cs | 11 +- PlumbingRepair/PlumbingRepair/FormMain.cs | 35 ++- PlumbingRepair/PlumbingRepair/Program.cs | 3 + .../BusinessLogic/ClientLogic.cs | 111 +++++++++ .../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 + .../Models/IOrderModel.cs | 1 + .../Implements/ClientStorage.cs | 91 ++++++++ .../Implements/OrderStorage.cs | 61 ++++- .../20230404151520_WithClient.Designer.cs | 218 ++++++++++++++++++ .../Migrations/20230404151520_WithClient.cs | 69 ++++++ .../PlumbingRepairDataBaseModelSnapshot.cs | 43 ++++ .../Models/Client.cs | 52 +++++ .../Models/Order.cs | 6 + .../PlumbingRepairDataBase.cs | 1 + .../DataListSingleton.cs | 2 + .../Implements/ClientStorage.cs | 109 +++++++++ .../Implements/OrderStorage.cs | 20 +- .../Models/Client.cs | 45 ++++ .../Models/Order.cs | 8 +- .../DataFileSingleton.cs | 4 + .../Implements/ClientStorage.cs | 82 +++++++ .../Implements/OrderStorage.cs | 26 ++- .../Models/Client.cs | 65 ++++++ .../Models/Order.cs | 10 +- 35 files changed, 1384 insertions(+), 55 deletions(-) create mode 100644 PlumbingRepair/PlumbingRepair/FormClients.Designer.cs create mode 100644 PlumbingRepair/PlumbingRepair/FormClients.cs create mode 100644 PlumbingRepair/PlumbingRepair/FormClients.resx create mode 100644 PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogic/ClientLogic.cs create mode 100644 PlumbingRepair/PlumbingRepairContracts/BindingModels/ClientBindingModel.cs create mode 100644 PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IClientLogic.cs create mode 100644 PlumbingRepair/PlumbingRepairContracts/SearchModels/ClientSearchModel.cs create mode 100644 PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IClientStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairContracts/ViewModels/ClientViewModel.cs create mode 100644 PlumbingRepair/PlumbingRepairDataModels/Models/IClientModel.cs create mode 100644 PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/ClientStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.Designer.cs create mode 100644 PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.cs create mode 100644 PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Client.cs create mode 100644 PlumbingRepair/PlumbingRepairListImplement/Implements/ClientStorage.cs create mode 100644 PlumbingRepair/PlumbingRepairListImplement/Models/Client.cs create mode 100644 PlumbingRepair/PlumpingRepairFileImplement/Implements/ClientStorage.cs create mode 100644 PlumbingRepair/PlumpingRepairFileImplement/Models/Client.cs diff --git a/PlumbingRepair/PlumbingRepair/FormClients.Designer.cs b/PlumbingRepair/PlumbingRepair/FormClients.Designer.cs new file mode 100644 index 0000000..ac1925b --- /dev/null +++ b/PlumbingRepair/PlumbingRepair/FormClients.Designer.cs @@ -0,0 +1,94 @@ +namespace PlumbingRepair +{ + 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() + { + this.dataGridView = new System.Windows.Forms.DataGridView(); + this.buttonDel = new System.Windows.Forms.Button(); + this.buttonRef = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); + this.SuspendLayout(); + // + // dataGridView + // + this.dataGridView.AllowUserToAddRows = false; + this.dataGridView.AllowUserToDeleteRows = false; + this.dataGridView.BackgroundColor = System.Drawing.SystemColors.ControlLightLight; + this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView.Dock = System.Windows.Forms.DockStyle.Left; + this.dataGridView.Location = new System.Drawing.Point(0, 0); + this.dataGridView.Name = "dataGridView"; + this.dataGridView.ReadOnly = true; + this.dataGridView.RowHeadersVisible = false; + this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dataGridView.Size = new System.Drawing.Size(350, 312); + this.dataGridView.TabIndex = 0; + // + // buttonDel + // + this.buttonDel.Location = new System.Drawing.Point(368, 12); + this.buttonDel.Name = "buttonDel"; + this.buttonDel.Size = new System.Drawing.Size(75, 23); + this.buttonDel.TabIndex = 3; + this.buttonDel.Text = "Удалить"; + this.buttonDel.UseVisualStyleBackColor = true; + this.buttonDel.Click += new System.EventHandler(this.ButtonDel_Click); + // + // buttonRef + // + this.buttonRef.Location = new System.Drawing.Point(368, 53); + this.buttonRef.Name = "buttonRef"; + this.buttonRef.Size = new System.Drawing.Size(75, 23); + this.buttonRef.TabIndex = 4; + this.buttonRef.Text = "Обновить"; + this.buttonRef.UseVisualStyleBackColor = true; + this.buttonRef.Click += new System.EventHandler(this.ButtonRef_Click); + // + // FormClients + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(464, 312); + this.Controls.Add(this.buttonRef); + this.Controls.Add(this.buttonDel); + this.Controls.Add(this.dataGridView); + this.Name = "FormClients"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Клиенты"; + this.Load += new System.EventHandler(this.FormClients_Load); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.DataGridView dataGridView; + private System.Windows.Forms.Button buttonDel; + private System.Windows.Forms.Button buttonRef; + } +} \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepair/FormClients.cs b/PlumbingRepair/PlumbingRepair/FormClients.cs new file mode 100644 index 0000000..e1ce341 --- /dev/null +++ b/PlumbingRepair/PlumbingRepair/FormClients.cs @@ -0,0 +1,69 @@ +using Microsoft.Extensions.Logging; +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.BusinessLogicsContracts; + +namespace PlumbingRepair +{ + 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("Загрузка клиентов"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка загрузки клиентов"); + 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); + try + { + if (!_logic.Delete(new ClientBindingModel { Id = id })) + { + throw new Exception("Ошибка при удалении. Дополнительная информация в логах."); + } + _logger.LogInformation("Удаление клиента"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления клиента"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + LoadData(); + } + } + } + private void ButtonRef_Click(object sender, EventArgs e) + { + LoadData(); + } + } +} diff --git a/PlumbingRepair/PlumbingRepair/FormClients.resx b/PlumbingRepair/PlumbingRepair/FormClients.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/PlumbingRepair/PlumbingRepair/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/PlumbingRepair/PlumbingRepair/FormMain.Designer.cs b/PlumbingRepair/PlumbingRepair/FormMain.Designer.cs index 8881750..2bd0bce 100644 --- a/PlumbingRepair/PlumbingRepair/FormMain.Designer.cs +++ b/PlumbingRepair/PlumbingRepair/FormMain.Designer.cs @@ -32,6 +32,7 @@ СправочникиToolStripMenuItem = new ToolStripMenuItem(); ИзделияToolStripMenuItem = new ToolStripMenuItem(); КомпонентыToolStripMenuItem = new ToolStripMenuItem(); + КлиентыToolStripMenuItem = new ToolStripMenuItem(); отчетыToolStripMenuItem = new ToolStripMenuItem(); WorksToolStripMenuItem = new ToolStripMenuItem(); WorkComponentToolStripMenuItem = new ToolStripMenuItem(); @@ -59,7 +60,7 @@ // // СправочникиToolStripMenuItem // - СправочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ИзделияToolStripMenuItem, КомпонентыToolStripMenuItem }); + СправочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ИзделияToolStripMenuItem, КомпонентыToolStripMenuItem, КлиентыToolStripMenuItem }); СправочникиToolStripMenuItem.Name = "СправочникиToolStripMenuItem"; СправочникиToolStripMenuItem.Size = new Size(117, 24); СправочникиToolStripMenuItem.Text = "Cправочники"; @@ -78,6 +79,13 @@ КомпонентыToolStripMenuItem.Text = "Компоненты"; КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; // + // КлиентыToolStripMenuItem + // + КлиентыToolStripMenuItem.Name = "КлиентыToolStripMenuItem"; + КлиентыToolStripMenuItem.Size = new Size(182, 26); + КлиентыToolStripMenuItem.Text = "Клиенты"; + КлиентыToolStripMenuItem.Click += КлиентыToolStripMenuItem_Click; + // // отчетыToolStripMenuItem // отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { WorksToolStripMenuItem, WorkComponentToolStripMenuItem, OrdersToolStripMenuItem }); @@ -202,6 +210,7 @@ private ToolStripMenuItem СправочникиToolStripMenuItem; private ToolStripMenuItem ИзделияToolStripMenuItem; private ToolStripMenuItem КомпонентыToolStripMenuItem; + private ToolStripMenuItem КлиентыToolStripMenuItem; private DataGridView DataGridView; private Button CreateOrderButton; private Button TakeOrderInWorkButton; diff --git a/PlumbingRepair/PlumbingRepair/FormMain.cs b/PlumbingRepair/PlumbingRepair/FormMain.cs index dfbb423..e13fdd4 100644 --- a/PlumbingRepair/PlumbingRepair/FormMain.cs +++ b/PlumbingRepair/PlumbingRepair/FormMain.cs @@ -3,6 +3,7 @@ using PlumbingRepairBusinessLogic.BusinessLogic; using PlumbingRepairContracts.BindingModels; using PlumbingRepairContracts.BusinessLogicsContracts; using PlumbingRepairDataModels.Enums; +using System.Windows.Forms; namespace PlumbingRepair { @@ -37,6 +38,8 @@ namespace PlumbingRepair { DataGridView.DataSource = list; DataGridView.Columns["WorkId"].Visible = false; + DataGridView.Columns["ClientId"].Visible = false; + DataGridView.Columns["DateImplement"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } _logger.LogInformation("Загрузка заказов"); @@ -67,6 +70,14 @@ namespace PlumbingRepair 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 CreateOrderButton_Click(object sender, EventArgs e) { @@ -90,13 +101,7 @@ namespace PlumbingRepair { var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { - Id = id, - WorkId = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["WorkId"].Value), - WorkName = DataGridView.SelectedRows[0].Cells["WorkName"].Value.ToString(), - Status = Enum.Parse(DataGridView.SelectedRows[0].Cells["Status"].Value.ToString()), - Count = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Count"].Value), - Sum = double.Parse(DataGridView.SelectedRows[0].Cells["Sum"].Value.ToString()), - DateCreate = DateTime.Parse(DataGridView.SelectedRows[0].Cells["DateCreate"].Value.ToString()), + Id = id }); if (!operationResult) @@ -125,13 +130,7 @@ namespace PlumbingRepair { var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { - Id = id, - WorkId = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["WorkId"].Value), - WorkName = DataGridView.SelectedRows[0].Cells["WorkName"].Value.ToString(), - Status = Enum.Parse(DataGridView.SelectedRows[0].Cells["Status"].Value.ToString()), - Count = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Count"].Value), - Sum = double.Parse(DataGridView.SelectedRows[0].Cells["Sum"].Value.ToString()), - DateCreate = DateTime.Parse(DataGridView.SelectedRows[0].Cells["DateCreate"].Value.ToString()), + Id = id }); if (!operationResult) @@ -160,13 +159,7 @@ namespace PlumbingRepair { var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { - Id = id, - WorkId = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["WorkId"].Value), - WorkName = DataGridView.SelectedRows[0].Cells["WorkName"].Value.ToString(), - Status = Enum.Parse(DataGridView.SelectedRows[0].Cells["Status"].Value.ToString()), - Count = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Count"].Value), - Sum = double.Parse(DataGridView.SelectedRows[0].Cells["Sum"].Value.ToString()), - DateCreate = DateTime.Parse(DataGridView.SelectedRows[0].Cells["DateCreate"].Value.ToString()), + Id = id }); if (!operationResult) diff --git a/PlumbingRepair/PlumbingRepair/Program.cs b/PlumbingRepair/PlumbingRepair/Program.cs index 343fd1a..36bc9dc 100644 --- a/PlumbingRepair/PlumbingRepair/Program.cs +++ b/PlumbingRepair/PlumbingRepair/Program.cs @@ -38,9 +38,11 @@ namespace PlumbingRepair services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -54,6 +56,7 @@ namespace PlumbingRepair services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogic/ClientLogic.cs b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogic/ClientLogic.cs new file mode 100644 index 0000000..3d606d5 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairBusinessLogic/BusinessLogic/ClientLogic.cs @@ -0,0 +1,111 @@ +using Microsoft.Extensions.Logging; +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.BusinessLogicsContracts; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; + +namespace PlumbingRepairBusinessLogic.BusinessLogic +{ + public class ClientLogic : IClientLogic + { + private readonly ILogger _logger; + private readonly IClientStorage _clientStorage; + public ClientLogic(ILogger logger, IClientStorage clientStorage) + { + _logger = logger; + _clientStorage = clientStorage; + } + public List? ReadList(ClientSearchModel? model) + { + _logger.LogInformation("ReadList. ClientFIO:{ClientFIO}. Id:{Id}", model?.ClientFIO, 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; + } + public ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientFIO:{ClientFIO}. Id:{Id}", model.ClientFIO, 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 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; + } + 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.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Нет пароля учетной записи клиента", nameof(model.ClientFIO)); + } + _logger.LogInformation("Client. ClientFIO:{ClientFIO}. Email:{Email}. Password:{Password}. Id:{Id}", model.ClientFIO, model.Email, model.Password, model.Id); + var element = _clientStorage.GetElement(new ClientSearchModel + { + Email = model.Email + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Клиент с таким логином уже есть"); + } + } + } +} diff --git a/PlumbingRepair/PlumbingRepairContracts/BindingModels/ClientBindingModel.cs b/PlumbingRepair/PlumbingRepairContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..ba3cef0 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,12 @@ +using PlumbingRepairDataModels.Models; + +namespace PlumbingRepairContracts.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/PlumbingRepair/PlumbingRepairContracts/BindingModels/OrderBindingModel.cs b/PlumbingRepair/PlumbingRepairContracts/BindingModels/OrderBindingModel.cs index 2450a64..541b689 100644 --- a/PlumbingRepair/PlumbingRepairContracts/BindingModels/OrderBindingModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/BindingModels/OrderBindingModel.cs @@ -7,6 +7,7 @@ namespace PlumbingRepairContracts.BindingModels { public int Id { get; set; } public int WorkId { 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/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IClientLogic.cs b/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IClientLogic.cs new file mode 100644 index 0000000..3763ef1 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairContracts/BusinessLogicsContracts/IClientLogic.cs @@ -0,0 +1,15 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.ViewModels; + +namespace PlumbingRepairContracts.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/PlumbingRepair/PlumbingRepairContracts/SearchModels/ClientSearchModel.cs b/PlumbingRepair/PlumbingRepairContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..62abb37 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,10 @@ +namespace PlumbingRepairContracts.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/PlumbingRepair/PlumbingRepairContracts/SearchModels/OrderSearchModel.cs b/PlumbingRepair/PlumbingRepairContracts/SearchModels/OrderSearchModel.cs index 03848ad..558c523 100644 --- a/PlumbingRepair/PlumbingRepairContracts/SearchModels/OrderSearchModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/SearchModels/OrderSearchModel.cs @@ -3,6 +3,7 @@ public class OrderSearchModel { public int? Id { get; set; } + public int? ClientId { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } } diff --git a/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IClientStorage.cs b/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IClientStorage.cs new file mode 100644 index 0000000..d08d9f2 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairContracts/StoragesContracts/IClientStorage.cs @@ -0,0 +1,16 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.ViewModels; + +namespace PlumbingRepairContracts.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/PlumbingRepair/PlumbingRepairContracts/ViewModels/ClientViewModel.cs b/PlumbingRepair/PlumbingRepairContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..84ccc44 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,16 @@ +using PlumbingRepairDataModels.Models; +using System.ComponentModel; + +namespace PlumbingRepairContracts.ViewModels +{ + public class ClientViewModel : IClientModel + { + public int Id { get; set; } + [DisplayName("ФИО клиента")] + public string ClientFIO { get; set; } = string.Empty; + [DisplayName("Логин (эл. почта)")] + public string Email { get; set; } = string.Empty; + [DisplayName("Пароль")] + public string Password { get; set; } = string.Empty; + } +} diff --git a/PlumbingRepair/PlumbingRepairContracts/ViewModels/OrderViewModel.cs b/PlumbingRepair/PlumbingRepairContracts/ViewModels/OrderViewModel.cs index 801613c..1a6f8ce 100644 --- a/PlumbingRepair/PlumbingRepairContracts/ViewModels/OrderViewModel.cs +++ b/PlumbingRepair/PlumbingRepairContracts/ViewModels/OrderViewModel.cs @@ -11,6 +11,9 @@ namespace PlumbingRepairContracts.ViewModels public int WorkId { get; set; } [DisplayName("Название изделия")] public string WorkName { 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/PlumbingRepair/PlumbingRepairDataModels/Models/IClientModel.cs b/PlumbingRepair/PlumbingRepairDataModels/Models/IClientModel.cs new file mode 100644 index 0000000..58dbd60 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairDataModels/Models/IClientModel.cs @@ -0,0 +1,9 @@ +namespace PlumbingRepairDataModels.Models +{ + public interface IClientModel : IId + { + string ClientFIO { get; } + string Email { get; } + string Password { get; } + } +} diff --git a/PlumbingRepair/PlumbingRepairDataModels/Models/IOrderModel.cs b/PlumbingRepair/PlumbingRepairDataModels/Models/IOrderModel.cs index 96c83f4..113b612 100644 --- a/PlumbingRepair/PlumbingRepairDataModels/Models/IOrderModel.cs +++ b/PlumbingRepair/PlumbingRepairDataModels/Models/IOrderModel.cs @@ -5,6 +5,7 @@ namespace PlumbingRepairDataModels.Models public interface IOrderModel : IId { int WorkId { get; } + int ClientId { get; } string WorkName { get; } int Count { get; } double Sum { get; } diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/ClientStorage.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..b2a6b8e --- /dev/null +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,91 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace PlumbingRepairDatabaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public List GetFullList() + { + using var context = new PlumbingRepairDataBase(); + return context.Clients + .Include(x => x.Orders) + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel model) + { + if (model == null) + { + return new(); + } + if (!string.IsNullOrEmpty(model.Email)) + { + using var context = new PlumbingRepairDataBase(); + return context.Clients + .Include(x => x.Orders) + .Where(x => x.Email.Contains(model.Email)) + .Select(x => x.GetViewModel) + .ToList(); + } + return new(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + using var context = new PlumbingRepairDataBase(); + if (model.Id.HasValue) + { + return context.Clients + .FirstOrDefault(x => (x.Id == model.Id))?.GetViewModel; + } + else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password)) + { + return context.Clients + .FirstOrDefault(x => (x.Email == model.Email && x.Password == model.Password))?.GetViewModel; + } + return new(); + } + public ClientViewModel? Insert(ClientBindingModel model) + { + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + using var context = new PlumbingRepairDataBase(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new PlumbingRepairDataBase(); + 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 PlumbingRepairDataBase(); + var element = context.Clients + .Include(x => x.Orders) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Clients.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/OrderStorage.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/OrderStorage.cs index 3e51188..41f3db4 100644 --- a/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/OrderStorage.cs +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Implements/OrderStorage.cs @@ -1,4 +1,5 @@ -using PlumbingRepairContracts.BindingModels; +using Microsoft.EntityFrameworkCore; +using PlumbingRepairContracts.BindingModels; using PlumbingRepairContracts.SearchModels; using PlumbingRepairContracts.StoragesContracts; using PlumbingRepairContracts.ViewModels; @@ -12,24 +13,45 @@ namespace PlumbingRepairDatabaseImplement.Implements { using var context = new PlumbingRepairDataBase(); - return context.Orders.Select(x => x.GetViewModel).ToList(); + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .Select(x => x.GetViewModel) + .ToList(); } public List GetFilteredList(OrderSearchModel model) { - if (model is null) - return new(); - using var context = new PlumbingRepairDataBase(); - if (!model.Id.HasValue) + if (model.Id.HasValue) { return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .Where(x => x.Id == model.Id) + .Select(x => x.GetViewModel) + .ToList(); + } + else if (model.DateFrom != null && model.DateTo != null) + { + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) .Select(x => x.GetViewModel) .ToList(); } + else if (model.ClientId.HasValue) + { + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .Where(x => x.ClientId == model.ClientId) + .Select(x => x.GetViewModel) + .ToList(); + } - return context.Orders.Where(x => x.Id == model.Id).Select(x => x.GetViewModel).ToList(); + return new(); } public OrderViewModel? GetElement(OrderSearchModel model) @@ -41,7 +63,11 @@ namespace PlumbingRepairDatabaseImplement.Implements using var context = new PlumbingRepairDataBase(); - return context.Orders.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) + ?.GetViewModel; } public OrderViewModel? Insert(OrderBindingModel model) @@ -58,7 +84,11 @@ namespace PlumbingRepairDatabaseImplement.Implements context.Orders.Add(newOrder); context.SaveChanges(); - return newOrder.GetViewModel; + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .FirstOrDefault(x => x.Id == newOrder.Id) + ?.GetViewModel; } public OrderViewModel? Update(OrderBindingModel model) @@ -75,7 +105,11 @@ namespace PlumbingRepairDatabaseImplement.Implements order.Update(model); context.SaveChanges(); - return order.GetViewModel; + return context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .FirstOrDefault(x => x.Id == model.Id) + ?.GetViewModel; } public OrderViewModel? Delete(OrderBindingModel model) @@ -86,10 +120,15 @@ namespace PlumbingRepairDatabaseImplement.Implements if (element != null) { + var deletedElement = context.Orders + .Include(x => x.Work) + .Include(x => x.Client) + .FirstOrDefault(x => x.Id == model.Id) + ?.GetViewModel; context.Orders.Remove(element); context.SaveChanges(); - return element.GetViewModel; + return deletedElement; } return null; diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.Designer.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.Designer.cs new file mode 100644 index 0000000..a554234 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.Designer.cs @@ -0,0 +1,218 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using PlumbingRepairDatabaseImplement; + +#nullable disable + +namespace PlumbingRepairDatabaseImplement.Migrations +{ + [DbContext(typeof(PlumbingRepairDataBase))] + [Migration("20230404151520_WithClient")] + partial class WithClient + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp with time zone"); + + b.Property("DateImplement") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.Property("WorkId") + .HasColumnType("integer"); + + b.Property("WorkName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("WorkId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Work", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Price") + .HasColumnType("double precision"); + + b.Property("WorkName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Works"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.WorkComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("WorkId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("WorkId"); + + b.ToTable("WorkComponents"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Order", b => + { + b.HasOne("PlumbingRepairDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("PlumbingRepairDatabaseImplement.Models.Work", "Work") + .WithMany("Orders") + .HasForeignKey("WorkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Client"); + + b.Navigation("Work"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.WorkComponent", b => + { + b.HasOne("PlumbingRepairDatabaseImplement.Models.Component", "Component") + .WithMany("WorkComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("PlumbingRepairDatabaseImplement.Models.Work", "Work") + .WithMany("Components") + .HasForeignKey("WorkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Work"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Component", b => + { + b.Navigation("WorkComponents"); + }); + + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Work", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.cs new file mode 100644 index 0000000..1602a56 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/20230404151520_WithClient.cs @@ -0,0 +1,69 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace PlumbingRepairDatabaseImplement.Migrations +{ + /// + public partial class WithClient : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ClientId", + table: "Orders", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ClientFIO = table.Column(type: "text", nullable: false), + Email = table.Column(type: "text", nullable: false), + Password = table.Column(type: "text", 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/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/PlumbingRepairDataBaseModelSnapshot.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/PlumbingRepairDataBaseModelSnapshot.cs index a8fcca6..c29dfce 100644 --- a/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/PlumbingRepairDataBaseModelSnapshot.cs +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Migrations/PlumbingRepairDataBaseModelSnapshot.cs @@ -22,6 +22,31 @@ namespace PlumbingRepairDatabaseImplement.Migrations NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Component", b => { b.Property("Id") @@ -50,6 +75,9 @@ namespace PlumbingRepairDatabaseImplement.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("ClientId") + .HasColumnType("integer"); + b.Property("Count") .HasColumnType("integer"); @@ -74,6 +102,8 @@ namespace PlumbingRepairDatabaseImplement.Migrations b.HasKey("Id"); + b.HasIndex("ClientId"); + b.HasIndex("WorkId"); b.ToTable("Orders"); @@ -127,12 +157,20 @@ namespace PlumbingRepairDatabaseImplement.Migrations modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Order", b => { + b.HasOne("PlumbingRepairDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.HasOne("PlumbingRepairDatabaseImplement.Models.Work", "Work") .WithMany("Orders") .HasForeignKey("WorkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Client"); + b.Navigation("Work"); }); @@ -155,6 +193,11 @@ namespace PlumbingRepairDatabaseImplement.Migrations b.Navigation("Work"); }); + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + modelBuilder.Entity("PlumbingRepairDatabaseImplement.Models.Component", b => { b.Navigation("WorkComponents"); diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Client.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Client.cs new file mode 100644 index 0000000..79e7c73 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Client.cs @@ -0,0 +1,52 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace PlumbingRepairDatabaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; set; } + [Required] + public string ClientFIO { get; set; } = string.Empty; + [Required] + public string Email { get; set; } = string.Empty; + [Required] + public string Password { get; 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 Client() + { + 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/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Order.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Order.cs index 8e1821a..0a967a1 100644 --- a/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Order.cs +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/Models/Order.cs @@ -13,6 +13,8 @@ namespace PlumbingRepairDatabaseImplement.Models public int WorkId { get; private set; } public string WorkName { get; private set; } = string.Empty; + [Required] + public int ClientId { get; private set; } [Required] public int Count { get; private set; } @@ -29,6 +31,7 @@ namespace PlumbingRepairDatabaseImplement.Models public DateTime? DateImplement { get; private set; } public virtual Work Work { get; set; } + public virtual Client Client { get; set; } public static Order? Create(OrderBindingModel? model) { @@ -42,6 +45,7 @@ namespace PlumbingRepairDatabaseImplement.Models Id = model.Id, WorkId = model.WorkId, WorkName = model.WorkName, + ClientId = model.ClientId, Count = model.Count, Sum = model.Sum, Status = model.Status, @@ -66,6 +70,8 @@ namespace PlumbingRepairDatabaseImplement.Models Id = Id, WorkId = WorkId, WorkName = WorkName, + ClientId = ClientId, + ClientFIO = Client.ClientFIO, Count = Count, Sum = Sum, Status = Status, diff --git a/PlumbingRepair/PlumbingRepairDatabaseImplement/PlumbingRepairDataBase.cs b/PlumbingRepair/PlumbingRepairDatabaseImplement/PlumbingRepairDataBase.cs index 76df650..dc6bfb6 100644 --- a/PlumbingRepair/PlumbingRepairDatabaseImplement/PlumbingRepairDataBase.cs +++ b/PlumbingRepair/PlumbingRepairDatabaseImplement/PlumbingRepairDataBase.cs @@ -17,5 +17,6 @@ namespace PlumbingRepairDatabaseImplement public virtual DbSet Works { set; get; } public virtual DbSet WorkComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Clients { set; get; } } } diff --git a/PlumbingRepair/PlumbingRepairListImplement/DataListSingleton.cs b/PlumbingRepair/PlumbingRepairListImplement/DataListSingleton.cs index 2a6b2e0..c058534 100644 --- a/PlumbingRepair/PlumbingRepairListImplement/DataListSingleton.cs +++ b/PlumbingRepair/PlumbingRepairListImplement/DataListSingleton.cs @@ -8,12 +8,14 @@ namespace PlumbingRepairListImplement public List Components { get; set; } public List Orders { get; set; } public List Works { get; set; } + public List Clients { get; set; } private DataListSingleton() { Components = new List(); Orders = new List(); Works = new List(); + Clients = new List(); } public static DataListSingleton GetInstance() diff --git a/PlumbingRepair/PlumbingRepairListImplement/Implements/ClientStorage.cs b/PlumbingRepair/PlumbingRepairListImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..f86153e --- /dev/null +++ b/PlumbingRepair/PlumbingRepairListImplement/Implements/ClientStorage.cs @@ -0,0 +1,109 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairListImplement.Models; + +namespace PlumbingRepairListImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataListSingleton _source; + public ClientStorage() + { + _source = DataListSingleton.GetInstance(); + } + public List GetFullList() + { + var result = new List(); + foreach (var client in _source.Clients) + { + result.Add(client.GetViewModel); + } + return result; + } + public List GetFilteredList(ClientSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.Email)) + { + return result; + } + foreach (var client in _source.Clients) + { + if (client.Email.Contains(model.Email)) + { + result.Add(client.GetViewModel); + } + } + return result; + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (model.Id.HasValue) + { + foreach (var client in _source.Clients) + { + if (client.Id == model.Id) + { + return client.GetViewModel; + } + } + } + else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password)) + { + foreach (var client in _source.Clients) + { + if (client.Email == model.Email && client.Password == model.Password) + { + return client.GetViewModel; + } + } + } + return null; + } + 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 newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + _source.Clients.Add(newClient); + return newClient.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/PlumbingRepair/PlumbingRepairListImplement/Implements/OrderStorage.cs b/PlumbingRepair/PlumbingRepairListImplement/Implements/OrderStorage.cs index 68fe461..5e7eabb 100644 --- a/PlumbingRepair/PlumbingRepairListImplement/Implements/OrderStorage.cs +++ b/PlumbingRepair/PlumbingRepairListImplement/Implements/OrderStorage.cs @@ -30,10 +30,19 @@ namespace PlumbingRepairListImplement.Implements public List GetFilteredList(OrderSearchModel model) { var result = new List(); - - if (!model.Id.HasValue || model.Id == 0) + if (model.Id.HasValue) { - foreach (Order order in _source.Orders) + foreach (var order in _source.Orders) + { + if (order.Id == model.Id) + { + result.Add(order.GetViewModel); + } + } + } + else if (model.DateFrom != null && model.DateTo != null) + { + foreach (var order in _source.Orders) { if (order.DateCreate >= model.DateFrom && order.DateCreate <= model.DateTo) { @@ -41,17 +50,16 @@ namespace PlumbingRepairListImplement.Implements } } } - else + else if (model.ClientId.HasValue) { foreach (var order in _source.Orders) { - if (model.Id.HasValue && order.Id == model.Id) + if (order.ClientId == model.ClientId) { result.Add(order.GetViewModel); } } } - return result; } diff --git a/PlumbingRepair/PlumbingRepairListImplement/Models/Client.cs b/PlumbingRepair/PlumbingRepairListImplement/Models/Client.cs new file mode 100644 index 0000000..6cee342 --- /dev/null +++ b/PlumbingRepair/PlumbingRepairListImplement/Models/Client.cs @@ -0,0 +1,45 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; + +namespace PlumbingRepairListImplement.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 Client() + { + 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/PlumbingRepair/PlumbingRepairListImplement/Models/Order.cs b/PlumbingRepair/PlumbingRepairListImplement/Models/Order.cs index ef3854f..0afff36 100644 --- a/PlumbingRepair/PlumbingRepairListImplement/Models/Order.cs +++ b/PlumbingRepair/PlumbingRepairListImplement/Models/Order.cs @@ -10,6 +10,7 @@ namespace PlumbingRepairListImplement.Models public int Id { get; private set; } public int WorkId { get; private set; } public string WorkName { get; private set; } + public int ClientId { get; private set; } public int Count { get; private set; } public double Sum { get; private set; } public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; @@ -27,6 +28,7 @@ namespace PlumbingRepairListImplement.Models Id = model.Id, WorkId = model.WorkId, WorkName = model.WorkName, + ClientId = model.ClientId, Count = model.Count, Sum = model.Sum, Status = model.Status, @@ -41,12 +43,7 @@ namespace PlumbingRepairListImplement.Models { return; } - WorkId = model.WorkId; - WorkName = model.WorkName; - Count = model.Count; - Sum = model.Sum; Status = model.Status; - DateCreate = model.DateCreate; DateImplement = model.DateImplement; } @@ -55,6 +52,7 @@ namespace PlumbingRepairListImplement.Models Id = Id, WorkId = WorkId, WorkName = WorkName, + ClientId = ClientId, Count = Count, Sum = Sum, Status = Status, diff --git a/PlumbingRepair/PlumpingRepairFileImplement/DataFileSingleton.cs b/PlumbingRepair/PlumpingRepairFileImplement/DataFileSingleton.cs index 2f5e914..f2df4f6 100644 --- a/PlumbingRepair/PlumpingRepairFileImplement/DataFileSingleton.cs +++ b/PlumbingRepair/PlumpingRepairFileImplement/DataFileSingleton.cs @@ -10,10 +10,12 @@ namespace PlumbingRepairFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string WorkFileName = "Work.xml"; + private readonly string ClientFileName = "Client.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Works { get; private set; } + public List Clients { get; private set; } public static DataFileSingleton GetInstance() { @@ -27,12 +29,14 @@ namespace PlumbingRepairFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveWorks() => SaveData(Works, WorkFileName, "Works", 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 => Component.Create(x)!)!; Works = LoadData(WorkFileName, "Work", x => Work.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/PlumbingRepair/PlumpingRepairFileImplement/Implements/ClientStorage.cs b/PlumbingRepair/PlumpingRepairFileImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..156384d --- /dev/null +++ b/PlumbingRepair/PlumpingRepairFileImplement/Implements/ClientStorage.cs @@ -0,0 +1,82 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.SearchModels; +using PlumbingRepairContracts.StoragesContracts; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairFileImplement.Models; + +namespace PlumbingRepairFileImplement.Implements +{ + public class ClientStorage : IClientStorage + { + private readonly DataFileSingleton source; + public ClientStorage() + { + source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return source.Clients + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel model) + { + if (!string.IsNullOrEmpty(model.Email)) + { + return source.Clients + .Where(x => x.Email.Contains(model.Email)) + .Select(x => x.GetViewModel) + .ToList(); + } + return new(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (model.Id.HasValue) + { + return source.Clients + .FirstOrDefault(x => (x.Id == model.Id))?.GetViewModel; + } + else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password)) + { + return source.Clients + .FirstOrDefault(x => (x.Email == model.Email && x.Password == model.Password))?.GetViewModel; + } + return new(); + } + 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) + { + source.Clients.Remove(client); + source.SaveClients(); + return client.GetViewModel; + } + return null; + } + } +} diff --git a/PlumbingRepair/PlumpingRepairFileImplement/Implements/OrderStorage.cs b/PlumbingRepair/PlumpingRepairFileImplement/Implements/OrderStorage.cs index 88ce242..d78f954 100644 --- a/PlumbingRepair/PlumpingRepairFileImplement/Implements/OrderStorage.cs +++ b/PlumbingRepair/PlumpingRepairFileImplement/Implements/OrderStorage.cs @@ -22,15 +22,29 @@ namespace PlumbingRepairFileImplement.Implements public List GetFilteredList(OrderSearchModel model) { - if (!model.Id.HasValue) + if (model.Id.HasValue) { return source.Orders - .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) - .Select(x => x.GetViewModel) - .ToList(); + .Where(x => x.Id == model.Id) + .Select(x => x.GetViewModel) + .ToList(); + } + else if (model.DateFrom != null && model.DateTo != null) + { + return source.Orders + .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) + .Select(x => x.GetViewModel) + .ToList(); + } + else if (model.ClientId.HasValue) + { + return source.Orders + .Where(x => x.ClientId == model.ClientId) + .Select(x => x.GetViewModel) + .ToList(); } - return source.Orders.Where(x => x.Id == model.Id).Select(x => x.GetViewModel).ToList(); + return new(); } public OrderViewModel? GetElement(OrderSearchModel model) @@ -74,7 +88,7 @@ namespace PlumbingRepairFileImplement.Implements return order.GetViewModel; } - public OrderViewModel? Delete(OrderBindingModel model) + public OrderViewModel? Delete(OrderBindingModel model) { var element = source.Orders.FirstOrDefault(x => x.Id == model.Id); diff --git a/PlumbingRepair/PlumpingRepairFileImplement/Models/Client.cs b/PlumbingRepair/PlumpingRepairFileImplement/Models/Client.cs new file mode 100644 index 0000000..64c154c --- /dev/null +++ b/PlumbingRepair/PlumpingRepairFileImplement/Models/Client.cs @@ -0,0 +1,65 @@ +using PlumbingRepairContracts.BindingModels; +using PlumbingRepairContracts.ViewModels; +using PlumbingRepairDataModels.Models; +using System.Xml.Linq; + +namespace PlumbingRepairFileImplement.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 Client() + { + 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 Client() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ClientFIO = element.Element("ClientFIO")!.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("ClientFIO", ClientFIO), + new XElement("Email", Email), + new XElement("Password", Password)); + } +} diff --git a/PlumbingRepair/PlumpingRepairFileImplement/Models/Order.cs b/PlumbingRepair/PlumpingRepairFileImplement/Models/Order.cs index 6dd1d40..7d2615c 100644 --- a/PlumbingRepair/PlumpingRepairFileImplement/Models/Order.cs +++ b/PlumbingRepair/PlumpingRepairFileImplement/Models/Order.cs @@ -10,6 +10,7 @@ namespace PlumbingRepairFileImplement.Models { public int Id { get; private set; } public int WorkId { get; private set; } + public int ClientId { get; private set; } public string WorkName { get; private set; } = string.Empty; public int Count { get; private set; } public double Sum { get; private set; } @@ -28,6 +29,7 @@ namespace PlumbingRepairFileImplement.Models Id = model.Id, WorkId = model.WorkId, WorkName = model.WorkName, + ClientId = model.ClientId, Count = model.Count, Sum = model.Sum, Status = model.Status, @@ -48,6 +50,7 @@ namespace PlumbingRepairFileImplement.Models Id = Convert.ToInt32(element.Attribute("Id")!.Value), WorkId = Convert.ToInt32(element.Element("WorkId")!.Value), WorkName = element.Element("WorkName")!.Value, + ClientId = Convert.ToInt32(element.Element("ClientId")!.Value), Count = Convert.ToInt32(element.Element("Count")!.Value), Sum = Convert.ToDouble(element.Element("Sum")!.Value), Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value), @@ -66,12 +69,7 @@ namespace PlumbingRepairFileImplement.Models { return; } - WorkId = model.WorkId; - WorkName = model.WorkName; - Count = model.Count; - Sum = model.Sum; Status = model.Status; - DateCreate = model.DateCreate; DateImplement = model.DateImplement; } @@ -80,6 +78,7 @@ namespace PlumbingRepairFileImplement.Models Id = Id, WorkId = WorkId, WorkName = WorkName, + ClientId = ClientId, Count = Count, Sum = Sum, Status = Status, @@ -91,6 +90,7 @@ namespace PlumbingRepairFileImplement.Models new XAttribute("Id", Id), new XElement("WorkName", WorkName), new XElement("WorkId", WorkId.ToString()), + new XElement("ClientId", ClientId.ToString()), new XElement("Count", Count.ToString()), new XElement("Sum", Sum.ToString()), new XElement("Status", Status.ToString()),