diff --git a/BusinessLogic/BusinessLogic/PurchaseLogic.cs b/BusinessLogic/BusinessLogic/PurchaseLogic.cs index 63edb55..d9acc2b 100644 --- a/BusinessLogic/BusinessLogic/PurchaseLogic.cs +++ b/BusinessLogic/BusinessLogic/PurchaseLogic.cs @@ -6,6 +6,7 @@ using Contracts.SearchModels; using Contracts.StorageContracts; using Contracts.ViewModels; using DatabaseImplement.Implements; +using DatabaseImplement.Migrations; using DatabaseImplement.Models; using DataModels.Enums; using DataModels.Models; @@ -21,13 +22,16 @@ namespace BusinessLogic.BusinessLogic public class PurchaseLogic : IPurchaseLogic { private readonly IPurchaseStorage _purchaseStorage; - private readonly ILogger _logger; + private readonly IProductStorage _productStorage; + private readonly ILogger _logger; - public PurchaseLogic(IPurchaseStorage purchaseStorage, ILogger logger) + public PurchaseLogic(IPurchaseStorage purchaseStorage, IProductStorage productStorage, ILogger logger) { _purchaseStorage = purchaseStorage; _logger = logger; - } + _productStorage = productStorage; + + } public PurchaseViewModel Create(PurchaseBindingModel model) { @@ -76,7 +80,7 @@ namespace BusinessLogic.BusinessLogic public List ReadElements(PurchaseSearchModel? model) { _logger.LogInformation("ReadList. Id: {Id}", model?.Id); - var purchase_list = _purchaseStorage.GetFullList(model); + var purchase_list = model == null ? _purchaseStorage.GetFullList(model) : _purchaseStorage.GetFilteredList(model); if (purchase_list is null || purchase_list.Count() == 0) { _logger.LogWarning("ReadList return null list"); @@ -99,5 +103,14 @@ namespace BusinessLogic.BusinessLogic } return purchase; } + public PurchaseViewModel AddProduct(PurchaseSearchModel purchase_model, ProductSearchModel product_model, int count) + { + _purchaseStorage.AddProducts(purchase_model, product_model, count); + return _purchaseStorage.GetElement(purchase_model); + } + public Dictionary GetProducts(PurchaseSearchModel model) + { + return _purchaseStorage.GetProducts(model); + } } } diff --git a/Contracts/BindingModels/PurchaseBindingModel.cs b/Contracts/BindingModels/PurchaseBindingModel.cs index a245f47..67268dd 100644 --- a/Contracts/BindingModels/PurchaseBindingModel.cs +++ b/Contracts/BindingModels/PurchaseBindingModel.cs @@ -14,6 +14,7 @@ namespace Contracts.BindingModels public DateTime DatePurchase { get; set; } public Guid UserId { get; set; } public PurchaseStatus Status { get; set; } - public Dictionary PurchaseProducts { get; set; } = new(); + public Dictionary? PurchaseProducts { get; set; } = new(); + public double Cost { get; set; } } } diff --git a/Contracts/BusinessLogicContracts/IPurchaseLogic.cs b/Contracts/BusinessLogicContracts/IPurchaseLogic.cs index 7f3a623..8fa80fa 100644 --- a/Contracts/BusinessLogicContracts/IPurchaseLogic.cs +++ b/Contracts/BusinessLogicContracts/IPurchaseLogic.cs @@ -20,5 +20,7 @@ namespace Contracts.BusinessLogicContracts List ReadElements(PurchaseSearchModel? model); PurchaseViewModel Delete(PurchaseSearchModel model); - } + PurchaseViewModel AddProduct(PurchaseSearchModel purchase, ProductSearchModel product, int count); + Dictionary GetProducts(PurchaseSearchModel model); + } } diff --git a/Contracts/SearchModels/PurchaseSearchModel.cs b/Contracts/SearchModels/PurchaseSearchModel.cs index 1dc89d7..2738bf0 100644 --- a/Contracts/SearchModels/PurchaseSearchModel.cs +++ b/Contracts/SearchModels/PurchaseSearchModel.cs @@ -13,8 +13,8 @@ namespace Contracts.SearchModels public Guid? Id { get; set; } public DateTime? DateFrom { get; set; } public DateTime? DateTo { get; set; } - public double? PriceFrom { get; set; } - public double? PriceTo { get; set; } + public double? CostFrom { get; set; } + public double? CostTo { get; set; } public PurchaseStatus? Status { get; set; } } } diff --git a/Contracts/StorageContracts/IPurchaseStorage.cs b/Contracts/StorageContracts/IPurchaseStorage.cs index 1b141ec..8944c44 100644 --- a/Contracts/StorageContracts/IPurchaseStorage.cs +++ b/Contracts/StorageContracts/IPurchaseStorage.cs @@ -21,5 +21,7 @@ namespace Contracts.StorageContracts PurchaseViewModel? Update(PurchaseBindingModel model); PurchaseViewModel? Delete(PurchaseSearchModel model); - } + PurchaseViewModel? AddProducts(PurchaseSearchModel purchaseModel, ProductSearchModel productModel, int count); + Dictionary GetProducts(PurchaseSearchModel purchaseModel); + } } diff --git a/Contracts/ViewModels/PurchaseViewModel.cs b/Contracts/ViewModels/PurchaseViewModel.cs index abfb68b..bd2eede 100644 --- a/Contracts/ViewModels/PurchaseViewModel.cs +++ b/Contracts/ViewModels/PurchaseViewModel.cs @@ -14,7 +14,7 @@ namespace Contracts.ViewModels public DateTime DatePurchase { get; set; } public required Guid UserId { get; set; } public PurchaseStatus Status { get; set; } - public Dictionary PurchaseProducts { get; set; } = new(); - + public Dictionary? PurchaseProducts { get; set; } = new(); + public double Cost { get; set; } } } diff --git a/DataModels/Models/IPurchase.cs b/DataModels/Models/IPurchase.cs index e13e222..d862ed1 100644 --- a/DataModels/Models/IPurchase.cs +++ b/DataModels/Models/IPurchase.cs @@ -11,5 +11,6 @@ namespace DataModels.Models { DateTime DatePurchase { get; } PurchaseStatus Status { get; } + double Cost { get; } } } diff --git a/DatabaseImplement/Implements/PurchaseStorage.cs b/DatabaseImplement/Implements/PurchaseStorage.cs index 7efd5fa..2239727 100644 --- a/DatabaseImplement/Implements/PurchaseStorage.cs +++ b/DatabaseImplement/Implements/PurchaseStorage.cs @@ -53,6 +53,59 @@ namespace DatabaseImplement.Implements public List GetFilteredList(PurchaseSearchModel? model) { using var context = new Database(); + if (!model.CostFrom.HasValue && !model.CostTo.HasValue && !model.DateTo.HasValue && !model.DateFrom.HasValue && !model.Status.HasValue) + { + return new(); + } + + if (model.CostFrom.HasValue && model.CostTo.HasValue) + { + return context.Purchases + .Where(x => x.Cost <= model.CostTo && x.Cost >= model.CostFrom) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + if (model.CostFrom.HasValue) + { + return context.Purchases + .Where(x => x.Cost >= model.CostFrom) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + if (model.CostTo.HasValue) + { + return context.Purchases + .Where(x => x.Cost <= model.CostTo) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + if (model.DateFrom.HasValue && model.DateTo.HasValue) + { + return context.Purchases + .Where(x => x.DatePurchase <= model.DateTo && x.DatePurchase >= model.DateFrom) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + if (model.DateFrom.HasValue) + { + return context.Purchases + .Where(x => x.DatePurchase >= model.DateFrom) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + if (model.DateTo.HasValue) + { + return context.Purchases + .Where(x => x.DatePurchase <= model.DateTo) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } return context.Purchases .Include(x => x.Products) .ThenInclude(x => x.Product) @@ -96,5 +149,64 @@ namespace DatabaseImplement.Implements throw; } } - } + public PurchaseViewModel? AddProducts(PurchaseSearchModel purchaseModel, ProductSearchModel productModel, int count) + { + using var context = new Database(); + using var transaction = context.Database.BeginTransaction(); + try + { + var purchase = context.Purchases.FirstOrDefault(rec => + rec.Id == purchaseModel.Id); + + var product = context.Products.FirstOrDefault(rec => + rec.Id == productModel.Id); + + if (purchase == null) + return null; + + if (product == null) + return null; + + if (count <= 0) + return null; + + context.PurchaseProducts.Add(new PurchaseProducts + { + Purchase = purchase, + Product = product, + Count = count + }); + context.SaveChanges(); + return purchase.GetViewModel; + } + catch { transaction.Rollback(); throw; } + + } + + public Dictionary GetProducts(PurchaseSearchModel model) + { + Dictionary productsDict = new(); + using var context = new Database(); + + var purchase = context.Purchases.FirstOrDefault(rec => + rec.Id == model.Id); + + if (purchase == null) + { + return null; + } + + var purchaseProducts = context.PurchaseProducts + .Where(x => x.PurchaseId == model.Id) + .ToList(); + + foreach (var purchaseProduct in purchaseProducts) + { + productsDict.Add(purchaseProduct.ProductId, purchaseProduct.Count); + } + + return productsDict; + } + + } } diff --git a/DatabaseImplement/Migrations/20240625215017_purchase.Designer.cs b/DatabaseImplement/Migrations/20240625215017_purchase.Designer.cs new file mode 100644 index 0000000..15fe9ea --- /dev/null +++ b/DatabaseImplement/Migrations/20240625215017_purchase.Designer.cs @@ -0,0 +1,495 @@ +// +using System; +using DatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DatabaseImplement.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20240625215017_purchase")] + partial class purchase + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("DatabaseImplement.Models.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("MediaFiles"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("integer"); + + b.Property("IsBeingSold") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("double precision"); + + b.Property("Rate") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Purchase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.Property("DatePurchase") + .HasColumnType("timestamp without time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Purchases"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.PurchaseProducts", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.Property("PurchaseId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("PurchaseId"); + + b.ToTable("PurchaseProducts"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Sell", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DateSell") + .HasColumnType("timestamp without time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Sells"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SellProducts", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.Property("SellId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("SellId"); + + b.ToTable("SellProducts"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Supplier", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Deals") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Suppliers"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SupplierProduct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.Property("SupplierId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("SupplierId"); + + b.ToTable("SupplierProducts"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Supply", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .HasColumnType("timestamp without time zone"); + + b.Property("DateArriving") + .HasColumnType("timestamp without time zone"); + + b.Property("DateComplete") + .HasColumnType("timestamp without time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("double precision"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SupplierId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("SupplierId"); + + b.ToTable("Supplies"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SupplyDoc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("SupplyId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("SupplyDocs"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SupplyProduct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("ProductId") + .HasColumnType("uuid"); + + b.Property("SupplyId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("SupplyId"); + + b.ToTable("SupplyProducts"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Birthday") + .HasColumnType("timestamp without time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("OnlyImportantMails") + .HasColumnType("boolean"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("SecondName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.MediaFile", b => + { + b.HasOne("DatabaseImplement.Models.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Purchase", b => + { + b.HasOne("DatabaseImplement.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.PurchaseProducts", b => + { + b.HasOne("DatabaseImplement.Models.Product", "Product") + .WithMany("PurchaseProducts") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DatabaseImplement.Models.Purchase", "Purchase") + .WithMany("Products") + .HasForeignKey("PurchaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Purchase"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Sell", b => + { + b.HasOne("DatabaseImplement.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SellProducts", b => + { + b.HasOne("DatabaseImplement.Models.Product", "Product") + .WithMany("SellProducts") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DatabaseImplement.Models.Sell", "Sell") + .WithMany("Products") + .HasForeignKey("SellId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Sell"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SupplierProduct", b => + { + b.HasOne("DatabaseImplement.Models.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DatabaseImplement.Models.Supplier", "Supplier") + .WithMany("Products") + .HasForeignKey("SupplierId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Supplier"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Supply", b => + { + b.HasOne("DatabaseImplement.Models.Supplier", "Supplier") + .WithMany() + .HasForeignKey("SupplierId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Supplier"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.SupplyProduct", b => + { + b.HasOne("DatabaseImplement.Models.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DatabaseImplement.Models.Supply", "Supply") + .WithMany("Products") + .HasForeignKey("SupplyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + + b.Navigation("Supply"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.User", b => + { + b.HasOne("DatabaseImplement.Models.Role", "Role") + .WithMany() + .HasForeignKey("RoleId"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Product", b => + { + b.Navigation("PurchaseProducts"); + + b.Navigation("SellProducts"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Purchase", b => + { + b.Navigation("Products"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Sell", b => + { + b.Navigation("Products"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Supplier", b => + { + b.Navigation("Products"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Supply", b => + { + b.Navigation("Products"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DatabaseImplement/Migrations/20240625215017_purchase.cs b/DatabaseImplement/Migrations/20240625215017_purchase.cs new file mode 100644 index 0000000..376cec5 --- /dev/null +++ b/DatabaseImplement/Migrations/20240625215017_purchase.cs @@ -0,0 +1,130 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DatabaseImplement.Migrations +{ + /// + public partial class purchase : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Birthday", + table: "Users", + type: "timestamp without time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "DateComplete", + table: "Supplies", + type: "timestamp without time zone", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DateArriving", + table: "Supplies", + type: "timestamp without time zone", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Date", + table: "Supplies", + type: "timestamp without time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "DateSell", + table: "Sells", + type: "timestamp without time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "DatePurchase", + table: "Purchases", + type: "timestamp without time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AddColumn( + name: "Cost", + table: "Purchases", + type: "double precision", + nullable: false, + defaultValue: 0.0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Cost", + table: "Purchases"); + + migrationBuilder.AlterColumn( + name: "Birthday", + table: "Users", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone"); + + migrationBuilder.AlterColumn( + name: "DateComplete", + table: "Supplies", + type: "timestamp with time zone", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DateArriving", + table: "Supplies", + type: "timestamp with time zone", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Date", + table: "Supplies", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone"); + + migrationBuilder.AlterColumn( + name: "DateSell", + table: "Sells", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone"); + + migrationBuilder.AlterColumn( + name: "DatePurchase", + table: "Purchases", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp without time zone"); + } + } +} diff --git a/DatabaseImplement/Migrations/DatabaseModelSnapshot.cs b/DatabaseImplement/Migrations/DatabaseModelSnapshot.cs index 4956384..db099bf 100644 --- a/DatabaseImplement/Migrations/DatabaseModelSnapshot.cs +++ b/DatabaseImplement/Migrations/DatabaseModelSnapshot.cs @@ -75,8 +75,11 @@ namespace DatabaseImplement.Migrations .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("Cost") + .HasColumnType("double precision"); + b.Property("DatePurchase") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("Status") .HasColumnType("integer"); @@ -137,7 +140,7 @@ namespace DatabaseImplement.Migrations .HasColumnType("uuid"); b.Property("DateSell") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("UserId") .HasColumnType("uuid"); @@ -222,13 +225,13 @@ namespace DatabaseImplement.Migrations .HasColumnType("uuid"); b.Property("Date") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("DateArriving") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("DateComplete") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("Name") .IsRequired() @@ -299,7 +302,7 @@ namespace DatabaseImplement.Migrations .HasColumnType("uuid"); b.Property("Birthday") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp without time zone"); b.Property("Email") .IsRequired() diff --git a/DatabaseImplement/Models/Purchase.cs b/DatabaseImplement/Models/Purchase.cs index aa552b1..e02aec8 100644 --- a/DatabaseImplement/Models/Purchase.cs +++ b/DatabaseImplement/Models/Purchase.cs @@ -23,6 +23,7 @@ namespace DatabaseImplement.Models public DateTime DatePurchase { get; set; } [Required] public Guid UserId { get; set; } + public double Cost { get; set; } [Required] public PurchaseStatus Status { get; private set; } = PurchaseStatus.Unknown; private Dictionary? _purchaseProducts = null; @@ -59,7 +60,8 @@ namespace DatabaseImplement.Models DatePurchase = DatePurchase, UserId = UserId, PurchaseProducts = PurchaseProducts, - Status = Status + Status = Status, + Cost = Cost }; public PurchaseViewModel GetViewModel => new() @@ -68,7 +70,8 @@ namespace DatabaseImplement.Models DatePurchase = DatePurchase, UserId = UserId, PurchaseProducts = PurchaseProducts, - Status = Status + Status = Status, + Cost = Cost }; public static Purchase ToPurchaseFromView(PurchaseViewModel model, Purchase purchase) => new() @@ -77,7 +80,8 @@ namespace DatabaseImplement.Models DatePurchase = model.DatePurchase, UserId = model.UserId, PurchaseProducts = model.PurchaseProducts, - Status = model.Status + Status = model.Status, + Cost = model.Cost }; public static Purchase ToPurchaseFromBinding(PurchaseBindingModel model, Purchase purchase) => new() @@ -86,7 +90,8 @@ namespace DatabaseImplement.Models DatePurchase = model.DatePurchase, UserId = model.UserId, PurchaseProducts = model.PurchaseProducts, - Status = model.Status + Status = model.Status, + Cost = model.Cost }; public void Update(PurchaseBindingModel model) @@ -100,7 +105,9 @@ namespace DatabaseImplement.Models UserId = model.UserId; PurchaseProducts = model.PurchaseProducts; Status = model.Status; - } + Cost = model.Cost; + + } public void UpdateProducts(Database context, PurchaseBindingModel model) { var purchaseProducts = context.PurchaseProducts.Where(rec => diff --git a/RestAPI/Controllers/MediaFileController.cs b/RestAPI/Controllers/MediaFileController.cs index 4dba4d7..d6f1445 100644 --- a/RestAPI/Controllers/MediaFileController.cs +++ b/RestAPI/Controllers/MediaFileController.cs @@ -15,7 +15,7 @@ namespace RestAPI.Controllers private readonly IMediaFileLogic _mediaFileLogic; private readonly IProductLogic _productLogic; private readonly ILogger _logger; - public MediaFileController(ILogger logger, IMediaFileLogic mediaFileLogic, IProductLogic productLogic) + public MediaFileController(ILogger logger, IMediaFileLogic mediaFileLogic, IProductLogic productLogic) { _logger = logger; _mediaFileLogic = mediaFileLogic; diff --git a/RestAPI/Controllers/ProductController.cs b/RestAPI/Controllers/ProductController.cs index 5a875ab..e9feeb3 100644 --- a/RestAPI/Controllers/ProductController.cs +++ b/RestAPI/Controllers/ProductController.cs @@ -44,6 +44,20 @@ namespace RestAPI.Controllers } } + [HttpGet] + public ProductViewModel GetProduct(Guid id) + { + try + { + return _product.ReadElement(new ProductSearchModel() {Id = id}); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения продукта"); + throw; + } + } + [HttpPatch] public IResult Update([FromBody] ProductBindingModel model) { diff --git a/RestAPI/Controllers/PurchaseController.cs b/RestAPI/Controllers/PurchaseController.cs index 2fa172e..3be2e5c 100644 --- a/RestAPI/Controllers/PurchaseController.cs +++ b/RestAPI/Controllers/PurchaseController.cs @@ -1,83 +1,152 @@ -using Microsoft.AspNetCore.Http; +using BusinessLogic.BusinessLogic; +using Contracts.BindingModels; +using Contracts.BusinessLogicContracts; +using Contracts.Exceptions; +using Contracts.SearchModels; +using Contracts.ViewModels; +using DatabaseImplement.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace RestAPI.Controllers { + [Route("[controller]/[action]")] + [ApiController] public class PurchaseController : Controller { - // GET: PurchaseController - public ActionResult Index() - { - return View(); - } + private readonly ILogger _logger; + private readonly IPurchaseLogic _purchaseLogic; - // GET: PurchaseController/Details/5 - public ActionResult Details(int id) + public PurchaseController(ILogger logger, IPurchaseLogic purchaseLogic) { - return View(); + _logger = logger; + _purchaseLogic = purchaseLogic; } - - // GET: PurchaseController/Create - public ActionResult Create() - { - return View(); - } - - // POST: PurchaseController/Create - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult Create(IFormCollection collection) + [HttpGet] + public List? GetList(double? costfrom, double? costto, DateTime? datefrom, DateTime? dateto) { try { - return RedirectToAction(nameof(Index)); + if (costfrom == null && costto == null && datefrom == null && dateto == null) + return _purchaseLogic.ReadElements(null); + + else + return _purchaseLogic.ReadElements(new PurchaseSearchModel() + { + CostFrom = costfrom, + CostTo = costto, + DateFrom = datefrom, + DateTo = dateto + }); } - catch + catch (Exception ex) { - return View(); + _logger.LogError(ex, "Ошибка получения списка продуктов"); + throw; } } - // GET: PurchaseController/Edit/5 - public ActionResult Edit(int id) - { - return View(); - } - - // POST: PurchaseController/Edit/5 - [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult Edit(int id, IFormCollection collection) + [HttpGet] + public PurchaseViewModel Get(Guid id) { try { - return RedirectToAction(nameof(Index)); + return _purchaseLogic.ReadElement(new PurchaseSearchModel() { Id = id }); } - catch + catch (Exception ex) { - return View(); + _logger.LogError(ex, "Ошибка получения продукта"); + throw; } } - - // GET: PurchaseController/Delete/5 - public ActionResult Delete(int id) - { - return View(); - } - - // POST: PurchaseController/Delete/5 [HttpPost] - [ValidateAntiForgeryToken] - public ActionResult Delete(int id, IFormCollection collection) + public PurchaseViewModel Create(Guid UserId) { try { - return RedirectToAction(nameof(Index)); + var purchase = _purchaseLogic.Create(new PurchaseBindingModel() + { + Cost = 0, + DatePurchase = DateTime.Now, + UserId = UserId + }); + + return new PurchaseViewModel() + { + DatePurchase = purchase.DatePurchase, + UserId = purchase.UserId, + Cost = purchase.Cost, + }; } - catch + catch (Exception ex) { - return View(); + _logger.LogError(ex, "Error update purchase"); + return null; } } + + [HttpPatch] + public PurchaseViewModel Update([FromBody] PurchaseBindingModel model) + { + try + { + var res = _purchaseLogic.Update(model); + return new PurchaseViewModel() + { + Id = res.Id, + Cost = res.Cost, + DatePurchase = res.DatePurchase, + PurchaseProducts = res.PurchaseProducts, + UserId = res.UserId, + }; + } + + catch (Exception ex) + { + _logger.LogError(ex, "Error update purchase"); + return null; + } + } + [HttpPatch] + public PurchaseViewModel AddProducts(Guid purchaseId, Guid productId, int count) + { + try + { + var purchase = _purchaseLogic.AddProduct( + new PurchaseSearchModel() + { + Id = purchaseId + }, + new ProductSearchModel() + { + Id = productId + }, + count); + + return new PurchaseViewModel() + { + Id = purchase.Id, + Cost = purchase.Cost, + DatePurchase = purchase.DatePurchase, + PurchaseProducts = purchase.PurchaseProducts, + UserId = purchase.UserId, + }; + } + + catch (Exception ex) + { + _logger.LogError(ex, "Error update purchase"); + return null; + } + } + [HttpGet] + public Dictionary GetProducts(Guid productId) + { + return _purchaseLogic.GetProducts(new PurchaseSearchModel + { + Id = productId, + }); + } } } diff --git a/WebApp/Pages/Cart.cshtml b/WebApp/Pages/Cart.cshtml index 32f767e..93f400c 100644 --- a/WebApp/Pages/Cart.cshtml +++ b/WebApp/Pages/Cart.cshtml @@ -1,4 +1,56 @@ @page @model WebApp.Pages.CartModel @{ -} \ No newline at end of file + ViewData["Title"] = "Cart"; +} +
+

Корзина

+ + @* @if (Model.Amount == 0) + { +

Ваша корзина пуста.

+ } *@ + else + { + + + + + + + + + + + + @* @foreach (var item in Model.CartItems) + { + + + + + + + + } *@ + +
ТоварЦенаКоличествоИтого
+ + @item.Product.Price.ToString("C") + + @((item.Product.Price * item.Quantity).ToString("C")) + +
+ +
+ @*

Итого: @Model.TotalPrice.ToString("C")

*@ +
+ + + } +
\ No newline at end of file diff --git a/WebApp/Pages/Cart.cshtml.cs b/WebApp/Pages/Cart.cshtml.cs index deab2d3..72928b1 100644 --- a/WebApp/Pages/Cart.cshtml.cs +++ b/WebApp/Pages/Cart.cshtml.cs @@ -1,13 +1,35 @@ +using Contracts.ViewModels; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Diagnostics.Eventing.Reader; +using WebApp.Helpers; namespace WebApp.Pages { + [Authorize(Roles = Roles.User)] public class CartModel : PageModel { - public void OnGet() + public PurchaseViewModel purchaseModel = null; + public Dictionary Products { get; set; } + public void OnGet(Guid id, int count) + { + if (purchaseModel == null) + { + purchaseModel = APIClient.GetRequest($"Purchase/Create/{this.GetUserId()}"); + + APIClient.GetRequest($"Purchase/AddProducts?purchaseId={purchaseModel.Id}?productId={id}?count={count}"); + } + purchaseModel = APIClient.GetRequest($"Purchase/Get/"); + + Products = APIClient.GetRequest>($"Purchase/GetProducts?id={purchaseModel.Id}"); + } + public IActionResult OnPostAsync() { + + + return RedirectToAction(""); } } -} +} \ No newline at end of file diff --git a/WebApp/Pages/Index.cshtml b/WebApp/Pages/Index.cshtml index b19ad67..c8411ec 100644 --- a/WebApp/Pages/Index.cshtml +++ b/WebApp/Pages/Index.cshtml @@ -7,7 +7,7 @@