Логика, контракты, круд короче

This commit is contained in:
the 2024-06-22 18:13:07 +04:00
parent 5f76bf2750
commit 644b5668ab
8 changed files with 502 additions and 9 deletions

View File

@ -15,33 +15,111 @@ namespace BusinessLogic.BusinessLogic
public class ProductLogic : IProductLogic public class ProductLogic : IProductLogic
{ {
private readonly IProductStorage _productStorage; private readonly IProductStorage _productStorage;
public ProductLogic(IProductStorage productStorage) private readonly ILogger _logger;
public ProductLogic(IProductStorage productStorage, ILogger<ProductLogic> logger)
{ {
_productStorage = productStorage; _productStorage = productStorage;
_logger = logger;
} }
public bool Create(ProductBindingModel model) public bool Create(ProductBindingModel model)
{ {
throw new NotImplementedException(); CheckModel(model);
if (_productStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
} }
public bool Delete(ProductBindingModel model) public bool Delete(ProductBindingModel model)
{ {
throw new NotImplementedException(); CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_productStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
} }
public ProductViewModel? ReadElement(ProductSearchModel model) public ProductViewModel? ReadElement(ProductSearchModel model)
{ {
throw new NotImplementedException(); if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Name:{Name}.Id:{ Id}", model.Name, model.Id);
var element = _productStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
} }
public List<ProductViewModel>? ReadList(ProductSearchModel? model) public List<ProductViewModel>? ReadList(ProductSearchModel? model)
{ {
throw new NotImplementedException(); _logger.LogInformation("ReadList. Name:{Name}.Id:{ Id}", model?.Name, model?.Id);
var list = model == null ? _productStorage.GetFullList() : _productStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
} }
public bool Update(ProductBindingModel model) public bool Update(ProductBindingModel model)
{ {
throw new NotImplementedException(); CheckModel(model);
if (_productStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(ProductBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Нет названия продукта", nameof(model.Name));
}
if (model.Price < 0)
{
throw new Exception("Цена продукта не может быть ниже нуля");
}
if (model.Amount < 0)
{
throw new Exception("Кол-во продуктов не может быть ниже нуля");
}
if (model.Rate < 0.0 || model.Rate > 5.0)
{
throw new Exception("Рейтинг продукта должен быть в пределах от 0.0 до 5.0");
}
_logger.LogInformation("Product. ProductName:{Name}.Price:{ Price}. Id: { Id}", model.Name, model.Price, model.Id);
var element = _productStorage.GetElement(new ProductSearchModel
{
Name = model.Name
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Продукт с таким названием уже есть");
}
} }
} }
} }

View File

@ -0,0 +1,114 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.BusinessLogic
{
public class SupplierLogic : ISupplierLogic
{
private readonly ISupplierStorage _supplierStorage;
private readonly ILogger _logger;
public SupplierLogic(ISupplierStorage supplierStorage, ILogger<SupplierLogic> logger)
{
_supplierStorage = supplierStorage;
_logger = logger;
}
public bool Create(SupplierBindingModel model)
{
CheckModel(model);
if (_supplierStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(SupplierBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_supplierStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public SupplierViewModel? ReadElement(SupplierSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Name:{Name}.Id:{ Id}", model.Name, model.Id);
var element = _supplierStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<SupplierViewModel>? ReadList(SupplierSearchModel? model)
{
_logger.LogInformation("ReadList. Name:{Name}.Id:{ Id}", model?.Name, model?.Id);
var list = model == null ? _supplierStorage.GetFullList() : _supplierStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(SupplierBindingModel model)
{
CheckModel(model);
if (_supplierStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(SupplierBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Нет названия поставщика", nameof(model.Name));
}
if (model.Deals < 0)
{
throw new Exception("Кол-во сделок не может быть меньше нуля");
}
foreach(var item in model.AvailibleProducts.Values)
{
if (item.Item2 < 0)
{
throw new Exception("Кол-во доступных продуктов не должно быть отрицательным");
}
}
}
}
}

View File

@ -0,0 +1,105 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.BusinessLogic
{
public class SupplyLogic : ISupplyLogic
{
private readonly ISupplyStorage _supplyStorage;
private readonly ILogger _logger;
public SupplyLogic(ISupplyStorage supplyStorage, ILogger<SupplyLogic> logger)
{
_supplyStorage = supplyStorage;
_logger = logger;
}
public bool Create(SupplyBindingModel model)
{
CheckModel(model);
if (_supplyStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(SupplyBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_supplyStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public SupplyViewModel? ReadElement(SupplySearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Name:{Name}.Id:{ Id}", model.Name, model.Id);
var element = _supplyStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<SupplyViewModel>? ReadList(SupplySearchModel? model)
{
_logger.LogInformation("ReadList. Name:{Name}.Id:{ Id}", model?.Name, model?.Id);
var list = model == null ? _supplyStorage.GetFullList() : _supplyStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(SupplyBindingModel model)
{
CheckModel(model);
if (_supplyStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(SupplyBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Нет названия поставки", nameof(model.Name));
}
}
}
}

View File

@ -12,5 +12,7 @@ namespace Contracts.SearchModels
public string? Name { get; set; } public string? Name { get; set; }
public double? Price { get; set; } public double? Price { get; set; }
public double? Rate { get; set; } public double? Rate { get; set; }
public int? Amount { get; set; }
public bool? IsBeingSold { get; set; }
} }
} }

View File

@ -10,6 +10,7 @@ namespace Contracts.SearchModels
public class SupplySearchModel public class SupplySearchModel
{ {
public Guid? Id { get; set; } public Guid? Id { get; set; }
public string Name { get; set; } = string.Empty;
public SupplyStatus? Status { get; set; } public SupplyStatus? Status { get; set; }
public DateTime? DateStart { get; set; } public DateTime? DateStart { get; set; }
public DateTime? DateEnd { get; set; } public DateTime? DateEnd { get; set; }

View File

@ -11,7 +11,7 @@ namespace Contracts.ViewModels
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public int Price { get; set; } public double Price { get; set; }
public double Rating { get; set; } public double Rating { get; set; }
public bool IsBeingSold { get; set; } public bool IsBeingSold { get; set; }
public int Amount { get; set; } public int Amount { get; set; }

View File

@ -0,0 +1,161 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
public class ProductStorage : IProductStorage
{
public ProductViewModel? Delete(ProductBindingModel model)
{
using var context = new Database();
var element = context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Products.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public ProductViewModel? GetElement(ProductSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new Database();
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public List<ProductViewModel> GetFilteredList(ProductSearchModel model)
{
if (!model.IsBeingSold.HasValue && !model.Price.HasValue && !model.Rate.HasValue && !model.Amount.HasValue && string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new Database();
if (model.Price.HasValue)
{
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.Where(x => x.Price <= model.Price)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
if (model.Rate.HasValue)
{
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.Where(x => x.Rate <= model.Rate)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
if (model.Amount.HasValue && model.IsBeingSold.HasValue)
{
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.Where(x => x.IsBeingSold == model.IsBeingSold && x.Amount >= model.Amount)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.Where(x => x.Name == model.Name)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<ProductViewModel> GetFullList()
{
using var context = new Database();
return context.Products
.Include(x => x.Name)
.Include(x => x.Price)
.Include(x => x.IsBeingSold)
.Include(x => x.Rate)
.Include(x => x.Amount)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public ProductViewModel? Insert(ProductBindingModel model)
{
using var context = new Database();
var newProduct = Product.Create(context, model);
if (newProduct == null)
{
return null;
}
context.Products.Add(newProduct);
context.SaveChanges();
return newProduct.GetViewModel;
}
public ProductViewModel? Update(ProductBindingModel model)
{
using var context = new Database();
using var transaction = context.Database.BeginTransaction();
try
{
var product = context.Products.FirstOrDefault(rec =>
rec.Id == model.Id);
if (product == null)
{
return null;
}
product.Update(model);
context.SaveChanges();
transaction.Commit();
return product.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

View File

@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace DatabaseImplement.Models namespace DatabaseImplement.Models
{ {
@ -55,7 +56,21 @@ namespace DatabaseImplement.Models
Amount = model.Amount Amount = model.Amount
}; };
public void Update(ProductBindingModel model, Product product) public static Product Create(Database context, ProductBindingModel model)
{
return new Product()
{
Id = model.Id,
Name = model.Name,
Price = model.Price,
Rate = model.Rate,
IsBeingSold = model.IsBeingSold,
Amount = model.Amount
};
}
public void Update(ProductBindingModel model)
{ {
if (model is null) if (model is null)
{ {
@ -68,5 +83,22 @@ namespace DatabaseImplement.Models
IsBeingSold = model.IsBeingSold; IsBeingSold = model.IsBeingSold;
Amount = model.Amount; Amount = model.Amount;
} }
public ProductViewModel GetViewModel
{
get
{
var context = new Database();
return new()
{
Id = Id,
Name = Name,
Price = Price,
IsBeingSold = IsBeingSold,
Rating = Rate,
Amount = Amount
};
}
}
} }
} }