diff --git a/SewingDresses/SewingDressesDatabaseImplement/Implements/ShopStorage.cs b/SewingDresses/SewingDressesDatabaseImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..592b935 --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Implements/ShopStorage.cs @@ -0,0 +1,144 @@ +using Microsoft.EntityFrameworkCore; +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.SearchModels; +using SewingDressesContracts.StoragesContracts; +using SewingDressesContracts.ViewModels; +using SewingDressesDatabaseImplement.Models; +using SewingDressesDataModels.Models; + +namespace SewingDressesDatabaseImplement.Implements +{ + public class ShopStorage : IShopStorage + { + public ShopViewModel? Delete(ShopBindingModel model) + { + using var context = new SewingDressesDatabase(); + var element = context.Shops.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + context.Shops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue) + { + return null; + } + using var context = new SewingDressesDatabase(); + return context.Shops.Include(x => x.Dresses).ThenInclude(x => x.Dress).FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + using var context = new SewingDressesDatabase(); + return context.Shops + .Include(x => x.Dresses) + .ThenInclude(x => x.Dress) + .Select(x => x.GetViewModel) + .Where(x => x.ShopName.Contains(model.Name ?? string.Empty)) + .ToList(); + } + + public List GetFullList() + { + using var context = new SewingDressesDatabase(); + return context.Shops + .Include(x => x.Dresses) + .ThenInclude(x => x.Dress) + .Select(x => x.GetViewModel) + .ToList(); + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + using var context = new SewingDressesDatabase(); + try + { + var newShop = Shop.Create(context, model); + if (newShop == null) + { + return null; + } + if (context.Shops.Any(x => x.ShopName == newShop.ShopName)) + { + throw new Exception("Не должно быть два магазина с одним названием"); + } + context.Shops.Add(newShop); + context.SaveChanges(); + return newShop.GetViewModel; + } + catch + { + throw; + } + } + + public ShopViewModel? Update(ShopBindingModel model) + { + using var context = new SewingDressesDatabase(); + var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id); + if (shop == null) + { + return null; + } + try + { + if (context.Shops.Any(x => (x.ShopName == model.ShopName && x.Id != model.Id))) + { + throw new Exception("Не должно быть два магазина с одним названием"); + } + shop.Update(model); + shop.UpdateDresses(context, model); + context.SaveChanges(); + return shop.GetViewModel; + } + catch + { + throw; + } + } + public bool SellDresses(IDressModel model, int count) + { + if (model == null) + return false; + using var context = new SewingDressesDatabase(); + using var transaction = context.Database.BeginTransaction(); + List lst = new List(); + foreach (var el in context.ShopDresses.Where(x => x.DressId == model.Id)) + { + int dif = count; + if (el.Count < dif) + dif = el.Count; + el.Count -= dif; + count -= dif; + if (el.Count == 0) + { + lst.Add(el); + } + if (count == 0) + break; + } + if (count > 0) + { + transaction.Rollback(); + return false; + } + foreach (var el in lst) + { + context.ShopDresses.Remove(el); + } + context.SaveChanges(); + transaction.Commit(); + return true; + } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.Designer.cs b/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.Designer.cs new file mode 100644 index 0000000..88a3209 --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.Designer.cs @@ -0,0 +1,246 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using SewingDressesDatabaseImplement; + +#nullable disable + +namespace SewingDressesDatabaseImplement1.Migrations +{ + [DbContext(typeof(SewingDressesDatabase))] + [Migration("20240404175726_ClientAboba")] + partial class ClientAboba + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.16") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cost") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Dress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DressName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Dresses"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.DressComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DressId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("DressId"); + + b.ToTable("DressComponents"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DateCreate") + .HasColumnType("datetime2"); + + b.Property("DateImplement") + .HasColumnType("datetime2"); + + b.Property("DressId") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Sum") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("DressId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Adress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpen") + .HasColumnType("datetime2"); + + b.Property("MaxCount") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.ShopDress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DressId") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DressId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopDresses"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.DressComponent", b => + { + b.HasOne("SewingDressesDatabaseImplement.Models.Component", "Component") + .WithMany("DressComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SewingDressesDatabaseImplement.Models.Dress", "Dress") + .WithMany("Components") + .HasForeignKey("DressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Dress"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Order", b => + { + b.HasOne("SewingDressesDatabaseImplement.Models.Dress", null) + .WithMany("Orders") + .HasForeignKey("DressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.ShopDress", b => + { + b.HasOne("SewingDressesDatabaseImplement.Models.Dress", "Dress") + .WithMany() + .HasForeignKey("DressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SewingDressesDatabaseImplement.Models.Shop", "Shop") + .WithMany("Dresses") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dress"); + + b.Navigation("Shop"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Component", b => + { + b.Navigation("DressComponents"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Dress", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Shop", b => + { + b.Navigation("Dresses"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.cs b/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.cs new file mode 100644 index 0000000..a3ed527 --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Migrations/20240404175726_ClientAboba.cs @@ -0,0 +1,78 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace SewingDressesDatabaseImplement1.Migrations +{ + /// + public partial class ClientAboba : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Shops", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ShopName = table.Column(type: "nvarchar(max)", nullable: false), + Adress = table.Column(type: "nvarchar(max)", nullable: false), + DateOpen = table.Column(type: "datetime2", nullable: false), + MaxCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Shops", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ShopDresses", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DressId = table.Column(type: "int", nullable: false), + ShopId = table.Column(type: "int", nullable: false), + Count = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopDresses", x => x.Id); + table.ForeignKey( + name: "FK_ShopDresses_Dresses_DressId", + column: x => x.DressId, + principalTable: "Dresses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ShopDresses_Shops_ShopId", + column: x => x.ShopId, + principalTable: "Shops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ShopDresses_DressId", + table: "ShopDresses", + column: "DressId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopDresses_ShopId", + table: "ShopDresses", + column: "ShopId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ShopDresses"); + + migrationBuilder.DropTable( + name: "Shops"); + } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Migrations/SewingDressesDatabaseModelSnapshot.cs b/SewingDresses/SewingDressesDatabaseImplement/Migrations/SewingDressesDatabaseModelSnapshot.cs index c67a266..3532f2a 100644 --- a/SewingDresses/SewingDressesDatabaseImplement/Migrations/SewingDressesDatabaseModelSnapshot.cs +++ b/SewingDresses/SewingDressesDatabaseImplement/Migrations/SewingDressesDatabaseModelSnapshot.cs @@ -17,7 +17,7 @@ namespace SewingDressesDatabaseImplement1.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("ProductVersion", "7.0.16") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -121,6 +121,59 @@ namespace SewingDressesDatabaseImplement1.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Adress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DateOpen") + .HasColumnType("datetime2"); + + b.Property("MaxCount") + .HasColumnType("int"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.ShopDress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("DressId") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DressId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopDresses"); + }); + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.DressComponent", b => { b.HasOne("SewingDressesDatabaseImplement.Models.Component", "Component") @@ -149,6 +202,25 @@ namespace SewingDressesDatabaseImplement1.Migrations .IsRequired(); }); + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.ShopDress", b => + { + b.HasOne("SewingDressesDatabaseImplement.Models.Dress", "Dress") + .WithMany() + .HasForeignKey("DressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SewingDressesDatabaseImplement.Models.Shop", "Shop") + .WithMany("Dresses") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dress"); + + b.Navigation("Shop"); + }); + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Component", b => { b.Navigation("DressComponents"); @@ -160,6 +232,11 @@ namespace SewingDressesDatabaseImplement1.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("SewingDressesDatabaseImplement.Models.Shop", b => + { + b.Navigation("Dresses"); + }); #pragma warning restore 612, 618 } } diff --git a/SewingDresses/SewingDressesDatabaseImplement/Models/Shop.cs b/SewingDresses/SewingDressesDatabaseImplement/Models/Shop.cs new file mode 100644 index 0000000..845dd8d --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Models/Shop.cs @@ -0,0 +1,100 @@ +using SewingDressesContracts.BindingModels; +using SewingDressesContracts.ViewModels; +using SewingDressesDataModels.Models; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace SewingDressesDatabaseImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; private set; } + [Required] + public string ShopName { get; private set; } + [Required] + public string Adress { get; private set; } + [Required] + public DateTime DateOpen { get; private set; } + [Required] + public int MaxCount { get; private set; } + private Dictionary? _shopDresses = null; + [NotMapped] + public Dictionary? ShopDresses + { + get + { + if ( _shopDresses == null ) + { + _shopDresses = Dresses.ToDictionary(x => x.DressId, x => (x.Dress as IDressModel, x.Count)); + } + return _shopDresses; + } + } + [ForeignKey("ShopId")] + public virtual List Dresses { get; set; } = new(); + public static Shop? Create(SewingDressesDatabase context, ShopBindingModel model) + { + if (model == null) + return null; + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Adress = model.Adress, + DateOpen = model.DateOpen, + MaxCount = model.MaxCount, + Dresses = model.ShopDresses.Select(x => new ShopDress + { + Dress = context.Dresses.First(y => y.Id == x.Key), + Count = x.Value.Item2 + }).ToList() + }; + } + public void Update(ShopBindingModel? model) + { + if (model == null ) + return; + ShopName = model.ShopName; + Adress = model.Adress; + DateOpen = model.DateOpen; + MaxCount = model.MaxCount; + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Adress = Adress, + DateOpen = DateOpen, + MaxCount = MaxCount, + ShopDresses = ShopDresses + }; + + public void UpdateDresses(SewingDressesDatabase context, ShopBindingModel model) + { + var shopDresses = context.ShopDresses.Where(rec => rec.ShopId == model.Id).ToList(); + if (shopDresses != null && shopDresses.Count > 0) + { + context.ShopDresses.RemoveRange(shopDresses.Where(rec => !model.ShopDresses.ContainsKey(rec.DressId))); + context.SaveChanges(); + foreach (var uDress in shopDresses) + { + uDress.Count = model.ShopDresses[uDress.DressId].Item2; + model.ShopDresses.Remove(uDress.DressId); + } + context.SaveChanges(); + } + var shop = context.Shops.First(x => x.Id == Id); + foreach (var pc in model.ShopDresses) + { + context.ShopDresses.Add(new ShopDress + { + Shop = shop, + Dress = context.Dresses.First(x => x.Id == pc.Key), + Count = pc.Value.Item2 + }); + context.SaveChanges() ; + } + _shopDresses = null; + } + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/Models/ShopDress.cs b/SewingDresses/SewingDressesDatabaseImplement/Models/ShopDress.cs new file mode 100644 index 0000000..5c64235 --- /dev/null +++ b/SewingDresses/SewingDressesDatabaseImplement/Models/ShopDress.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace SewingDressesDatabaseImplement.Models +{ + public class ShopDress + { + public int Id { get; set; } + [Required] + public int DressId { get; set; } + [Required] + public int ShopId { get; set; } + [Required] + public int Count { get; set; } + public virtual Shop Shop { get; set; } = new(); + public virtual Dress Dress { get; set; } = new(); + } +} diff --git a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs index 7a4beb3..a50b5c4 100644 --- a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs +++ b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabase.cs @@ -8,7 +8,7 @@ namespace SewingDressesDatabaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=.\SQLEXPRESS;Initial Catalog=SewingDressesDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=.\SQLEXPRESS;Initial Catalog=SewingDressesDatabaseHard;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } @@ -16,5 +16,7 @@ namespace SewingDressesDatabaseImplement public virtual DbSet Dresses { get; set; } public virtual DbSet DressComponents { get; set; } public virtual DbSet Orders { get; set; } + public virtual DbSet Shops { get; set; } + public virtual DbSet ShopDresses { get; set; } } } diff --git a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabaseImplement.csproj b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabaseImplement.csproj index 2574adc..1be8d24 100644 --- a/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabaseImplement.csproj +++ b/SewingDresses/SewingDressesDatabaseImplement/SewingDressesDatabaseImplement.csproj @@ -13,6 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive +