Внутренняя логика

This commit is contained in:
DyCTaTOR 2024-10-27 15:16:44 +03:00
parent 3a02a9e7f2
commit 40971f2997
22 changed files with 655 additions and 5 deletions

View File

@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
@ -9,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\WinFormsLibrary1\WinFormsLibrary1.csproj" /> <ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,103 @@
using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogics.BusinessLogics
{
public class ProductLogic : IProductLogic
{
private readonly IProductStorage _productStorage;
public ProductLogic(IProductStorage productStorage)
{
_productStorage = productStorage;
}
public List<ProductViewModel> ReadList(ProductSearchModel? model)
{
var list = model == null ? _productStorage.GetFullList() : _productStorage.GetFilteredList(model);
if (list == null)
{
return null;
}
return list;
}
public ProductViewModel ReadElement(ProductSearchModel? model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
var element = _productStorage.GetElement(model);
if (element == null)
{
return null;
}
return element;
}
public bool Create(ProductBindingModel model)
{
CheckModel(model);
if (_productStorage.Insert(model) == null)
{
return false;
}
return true;
}
public bool Update(ProductBindingModel model)
{
CheckModel(model);
if (_productStorage.Update(model) == null)
{
return false;
}
return true;
}
public bool Delete(ProductBindingModel model)
{
CheckModel(model, false);
if (_productStorage.Delete(model) == null)
{
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 ArgumentException("Введите название продукта", nameof(model.Name));
}
if (string.IsNullOrEmpty(model.Description))
{
throw new ArgumentException("Введите описание продукта", nameof(model.Description));
}
if (model.Category == null)
{
throw new ArgumentException("Введите категорию продукта", nameof(model.Category));
}
if (model.CountOnStorage < 0)
{
throw new ArgumentException("Укажите валидное число продукта на складе", nameof(model.CountOnStorage));
}
}
}
}

View File

@ -0,0 +1,19 @@
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BindingModels
{
public class ProductBindingModel : IProductModel
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public Category Category { get; set; }
public int CountOnStorage { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.BusinessLogicContracts
{
public interface IProductLogic
{
List<ProductViewModel>? ReadList(ProductSearchModel? model);
ProductViewModel? ReadElement(ProductSearchModel? model);
bool Create(ProductBindingModel model);
bool Update(ProductBindingModel model);
bool Delete(ProductBindingModel model);
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,16 @@
using Models.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.SearchModels
{
public class ProductSearchModel
{
public int? Id { get; set; }
public string? Name { get; set; }
public Category? Category { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.StorageContracts
{
public interface IProductStorage
{
List<ProductViewModel> GetFullList();
List<ProductViewModel> GetFilteredList(ProductSearchModel model);
ProductViewModel? GetElement(ProductSearchModel model);
ProductViewModel? Insert(ProductBindingModel model);
ProductViewModel? Update(ProductBindingModel model);
ProductViewModel? Delete(ProductBindingModel model);
}
}

View File

@ -0,0 +1,24 @@
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contracts.ViewModels
{
public class ProductViewModel : IProductModel
{
public int Id { get; set; }
[DisplayName("Название")]
public string Name { get; set; } = string.Empty;
[DisplayName("Описание")]
public string Description { get; set; } = string.Empty;
[DisplayName("Категория продукта")]
public Category Category { get; set; }
[DisplayName("Количество товаров на складе")]
public int CountOnStorage { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace DatabaseImplement
{
public class Database : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=kop;Username=postgres;Password=postgres");
}
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,78 @@
using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Implements
{
public class ProductStorage : IProductStorage
{
public List<ProductViewModel> GetFullList()
{
using var context = new Database();
return context.Products.Select(x => x.GetViewModel).ToList();
}
public List<ProductViewModel> GetFilteredList(ProductSearchModel model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new Database();
return context.Products
.Where(x => x.Name == model.Name)
.Select(x => x.GetViewModel)
.ToList();
}
public ProductViewModel? GetElement(ProductSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new Database();
return context.Products.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
public ProductViewModel? Insert(ProductBindingModel model)
{
var newProvider = Product.Create(model);
if (newProvider == null) return null;
using var context = new Database();
context.Products.Add(newProvider);
context.SaveChanges();
return newProvider.GetViewModel;
}
public ProductViewModel? Update(ProductBindingModel model)
{
using var context = new Database();
var provider = context.Products.FirstOrDefault(x => x.Id == model.Id);
if (provider == null) return null;
provider.Update(model);
context.SaveChanges();
return provider.GetViewModel;
}
public ProductViewModel? Delete(ProductBindingModel model)
{
using var context = new Database();
var element = context.Products.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Products.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,56 @@
// <auto-generated />
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("20241027113242_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Category")
.HasColumnType("integer");
b.Property<int>("CountOnStorage")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Products");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Products",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
Category = table.Column<int>(type: "integer", nullable: false),
CountOnStorage = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Products");
}
}
}

View File

@ -0,0 +1,53 @@
// <auto-generated />
using DatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DatabaseImplement.Migrations
{
[DbContext(typeof(Database))]
partial class DatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DatabaseImplement.Models.Product", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Category")
.HasColumnType("integer");
b.Property<int>("CountOnStorage")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Products");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,64 @@
using Contracts.BindingModels;
using Contracts.ViewModels;
using Models.Enums;
using Models.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DatabaseImplement.Models
{
public class Product : IProductModel
{
public int Id { get; private set; }
[Required]
public string Name { get; private set; } = string.Empty;
[Required]
public string Description { get; private set; } = string.Empty;
[Required]
public Category Category { get; private set; }
[Required]
public int CountOnStorage { get; private set; }
public static Product? Create(ProductBindingModel model)
{
if (model == null) return null;
return new Product
{
Id = model.Id,
Name = model.Name,
Description = model.Description,
Category = model.Category,
CountOnStorage = model.CountOnStorage,
};
}
public void Update(ProductBindingModel model)
{
if (model == null) return;
Name = model.Name;
Description = model.Description;
Category = model.Category;
CountOnStorage = model.CountOnStorage;
}
public ProductViewModel GetViewModel => new()
{
Id = Id,
Name = Name,
Description = Description,
Category = Category,
CountOnStorage = CountOnStorage,
};
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Enums
{
public enum Category
{
None,
Food,
Clothes,
House,
Health,
Technic,
Gift,
Sport
}
}

View File

@ -0,0 +1,7 @@
namespace Models
{
public interface IId
{
int Id { get;}
}
}

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,17 @@
using Models.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Models
{
public interface IProductModel : IId
{
string Name { get;}
string Description { get;}
Category Category { get;}
int CountOnStorage { get;}
}
}

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Library14Petrushin" Version="1.0.0" />
<PackageReference Include="Library15Gerimovich" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Businesslogic\BusinessLogics.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
<ProjectReference Include="..\WinFormsLibrary1\Components.csproj" />
</ItemGroup>
</Project>

View File

@ -3,9 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.10.34916.146 VisualStudioVersion = 17.10.34916.146
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsLibrary1", "WinFormsLibrary1\WinFormsLibrary1.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "WinFormsLibrary1\Components.csproj", "{4F13F436-1BE0-4F8D-A720-FCBF3893BA55}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsApp1", "WinFormsApp1\WinFormsApp1.csproj", "{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Forms", "WinFormsApp1\Forms.csproj", "{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Models", "Models\Models.csproj", "{C4816B78-EBAF-4183-8775-1180D91250D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogics", "Businesslogic\BusinessLogics.csproj", "{753AC945-F64F-4A41-9036-6450AAB5A890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "Contracts\Contracts.csproj", "{027FB9BF-E927-4C34-AFAD-C71EB03398EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseImplement", "DatabaseImplement\DatabaseImplement.csproj", "{02E84641-9C21-43C3-99CD-765878F8C8F6}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -21,6 +29,22 @@ Global
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.Build.0 = Release|Any CPU {4B1A0E96-B60A-4D73-B4AB-CF5157E593E5}.Release|Any CPU.Build.0 = Release|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4816B78-EBAF-4183-8775-1180D91250D5}.Release|Any CPU.Build.0 = Release|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{753AC945-F64F-4A41-9036-6450AAB5A890}.Release|Any CPU.Build.0 = Release|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{027FB9BF-E927-4C34-AFAD-C71EB03398EE}.Release|Any CPU.Build.0 = Release|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02E84641-9C21-43C3-99CD-765878F8C8F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -5,6 +5,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>