diff --git a/Course/BusinessLogic/BusinessLogic.csproj b/Course/BusinessLogic/BusinessLogic.csproj
index 132c02c..75a93ab 100644
--- a/Course/BusinessLogic/BusinessLogic.csproj
+++ b/Course/BusinessLogic/BusinessLogic.csproj
@@ -6,4 +6,12 @@
enable
+
+
+
+
+
+
+
+
diff --git a/Course/BusinessLogic/DetailLogic.cs b/Course/BusinessLogic/DetailLogic.cs
new file mode 100644
index 0000000..d4aa38d
--- /dev/null
+++ b/Course/BusinessLogic/DetailLogic.cs
@@ -0,0 +1,110 @@
+using Contracts.BindingModels;
+using Contracts.BusinessLogicsContracts;
+using Contracts.SearchModels;
+using Contracts.StoragesContracts;
+using Contracts.ViewModels;
+using Microsoft.Extensions.Logging;
+using System.Xml.Linq;
+
+namespace BusinessLogic
+{
+ public class DetailLogic : IDetailLogic
+ {
+ private readonly ILogger _logger;
+ private readonly IDetailStorage _detailStorage;
+ public DetailLogic(ILogger logger, IDetailStorage detailStorage)
+ {
+ _logger = logger;
+ _detailStorage = detailStorage;
+ }
+ public List? ReadList(DetailSearchModel? model)
+ {
+ _logger.LogInformation("ReadList. DetailName:{name}. Id:{Id}", model.Name, model.Id);
+ var list = model == null ? _detailStorage.GetFullList() : _detailStorage.GetFilteredList(model);
+ if (list == null)
+ {
+ _logger.LogWarning("ReadList return null list");
+ return null;
+ }
+ _logger.LogWarning("ReadList. Count:{Count}", list.Count);
+ return list;
+ }
+ public DetailViewModel? ReadElement(DetailSearchModel? model)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ _logger.LogInformation("ReadElement. DetailName:{Name}. Id:{Id}", model.Name, model.Id);
+ var elem = _detailStorage.GetElement(model);
+ if (elem == null)
+ {
+ _logger.LogWarning("ReadElement element not found");
+ return null;
+ }
+ _logger.LogInformation("ReadElement find. Id:{Id}", elem.Id);
+ return elem;
+ }
+
+
+ private void CheckModel(DetailBindingModel? model, bool withParams = true)
+ {
+ if (model == null)
+ {
+ throw new ArgumentNullException(nameof(model));
+ }
+ if (!withParams)
+ {
+ return;
+ }
+ if (string.IsNullOrEmpty(model.Name))
+ {
+ throw new ArgumentNullException("Нет названия детали", nameof(model.Name));
+ }
+ if (model.Cost <= 0)
+ {
+ throw new ArgumentNullException("Цена детали должна быть больше 0", nameof(model.Cost));
+ }
+ _logger.LogInformation("Detail. DetailName:{Name}. Cost:{Cost}. Id:{Id}", model.Name, model.Cost, model.Id);
+ var elem = _detailStorage.GetElement(new DetailSearchModel
+ {
+ Name = model.Name
+ });
+ if (elem != null && elem.Id != model.Id)
+ {
+ throw new InvalidOperationException("Деталь с таким названием уже существует");
+ }
+ }
+ public bool Create(DetailBindingModel? model)
+ {
+ CheckModel(model);
+ if (_detailStorage.Insert(model!) == null)
+ {
+ _logger.LogWarning("Insert error");
+ return false;
+ }
+ return true;
+ }
+ public bool Update(DetailBindingModel? model)
+ {
+ CheckModel(model);
+ if (_detailStorage.Update(model!) == null)
+ {
+ _logger.LogWarning("Update error");
+ return false;
+ }
+ return true;
+ }
+ public bool Delete(DetailBindingModel? model)
+ {
+ CheckModel(model, false);
+ _logger.LogInformation("Delete Id:{Id}", model!.Id);
+ if (_detailStorage.Delete(model!) == null)
+ {
+ _logger.LogWarning("Delete error");
+ return false;
+ }
+ return true;
+ }
+ }
+}
diff --git a/Course/Contracts/BindingModels/ImplementerBindingModel.cs b/Course/Contracts/BindingModels/ImplementerBindingModel.cs
new file mode 100644
index 0000000..99f32aa
--- /dev/null
+++ b/Course/Contracts/BindingModels/ImplementerBindingModel.cs
@@ -0,0 +1,14 @@
+
+using DataModels.Models;
+
+namespace Contracts.BindingModels
+{
+ public class ImplementerBindingModel : IImplementerModel
+ {
+ public int Id { get; set; }
+ public string Email { get; set; } = string.Empty;
+ public string Name { get; set; } = string.Empty;
+ public string Login { get; set; } = string.Empty;
+ public string Password { get; set; } = string.Empty;
+ }
+}
diff --git a/Course/Contracts/BusinessLogicsContracts/IDetailLogic.cs b/Course/Contracts/BusinessLogicsContracts/IDetailLogic.cs
new file mode 100644
index 0000000..ec37ca1
--- /dev/null
+++ b/Course/Contracts/BusinessLogicsContracts/IDetailLogic.cs
@@ -0,0 +1,15 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.BusinessLogicsContracts
+{
+ public interface IDetailLogic
+ {
+ List? ReadList(DetailSearchModel? model);
+ DetailViewModel? ReadElement(DetailSearchModel? model);
+ bool Create(DetailBindingModel? model);
+ bool Update(DetailBindingModel? model);
+ bool Delete(DetailBindingModel? model);
+ }
+}
diff --git a/Course/Contracts/BusinessLogicsContracts/IImplementerLogic.cs b/Course/Contracts/BusinessLogicsContracts/IImplementerLogic.cs
new file mode 100644
index 0000000..2923b51
--- /dev/null
+++ b/Course/Contracts/BusinessLogicsContracts/IImplementerLogic.cs
@@ -0,0 +1,15 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.BusinessLogicsContracts
+{
+ public interface IImplementerLogic
+ {
+ List? ReadList(ImplementerSearchModel? model);
+ ImplementerViewModel? ReadElement(ImplementerSearchModel? model);
+ bool Create(ImplementerBindingModel? model);
+ bool Update(ImplementerViewModel? model);
+ bool Delete(ImplementerViewModel? model);
+ }
+}
diff --git a/Course/Contracts/BusinessLogicsContracts/IProductLogic.cs b/Course/Contracts/BusinessLogicsContracts/IProductLogic.cs
new file mode 100644
index 0000000..29484ef
--- /dev/null
+++ b/Course/Contracts/BusinessLogicsContracts/IProductLogic.cs
@@ -0,0 +1,15 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.BusinessLogicsContracts
+{
+ public interface IProductLogic
+ {
+ List? ReadList(ProductSearchModel? model);
+ ProductViewModel? ReadElement(ProductSearchModel? model);
+ bool Create(ProductBindingModel? model);
+ bool Update(ProductBindingModel? model);
+ bool Delete(ProductBindingModel? model);
+ }
+}
diff --git a/Course/Contracts/BusinessLogicsContracts/IProductionLogic.cs b/Course/Contracts/BusinessLogicsContracts/IProductionLogic.cs
new file mode 100644
index 0000000..16b3ae9
--- /dev/null
+++ b/Course/Contracts/BusinessLogicsContracts/IProductionLogic.cs
@@ -0,0 +1,15 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.BusinessLogicsContracts
+{
+ public interface IProductionLogic
+ {
+ List? ReadList(ProductionSearchModel? model);
+ ProductionViewModel? ReadElement(ProductionSearchModel? model);
+ bool Create(ProductionBindingModel? model);
+ bool Update(ProductionViewModel? model);
+ bool Delete(ProductionViewModel? model);
+ }
+}
diff --git a/Course/Contracts/Contracts.csproj b/Course/Contracts/Contracts.csproj
index 8d61df8..2e520d2 100644
--- a/Course/Contracts/Contracts.csproj
+++ b/Course/Contracts/Contracts.csproj
@@ -6,13 +6,6 @@
enable
-
-
-
-
-
-
-
diff --git a/Course/Contracts/SearchModels/DetailSearchModel.cs b/Course/Contracts/SearchModels/DetailSearchModel.cs
new file mode 100644
index 0000000..47ff68a
--- /dev/null
+++ b/Course/Contracts/SearchModels/DetailSearchModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.SearchModels
+{
+ public class DetailSearchModel
+ {
+ public int? Id { get; set; }
+ public string? Name { get; set; }
+ public int? UserId { get; set; }
+ }
+}
diff --git a/Course/Contracts/SearchModels/ImplementerSearchModel.cs b/Course/Contracts/SearchModels/ImplementerSearchModel.cs
new file mode 100644
index 0000000..4fba103
--- /dev/null
+++ b/Course/Contracts/SearchModels/ImplementerSearchModel.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.SearchModels
+{
+ public class ImplementerSearchModel
+ {
+ public int? Id { get; set; }
+ public string? Login { get; set; }
+ }
+}
diff --git a/Course/Contracts/SearchModels/ProductSearchModel.cs b/Course/Contracts/SearchModels/ProductSearchModel.cs
new file mode 100644
index 0000000..ba7016d
--- /dev/null
+++ b/Course/Contracts/SearchModels/ProductSearchModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.SearchModels
+{
+ public class ProductSearchModel
+ {
+ public int? Id { get; set; }
+ public string? Name { get; set; }
+ public int? UserId { get; set; }
+ }
+}
diff --git a/Course/Contracts/SearchModels/ProductionSearchModel.cs b/Course/Contracts/SearchModels/ProductionSearchModel.cs
new file mode 100644
index 0000000..bf5ff28
--- /dev/null
+++ b/Course/Contracts/SearchModels/ProductionSearchModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.SearchModels
+{
+ public class ProductionSearchModel
+ {
+ public int? Id { get; set; }
+ public string? Name { get; set; }
+ public int? UserId { get; set; }
+ }
+}
diff --git a/Course/Contracts/StoragesContracts/IDetailStorage.cs b/Course/Contracts/StoragesContracts/IDetailStorage.cs
new file mode 100644
index 0000000..0d38cb3
--- /dev/null
+++ b/Course/Contracts/StoragesContracts/IDetailStorage.cs
@@ -0,0 +1,16 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.StoragesContracts
+{
+ public interface IDetailStorage
+ {
+ List GetFullList();
+ List GetFilteredList(DetailSearchModel model);
+ DetailViewModel? GetElement(DetailSearchModel model);
+ DetailViewModel? Insert(DetailBindingModel model);
+ DetailViewModel? Update(DetailBindingModel model);
+ DetailViewModel? Delete(DetailBindingModel model);
+ }
+}
diff --git a/Course/Contracts/StoragesContracts/IImplementerStorage.cs b/Course/Contracts/StoragesContracts/IImplementerStorage.cs
new file mode 100644
index 0000000..c010ba9
--- /dev/null
+++ b/Course/Contracts/StoragesContracts/IImplementerStorage.cs
@@ -0,0 +1,17 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.StoragesContracts
+{
+ public interface IImplementerStorage
+ {
+ List GetFullList();
+ List GetFilteredList(ImplementerSearchModel model);
+ ImplementerViewModel? GetElement(ImplementerSearchModel model);
+ ImplementerViewModel? Insert(ImplementerBindingModel model);
+ ImplementerViewModel? Update(ImplementerBindingModel model);
+ ImplementerViewModel? Delete(ImplementerBindingModel model);
+ }
+}
+
diff --git a/Course/Contracts/StoragesContracts/IProductStorage.cs b/Course/Contracts/StoragesContracts/IProductStorage.cs
new file mode 100644
index 0000000..ce21d8b
--- /dev/null
+++ b/Course/Contracts/StoragesContracts/IProductStorage.cs
@@ -0,0 +1,16 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.StoragesContracts
+{
+ public interface IProductStorage
+ {
+ List GetFullList();
+ List GetFilteredList(ProductSearchModel model);
+ ProductViewModel? GetElement(ProductSearchModel model);
+ ProductViewModel? Insert(ProductBindingModel model);
+ ProductViewModel? Update(ProductBindingModel model);
+ ProductViewModel? Delete(ProductBindingModel model);
+ }
+}
diff --git a/Course/Contracts/StoragesContracts/IProductionStorage.cs b/Course/Contracts/StoragesContracts/IProductionStorage.cs
new file mode 100644
index 0000000..804ece4
--- /dev/null
+++ b/Course/Contracts/StoragesContracts/IProductionStorage.cs
@@ -0,0 +1,17 @@
+using Contracts.BindingModels;
+using Contracts.SearchModels;
+using Contracts.ViewModels;
+
+namespace Contracts.StoragesContracts
+{
+ public interface IProductionStorage
+ {
+ List GetFullList();
+ List GetFilteredList(ProductionSearchModel model);
+ ProductionViewModel? GetElement(ProductionSearchModel model);
+ ProductionViewModel? Insert(ProductionBindingModel model);
+ ProductionViewModel? Update(ProductionBindingModel model);
+ ProductionViewModel? Delete(ProductionBindingModel model);
+ }
+}
+
diff --git a/Course/Contracts/ViewModels/DetailViewModel.cs b/Course/Contracts/ViewModels/DetailViewModel.cs
new file mode 100644
index 0000000..1b5810f
--- /dev/null
+++ b/Course/Contracts/ViewModels/DetailViewModel.cs
@@ -0,0 +1,21 @@
+using DataModels.Models;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.ViewModels
+{
+ public class DetailViewModel : IDetailModel
+ {
+ public int Id { get; set; }
+ [DisplayName("Название детали")]
+ public string Name { get; set; } = string.Empty;
+ [DisplayName("Цена детали")]
+ public double Cost { get; set; }
+ public int UserId { get; set; }
+
+ }
+}
diff --git a/Course/Contracts/ViewModels/ImplementerViewModel.cs b/Course/Contracts/ViewModels/ImplementerViewModel.cs
new file mode 100644
index 0000000..aee639b
--- /dev/null
+++ b/Course/Contracts/ViewModels/ImplementerViewModel.cs
@@ -0,0 +1,23 @@
+using DataModels.Models;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.ViewModels
+{
+ public class ImplementerViewModel : IImplementerModel
+ {
+ public int Id { get; set; }
+ [DisplayName("Имя исполнителя")]
+ public string Name { get; set; } = string.Empty;
+ [DisplayName("Почта")]
+ public string Email { get; set; } = string.Empty;
+ [DisplayName("Логин")]
+ public string Login { get; set; } = string.Empty;
+ [DisplayName("Пароль")]
+ public string Password { get; set; } = string.Empty;
+ }
+}
diff --git a/Course/Contracts/ViewModels/ProductViewModel.cs b/Course/Contracts/ViewModels/ProductViewModel.cs
new file mode 100644
index 0000000..186c4e1
--- /dev/null
+++ b/Course/Contracts/ViewModels/ProductViewModel.cs
@@ -0,0 +1,20 @@
+using DataModels.Models;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.ViewModels
+{
+ public class ProductViewModel : IProductModel
+ {
+ public int Id { get; set; }
+ [DisplayName("Название изделия")]
+ public string Name { get; set; } = string.Empty;
+ [DisplayName("Цена изделия")]
+ public double Cost { get; set; }
+ public int UserId { get; set; }
+ }
+}
diff --git a/Course/Contracts/ViewModels/ProductionViewModel.cs b/Course/Contracts/ViewModels/ProductionViewModel.cs
new file mode 100644
index 0000000..7302932
--- /dev/null
+++ b/Course/Contracts/ViewModels/ProductionViewModel.cs
@@ -0,0 +1,20 @@
+using DataModels.Models;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Contracts.ViewModels
+{
+ public class ProductionViewModel : IProductionModel
+ {
+ public int Id { get; set; }
+ [DisplayName("Название производства")]
+ public string Name { get; set; } = string.Empty;
+ [DisplayName("Цена производства")]
+ public double Cost { get; set; }
+ public int UserId { get; set; }
+ }
+}
diff --git a/Course/DataModels/Models/IUserModel.cs b/Course/DataModels/IUserModel.cs
similarity index 86%
rename from Course/DataModels/Models/IUserModel.cs
rename to Course/DataModels/IUserModel.cs
index eaf113a..1239a74 100644
--- a/Course/DataModels/Models/IUserModel.cs
+++ b/Course/DataModels/IUserModel.cs
@@ -1,4 +1,4 @@
-namespace DataModels.Models
+namespace DataModels
{
public interface IUserModel
{
diff --git a/Course/DataModels/Models/IImplementerModel.cs b/Course/DataModels/Models/IImplementerModel.cs
new file mode 100644
index 0000000..f774e64
--- /dev/null
+++ b/Course/DataModels/Models/IImplementerModel.cs
@@ -0,0 +1,6 @@
+namespace DataModels.Models
+{
+ public interface IImplementerModel : IUserModel
+ {
+ }
+}