it's over...
This commit is contained in:
parent
83d1365b68
commit
62372eb2a4
@ -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<PurchaseLogic> logger)
|
||||
public PurchaseLogic(IPurchaseStorage purchaseStorage, IProductStorage productStorage, ILogger<PurchaseLogic> logger)
|
||||
{
|
||||
_purchaseStorage = purchaseStorage;
|
||||
_logger = logger;
|
||||
}
|
||||
_productStorage = productStorage;
|
||||
|
||||
}
|
||||
|
||||
public PurchaseViewModel Create(PurchaseBindingModel model)
|
||||
{
|
||||
@ -76,7 +80,7 @@ namespace BusinessLogic.BusinessLogic
|
||||
public List<PurchaseViewModel> 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<Guid, int> GetProducts(PurchaseSearchModel model)
|
||||
{
|
||||
return _purchaseStorage.GetProducts(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Contracts.BindingModels
|
||||
public DateTime DatePurchase { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public PurchaseStatus Status { get; set; }
|
||||
public Dictionary<Guid, (IProduct, int)> PurchaseProducts { get; set; } = new();
|
||||
public Dictionary<Guid, (IProduct, int)>? PurchaseProducts { get; set; } = new();
|
||||
public double Cost { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -20,5 +20,7 @@ namespace Contracts.BusinessLogicContracts
|
||||
List<PurchaseViewModel> ReadElements(PurchaseSearchModel? model);
|
||||
|
||||
PurchaseViewModel Delete(PurchaseSearchModel model);
|
||||
}
|
||||
PurchaseViewModel AddProduct(PurchaseSearchModel purchase, ProductSearchModel product, int count);
|
||||
Dictionary<Guid, int> GetProducts(PurchaseSearchModel model);
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -21,5 +21,7 @@ namespace Contracts.StorageContracts
|
||||
PurchaseViewModel? Update(PurchaseBindingModel model);
|
||||
|
||||
PurchaseViewModel? Delete(PurchaseSearchModel model);
|
||||
}
|
||||
PurchaseViewModel? AddProducts(PurchaseSearchModel purchaseModel, ProductSearchModel productModel, int count);
|
||||
Dictionary<Guid, int> GetProducts(PurchaseSearchModel purchaseModel);
|
||||
}
|
||||
}
|
||||
|
@ -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<Guid, (IProduct, int)> PurchaseProducts { get; set; } = new();
|
||||
|
||||
public Dictionary<Guid, (IProduct, int)>? PurchaseProducts { get; set; } = new();
|
||||
public double Cost { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,6 @@ namespace DataModels.Models
|
||||
{
|
||||
DateTime DatePurchase { get; }
|
||||
PurchaseStatus Status { get; }
|
||||
double Cost { get; }
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,59 @@ namespace DatabaseImplement.Implements
|
||||
public List<PurchaseViewModel> 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<Guid, int> GetProducts(PurchaseSearchModel model)
|
||||
{
|
||||
Dictionary<Guid, int> 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
495
DatabaseImplement/Migrations/20240625215017_purchase.Designer.cs
generated
Normal file
495
DatabaseImplement/Migrations/20240625215017_purchase.Designer.cs
generated
Normal file
@ -0,0 +1,495 @@
|
||||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("Image")
|
||||
.IsRequired()
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.ToTable("MediaFiles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Product", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsBeingSold")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<double>("Rate")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Purchase", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<double>("Cost")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<DateTime>("DatePurchase")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Purchases");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.PurchaseProducts", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("PurchaseId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.HasIndex("PurchaseId");
|
||||
|
||||
b.ToTable("PurchaseProducts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Role", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Roles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Sell", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateSell")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<Guid?>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Sells");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.SellProducts", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SellId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.HasIndex("SellId");
|
||||
|
||||
b.ToTable("SellProducts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Supplier", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Deals")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Suppliers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.SupplierProduct", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SupplierId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.HasIndex("SupplierId");
|
||||
|
||||
b.ToTable("SupplierProducts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.Supply", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<DateTime?>("DateArriving")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<DateTime?>("DateComplete")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("SupplierId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SupplierId");
|
||||
|
||||
b.ToTable("Supplies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.SupplyDoc", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("SupplyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SupplyDocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.SupplyProduct", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("ProductId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("SupplyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProductId");
|
||||
|
||||
b.HasIndex("SupplyId");
|
||||
|
||||
b.ToTable("SupplyProducts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DatabaseImplement.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("Birthday")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("OnlyImportantMails")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("RoleId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
130
DatabaseImplement/Migrations/20240625215017_purchase.cs
Normal file
130
DatabaseImplement/Migrations/20240625215017_purchase.cs
Normal file
@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DatabaseImplement.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class purchase : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Birthday",
|
||||
table: "Users",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateComplete",
|
||||
table: "Supplies",
|
||||
type: "timestamp without time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateArriving",
|
||||
table: "Supplies",
|
||||
type: "timestamp without time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Date",
|
||||
table: "Supplies",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateSell",
|
||||
table: "Sells",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DatePurchase",
|
||||
table: "Purchases",
|
||||
type: "timestamp without time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp with time zone");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "Cost",
|
||||
table: "Purchases",
|
||||
type: "double precision",
|
||||
nullable: false,
|
||||
defaultValue: 0.0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Cost",
|
||||
table: "Purchases");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Birthday",
|
||||
table: "Users",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateComplete",
|
||||
table: "Supplies",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateArriving",
|
||||
table: "Supplies",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Date",
|
||||
table: "Supplies",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DateSell",
|
||||
table: "Sells",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "DatePurchase",
|
||||
table: "Purchases",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldType: "timestamp without time zone");
|
||||
}
|
||||
}
|
||||
}
|
@ -75,8 +75,11 @@ namespace DatabaseImplement.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<double>("Cost")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<DateTime>("DatePurchase")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
@ -137,7 +140,7 @@ namespace DatabaseImplement.Migrations
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateSell")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<Guid?>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
@ -222,13 +225,13 @@ namespace DatabaseImplement.Migrations
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<DateTime?>("DateArriving")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<DateTime?>("DateComplete")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
@ -299,7 +302,7 @@ namespace DatabaseImplement.Migrations
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("Birthday")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
|
@ -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<Guid, (IProduct, int)>? _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 =>
|
||||
|
@ -15,7 +15,7 @@ namespace RestAPI.Controllers
|
||||
private readonly IMediaFileLogic _mediaFileLogic;
|
||||
private readonly IProductLogic _productLogic;
|
||||
private readonly ILogger _logger;
|
||||
public MediaFileController(ILogger<MediaFileLogic> logger, IMediaFileLogic mediaFileLogic, IProductLogic productLogic)
|
||||
public MediaFileController(ILogger<MediaFileController> logger, IMediaFileLogic mediaFileLogic, IProductLogic productLogic)
|
||||
{
|
||||
_logger = logger;
|
||||
_mediaFileLogic = mediaFileLogic;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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<PurchaseController> 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<PurchaseViewModel>? 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<Guid, int> GetProducts(Guid productId)
|
||||
{
|
||||
return _purchaseLogic.GetProducts(new PurchaseSearchModel
|
||||
{
|
||||
Id = productId,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,56 @@
|
||||
@page
|
||||
@model WebApp.Pages.CartModel
|
||||
@{
|
||||
}
|
||||
ViewData["Title"] = "Cart";
|
||||
}
|
||||
<div class="container my-5">
|
||||
<h1>Корзина</h1>
|
||||
|
||||
@* @if (Model.Amount == 0)
|
||||
{
|
||||
<p>Ваша корзина пуста.</p>
|
||||
} *@
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Товар</th>
|
||||
<th>Цена</th>
|
||||
<th>Количество</th>
|
||||
<th>Итого</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@* @foreach (var item in Model.CartItems)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="data:image/png;base64,@Convert.ToBase64String(Model.GetMediaByProduct(item.Product))" class="img-fluid me-3" style="max-height: 50px;" alt="@item.Product.Name">
|
||||
<a asp-page="ProductDetails" asp-route-id="@item.Product.Id">@item.Product.Name</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>@item.Product.Price.ToString("C")</td>
|
||||
<td>
|
||||
<input type="number" class="form-control" value="@item.Quantity" min="1" max="100" onchange="updateCartItem('@item.Product.Id', this.value)">
|
||||
</td>
|
||||
<td>@((item.Product.Price * item.Quantity).ToString("C"))</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" onclick="removeFromCart('@item.Product.Id')">Удалить</button>
|
||||
</td>
|
||||
</tr>
|
||||
} *@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
@* <h3>Итого: @Model.TotalPrice.ToString("C")</h3> *@
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<a asp-page="Checkout" class="btn btn-primary">Оформить заказ</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -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<Guid, int> Products { get; set; }
|
||||
public void OnGet(Guid id, int count)
|
||||
{
|
||||
if (purchaseModel == null)
|
||||
{
|
||||
purchaseModel = APIClient.GetRequest<PurchaseViewModel>($"Purchase/Create/{this.GetUserId()}");
|
||||
|
||||
APIClient.GetRequest<PurchaseViewModel>($"Purchase/AddProducts?purchaseId={purchaseModel.Id}?productId={id}?count={count}");
|
||||
}
|
||||
purchaseModel = APIClient.GetRequest<PurchaseViewModel>($"Purchase/Get/");
|
||||
|
||||
Products = APIClient.GetRequest<Dictionary<Guid, int>>($"Purchase/GetProducts?id={purchaseModel.Id}");
|
||||
}
|
||||
public IActionResult OnPostAsync()
|
||||
{
|
||||
|
||||
|
||||
|
||||
return RedirectToAction("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<!-- Шапка -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">Catalog</a>
|
||||
<a asp-page="Index" class="navbar-brand">Catalog</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
@ -31,12 +31,12 @@
|
||||
</form>
|
||||
<div class="form-group ms-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<input type="range" step="1000" min="0" max="10000" value="" class="custom-range me-2" id="priceFrom">
|
||||
<label for="priceFrom">От: <span id="priceLabelFrom">50 000</span> руб.</label>
|
||||
<input type="range" step="1" min="0" max="100" value="" class="custom-range me-2" id="priceFrom">
|
||||
<label asp-for="ProductsModel" s for="pricefrom">От: <span id="priceLabelFrom"></span> руб.</label>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<input type="range" step="1000" min="0" max="100000" value="" class="custom-range me-2" id="priceTo">
|
||||
<label for="priceTo">До: <span id="priceLabelTo">50 000</span> руб.</label>
|
||||
<input type="range" step="1" min="0" max="100" value="" class="custom-range me-2" id="priceTo">
|
||||
<label asp-for="ProductsModel" for="priceto">До: <span id="priceLabelTo"></span> руб.</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -54,8 +54,31 @@
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">@weapon.Name</h5>
|
||||
<p class="card-text">Цена: @weapon.Price руб.</p>
|
||||
<a href="#" class="btn btn-primary">В корзину</a>
|
||||
<a href="#" class="btn btn-secondary">Просмотр</a>
|
||||
|
||||
<div class="star-rating">
|
||||
@for (int i = 0; i < (int)Math.Round(@weapon.Rate); i++)
|
||||
{
|
||||
<span class="filled-star">★</span>
|
||||
}
|
||||
@for (int i = 0; i < 5 - (int)Math.Round(@weapon.Rate); i++)
|
||||
{
|
||||
<span class="empty-star">★</span>
|
||||
}
|
||||
(@weapon.Rate)
|
||||
</div>
|
||||
|
||||
@if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<a asp-page="Cart" asp-route-id="@weapon.Id" asp-route-count=1 class="btn btn-primary">To cart</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a asp-page="Login" asp-route-count=1 class="btn btn-primary">To cart</a>
|
||||
}
|
||||
<a asp-page="ProductPage" asp-route-id="@weapon.Id" class="btn btn-secondary">View Product</a>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,7 +25,7 @@ namespace WebApp.Pages
|
||||
request += $"?priceto={priceto}";
|
||||
|
||||
ProductsModel = APIClient.GetRequest<List<ProductViewModel>>(request);
|
||||
MediaByProductsModel = APIClient.GetRequest<Dictionary<Guid, List<MediaFileViewModel>>>($"MediaFile/GetByProducts?");
|
||||
MediaByProductsModel = APIClient.GetRequest<Dictionary<Guid, List<MediaFileViewModel>>>($"MediaFile/GetByProducts");
|
||||
}
|
||||
public byte[] GetMediaByProduct(ProductViewModel productModel)
|
||||
{
|
||||
|
69
WebApp/Pages/ProductPage.cshtml
Normal file
69
WebApp/Pages/ProductPage.cshtml
Normal file
@ -0,0 +1,69 @@
|
||||
@page
|
||||
@model WebApp.Pages.ProductPageModel
|
||||
@{
|
||||
ViewData["Title"] = "Product Page";
|
||||
}
|
||||
<!-- Шапка -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container">
|
||||
<a asp-page="Index" class="navbar-brand">Catalog</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container my-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<img src="data:image/png;base64,@Convert.ToBase64String(Model.GetMediaByProduct(Model.productModel))" class="img-fluid" alt="@Model.productModel.Name">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h1>@Model.productModel.Name</h1>
|
||||
<div class="star-rating">
|
||||
@for (int i = 0; i < (int)Math.Round(@Model.productModel.Rate); i++)
|
||||
{
|
||||
<span class="filled-star">★</span>
|
||||
}
|
||||
@for (int i = 0; i < 5 - (int)Math.Round(@Model.productModel.Rate); i++)
|
||||
{
|
||||
<span class="empty-star">★</span>
|
||||
}
|
||||
(@Model.productModel.Rate)
|
||||
</div>
|
||||
<p class="lead">Цена: @Model.productModel.Price руб.</p>
|
||||
<p>Количество товара на складе: @Model.productModel.Amount</p>
|
||||
|
||||
@if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<form method="post">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<input type="hidden" name="id" value="@Model.productModel.Id" />
|
||||
<input type="number" name="count" min="1" max="@Model.productModel.Amount" value="1" class="form-control w-auto" />
|
||||
<button type="submit" class="btn btn-primary me-2">В корзину</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<label for="quantity" class="me-2">Количество:</label>
|
||||
<input type="number" id="quantity" name="quantity" min="1" max="@Model.productModel.Amount" value="1" class="form-control w-auto">
|
||||
</div>
|
||||
<a asp-page="Login" class="btn btn-primary me-2">
|
||||
В корзину
|
||||
</a>
|
||||
|
||||
}
|
||||
<button class="btn btn-secondary">Купить сейчас</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-5">
|
||||
<div class="col">
|
||||
<h2>Описание</h2>
|
||||
<p>@Model.productModel.Amount</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
43
WebApp/Pages/ProductPage.cshtml.cs
Normal file
43
WebApp/Pages/ProductPage.cshtml.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using Contracts.BindingModels;
|
||||
using Contracts.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace WebApp.Pages
|
||||
{
|
||||
public class ProductPageModel : PageModel
|
||||
{
|
||||
public PurchaseViewModel purchaseModel { get; set; }
|
||||
public ProductViewModel productModel { get; set; }
|
||||
public MediaFileViewModel mediaFileModel { get; set; }
|
||||
public Dictionary<Guid, List<MediaFileViewModel>> MediaByProductsModel { get; set; }
|
||||
public int Amount { get; set; } // Ñâîéñòâî äëÿ õðàíåíèÿ êîëè÷åñòâà òîâàðà
|
||||
public void OnGet(Guid id)
|
||||
{
|
||||
productModel = APIClient.GetRequest<ProductViewModel>($"Product/GetProduct?id={id}");
|
||||
}
|
||||
public byte[] GetMediaByProduct(ProductViewModel productModel)
|
||||
{
|
||||
MediaByProductsModel = APIClient.GetRequest<Dictionary<Guid, List<MediaFileViewModel>>>($"MediaFile/GetByProducts");
|
||||
MediaByProductsModel.TryGetValue(productModel.Id, out List<MediaFileViewModel> models);
|
||||
return models[0].Image;
|
||||
}
|
||||
public IActionResult OnPostAsync(Guid id, int count)
|
||||
{
|
||||
Amount = count;
|
||||
if (purchaseModel == null)
|
||||
{
|
||||
var model = new PurchaseBindingModel()
|
||||
{
|
||||
Cost = 0,
|
||||
DatePurchase = DateTime.Now,
|
||||
Status = 0,
|
||||
UserId = new Guid(this.GetUserId())
|
||||
};
|
||||
//purchaseModel = APIClient.PostRequest<PurchaseBindingModel>($"Purchase/Create", model);
|
||||
}
|
||||
APIClient.GetRequest<PurchaseViewModel>($"Purchase/AddProducts?purchaseId={purchaseModel.Id}?productId={id}?count={count}");
|
||||
return RedirectToPage("Cart");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
html {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@ -25,4 +25,17 @@ body {
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.star-rating span {
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filled-star {
|
||||
color: gold;
|
||||
}
|
||||
|
||||
.empty-star {
|
||||
color: gray;
|
||||
}
|
Loading…
Reference in New Issue
Block a user