From 032908178d325d77c43daf5ccea94d8b942ac603 Mon Sep 17 00:00:00 2001
From: Kirill <117719052+KirillFirsof@users.noreply.github.com>
Date: Wed, 27 Mar 2024 15:06:37 +0400
Subject: [PATCH] g

---
 ClothShop/ClothShop.sln                       |  6 ++
 .../ClothShopDatabase.cs                      | 24 +++++
 .../ClothShopDatabaseImplement.csproj         | 27 ++++++
 .../Models/Component.cs                       | 57 +++++++++++
 .../Models/Order.cs                           | 65 +++++++++++++
 .../Models/Textile.cs                         | 96 +++++++++++++++++++
 .../Models/TextileComponent.cs                | 16 ++++
 ClothShop/ClothShopView/ClothShopView.csproj  |  4 +
 8 files changed, 295 insertions(+)
 create mode 100644 ClothShop/ClothShopDatabaseImplement/ClothShopDatabase.cs
 create mode 100644 ClothShop/ClothShopDatabaseImplement/ClothShopDatabaseImplement.csproj
 create mode 100644 ClothShop/ClothShopDatabaseImplement/Models/Component.cs
 create mode 100644 ClothShop/ClothShopDatabaseImplement/Models/Order.cs
 create mode 100644 ClothShop/ClothShopDatabaseImplement/Models/Textile.cs
 create mode 100644 ClothShop/ClothShopDatabaseImplement/Models/TextileComponent.cs

diff --git a/ClothShop/ClothShop.sln b/ClothShop/ClothShop.sln
index 415d3e7..85f867b 100644
--- a/ClothShop/ClothShop.sln
+++ b/ClothShop/ClothShop.sln
@@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClothShopListImplement", "C
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClothShopFileImplement", "ClothShopFileImplement\ClothShopFileImplement.csproj", "{EDA6F63F-1DF0-4075-BDBE-B0B71B76D384}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClothShopDatabaseImplement", "ClothShopDatabaseImplement\ClothShopDatabaseImplement.csproj", "{38A05AFD-49C4-4E47-AAE8-45FD00D2F195}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -45,6 +47,10 @@ Global
 		{EDA6F63F-1DF0-4075-BDBE-B0B71B76D384}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EDA6F63F-1DF0-4075-BDBE-B0B71B76D384}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{EDA6F63F-1DF0-4075-BDBE-B0B71B76D384}.Release|Any CPU.Build.0 = Release|Any CPU
+		{38A05AFD-49C4-4E47-AAE8-45FD00D2F195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{38A05AFD-49C4-4E47-AAE8-45FD00D2F195}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{38A05AFD-49C4-4E47-AAE8-45FD00D2F195}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{38A05AFD-49C4-4E47-AAE8-45FD00D2F195}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/ClothShop/ClothShopDatabaseImplement/ClothShopDatabase.cs b/ClothShop/ClothShopDatabaseImplement/ClothShopDatabase.cs
new file mode 100644
index 0000000..4106767
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/ClothShopDatabase.cs
@@ -0,0 +1,24 @@
+using ClothShopDatabaseImplement.Models;
+using Microsoft.EntityFrameworkCore;
+namespace ClothShopDatabaseImplement
+{
+    public class ClothShopDatabase : DbContext
+    {
+        protected override void OnConfiguring(DbContextOptionsBuilder
+       optionsBuilder)
+        {
+            if (optionsBuilder.IsConfigured == false)
+            {
+                optionsBuilder.UseSqlServer(@"Data
+Source=LAPTOP-K77I3N46\SQLEXPRESS;Initial Catalog=ClothShopDatabaseFull;Integrated
+Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
+            }
+            base.OnConfiguring(optionsBuilder);
+        }
+        public virtual DbSet<Component> Components { set; get; }
+        public virtual DbSet<Textile> Textiles { set; get; }
+        public virtual DbSet<TextileComponent> TextileComponents { set; get; }
+        public virtual DbSet<Order> Orders { set; get; }
+    }
+}
+
diff --git a/ClothShop/ClothShopDatabaseImplement/ClothShopDatabaseImplement.csproj b/ClothShop/ClothShopDatabaseImplement/ClothShopDatabaseImplement.csproj
new file mode 100644
index 0000000..b00ca0b
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/ClothShopDatabaseImplement.csproj
@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Folder Include="Implements\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.3" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.3">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\ClothShopContracts\ClothShopContracts.csproj" />
+    <ProjectReference Include="..\ClothShopDataModels\ClothShopDataModels.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/ClothShop/ClothShopDatabaseImplement/Models/Component.cs b/ClothShop/ClothShopDatabaseImplement/Models/Component.cs
new file mode 100644
index 0000000..ba2375e
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/Models/Component.cs
@@ -0,0 +1,57 @@
+using ClothShopContracts.BindingModels;
+using ClothShopContracts.ViewModels;
+using ClothShopDataModels.Models;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+namespace ClothShopDatabaseImplement.Models
+{
+    public class Component : IComponentModel
+    {
+        public int Id { get; private set; }
+        [Required]
+        public string ComponentName { get; private set; } = string.Empty;
+        [Required]
+        public double Cost { get; set; }
+        [ForeignKey("ComponentId")]
+        public virtual List<TextileComponent> ProductComponents { get; set; } =
+       new();
+        public static Component? Create(ComponentBindingModel model)
+        {
+            if (model == null)
+            {
+                return null;
+            }
+            return new Component()
+            {
+                Id = model.Id,
+                ComponentName = model.ComponentName,
+                Cost = model.Cost
+            };
+        }
+        public static Component Create(ComponentViewModel model)
+        {
+            return new Component
+            {
+                Id = model.Id,
+                ComponentName = model.ComponentName,
+                Cost = model.Cost
+            };
+        }
+        public void Update(ComponentBindingModel model)
+        {
+            if (model == null)
+            {
+                return;
+            }
+            ComponentName = model.ComponentName;
+            Cost = model.Cost;
+        }
+        public ComponentViewModel GetViewModel => new()
+        {
+            Id = Id,
+            ComponentName = ComponentName,
+            Cost = Cost
+        };
+    }
+}
+
diff --git a/ClothShop/ClothShopDatabaseImplement/Models/Order.cs b/ClothShop/ClothShopDatabaseImplement/Models/Order.cs
new file mode 100644
index 0000000..0c561dd
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/Models/Order.cs
@@ -0,0 +1,65 @@
+using ClothShopContracts.BindingModels;
+using ClothShopContracts.ViewModels;
+using ClothShopDataModels.Enums;
+
+using System.ComponentModel.DataAnnotations;
+
+namespace ClothShopDatabaseImplement.Models
+{
+    public class Order
+    {
+        public int Id { get; private set; }
+        [Required]
+        public int Count { get; private set; }
+        [Required]
+        public double Sum { get; private set; }
+        [Required]
+        public OrderStatus Status { get; private set; }
+        [Required]
+        public DateTime DateCreate { get; private set; }
+        public DateTime? DateImplement { get; private set; }
+        [Required]
+        public int TextileId { get; private set; }
+        public virtual Textile? Textiles { get; private set; }
+
+        public static Order? Create(OrderBindingModel model)
+        {
+            if (model == null)
+            {
+                return null;
+            }
+            return new Order()
+            {
+                Id = model.Id,
+                Count = model.Count,
+                Sum = model.Sum,
+                Status = model.Status,
+                DateCreate = model.DateCreate,
+                DateImplement = model.DateImplement,
+                TextileId = model.TextileId,
+            };
+        }
+
+        public void Update(OrderBindingModel? model)
+        {
+            if (model == null)
+            {
+                return;
+            }
+            Status = model.Status;
+            DateImplement = model.DateImplement;
+        }
+
+        public OrderViewModel GetViewModel => new()
+        {
+            TextileId = TextileId,
+            Count = Count,
+            Sum = Sum,
+            Status = Status,
+            DateCreate = DateCreate,
+            DateImplement = DateImplement,
+            Id = Id,
+            TextileName = Textiles?.TextileName ?? string.Empty
+        };
+    }
+}
diff --git a/ClothShop/ClothShopDatabaseImplement/Models/Textile.cs b/ClothShop/ClothShopDatabaseImplement/Models/Textile.cs
new file mode 100644
index 0000000..bd593ec
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/Models/Textile.cs
@@ -0,0 +1,96 @@
+using ClothShopContracts.BindingModels;
+using ClothShopContracts.ViewModels;
+using ClothShopDataModels.Models;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+namespace ClothShopDatabaseImplement.Models
+{
+    public class Textile : ITextileModel
+    {
+        public int Id { get; set; }
+        [Required]
+        public string TextileName { get; set; } = string.Empty;
+        [Required]
+        public double Price { get; set; }
+        private Dictionary<int, (IComponentModel, int)>? _textileComponents =
+       null;
+        [NotMapped]
+        public Dictionary<int, (IComponentModel, int)> TextileComponents
+        {
+            get
+            {
+                if (_textileComponents == null)
+                {
+                    _textileComponents = Components
+                    .ToDictionary(recPC => recPC.ComponentId, recPC =>
+                   (recPC.Component as IComponentModel, recPC.Count));
+                }
+                return _textileComponents;
+            }
+        }
+        [ForeignKey("TextileId")]
+        public virtual List<TextileComponent> Components { get; set; } = new();
+        [ForeignKey("TextileId")]
+        public virtual List<Order> Orders { get; set; } = new();
+        public static Textile Create(ClothShopDatabase context,
+       TextileBindingModel model)
+        {
+            return new Textile()
+            {
+                Id = model.Id,
+                TextileName = model.TextileName,
+                Price = model.Price,
+                Components = model.TextileComponents.Select(x => new
+               TextileComponent
+                {
+                    Component = context.Components.First(y => y.Id == x.Key),
+                    Count = x.Value.Item2
+                }).ToList()
+            };
+        }
+        public void Update(TextileBindingModel model)
+        {
+            TextileName = model.TextileName;
+            Price = model.Price;
+        }
+        public TextileViewModel GetViewModel => new()
+        {
+            Id = Id,
+            TextileName = TextileName,
+            Price = Price,
+            TextileComponents = TextileComponents
+        };
+        public void UpdateComponents(ClothShopDatabase context,
+       TextileBindingModel model)
+        {
+            var textileComponents = context.TextileComponents.Where(rec =>
+           rec.TextileId == model.Id).ToList();
+            if (textileComponents != null && textileComponents.Count > 0)
+            { // удалили те, которых нет в модели
+                context.TextileComponents.RemoveRange(textileComponents.Where(rec
+               => !model.TextileComponents.ContainsKey(rec.ComponentId)));
+                context.SaveChanges();
+                // обновили количество у существующих записей
+                foreach (var updateComponent in textileComponents)
+                {
+                    updateComponent.Count =
+                   model.TextileComponents[updateComponent.ComponentId].Item2;
+                    model.TextileComponents.Remove(updateComponent.ComponentId);
+                }
+                context.SaveChanges();
+            }
+            var textile = context.Textiles.First(x => x.Id == Id);
+            foreach (var pc in model.TextileComponents)
+            {
+                context.TextileComponents.Add(new TextileComponent
+                {
+                    Textile = textile,
+                    Component = context.Components.First(x => x.Id == pc.Key),
+                    Count = pc.Value.Item2
+                });
+                context.SaveChanges();
+            }
+            _textileComponents = null;
+        }
+    }
+}
diff --git a/ClothShop/ClothShopDatabaseImplement/Models/TextileComponent.cs b/ClothShop/ClothShopDatabaseImplement/Models/TextileComponent.cs
new file mode 100644
index 0000000..4e60953
--- /dev/null
+++ b/ClothShop/ClothShopDatabaseImplement/Models/TextileComponent.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+namespace ClothShopDatabaseImplement.Models
+{
+    public class TextileComponent
+    {
+        public int Id { get; set; }
+        [Required]
+        public int TextileId { get; set; }
+        [Required]
+        public int ComponentId { get; set; }
+        [Required]
+        public int Count { get; set; }
+        public virtual Component Component { get; set; } = new();
+        public virtual Textile Textile { get; set; } = new();
+    }
+}
diff --git a/ClothShop/ClothShopView/ClothShopView.csproj b/ClothShop/ClothShopView/ClothShopView.csproj
index 79e0e3a..27e4341 100644
--- a/ClothShop/ClothShopView/ClothShopView.csproj
+++ b/ClothShop/ClothShopView/ClothShopView.csproj
@@ -9,6 +9,10 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.3">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
     <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
     <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />