Compare commits

...

14 Commits

Author SHA1 Message Date
Илья Федотов
b47ed95105 Base.03 2024-04-07 10:47:01 +04:00
Илья Федотов
76e115480c Base.02 2024-04-03 16:55:56 +04:00
Илья Федотов
0bee166077 Base.01 2024-03-22 09:14:00 +04:00
Илья Федотов
da1050a0cc Base.05 2024-03-21 19:57:27 +04:00
Илья Федотов
b757176d0b Base.04 2024-03-16 19:03:11 +04:00
Илья Федотов
91bbb0a239 Base.03 2024-03-16 18:07:46 +04:00
Илья Федотов
4ec14f7a2b Base.02 2024-03-15 14:49:38 +04:00
Илья Федотов
2e5afa7f85 Base.01 2024-03-02 16:10:45 +04:00
Илья Федотов
ab7d28ebc2 Base.06 2024-03-02 15:29:22 +04:00
Илья Федотов
5c7bc07585 Base.05 2024-02-26 20:28:10 +04:00
Илья Федотов
a7446a549b Base.04 2024-02-25 18:12:09 +04:00
Илья Федотов
bb8f28e937 Base.03 2024-02-25 18:07:14 +04:00
Илья Федотов
e04c4a3165 Base.02 2024-02-25 16:50:29 +04:00
Илья Федотов
520b361e50 Base.01 2024-02-24 21:32:11 +04:00
87 changed files with 6125 additions and 52 deletions

View File

@ -3,7 +3,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34221.43
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DinerView", "DinerView\DinerView.csproj", "{7FC291E6-FE0A-4D25-B46F-724FB599F26F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DinerView", "DinerView\DinerView.csproj", "{7FC291E6-FE0A-4D25-B46F-724FB599F26F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DinerDataModels", "DinerDataModels\DinerDataModels.csproj", "{2AFAC265-13C0-432E-8F33-ABF764FD0877}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DinerContracts", "DinerContracts\DinerContracts.csproj", "{89BA6B4F-1F08-4327-B88B-E48335742088}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DinerListImplement", "DinerListImplement\DinerListImplement.csproj", "{33BCF269-AF60-4E7E-9F3B-2ECEDCEBF8F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DineryBusinessLogic", "DineryBusinessLogic\DineryBusinessLogic.csproj", "{2920D9E3-AE18-4914-BD43-C04D9123FBD7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DinerFileImplement", "DinerShopImplement\DinerFileImplement.csproj", "{E46007E3-F3EC-4551-A203-19361E7B1B8D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DinerDataBaseImplement", "DinerDataBaseImplement\DinerDataBaseImplement.csproj", "{42A59EB5-A475-4CEF-AE2F-1396D6BFD143}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +27,30 @@ Global
{7FC291E6-FE0A-4D25-B46F-724FB599F26F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FC291E6-FE0A-4D25-B46F-724FB599F26F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FC291E6-FE0A-4D25-B46F-724FB599F26F}.Release|Any CPU.Build.0 = Release|Any CPU
{2AFAC265-13C0-432E-8F33-ABF764FD0877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AFAC265-13C0-432E-8F33-ABF764FD0877}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AFAC265-13C0-432E-8F33-ABF764FD0877}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AFAC265-13C0-432E-8F33-ABF764FD0877}.Release|Any CPU.Build.0 = Release|Any CPU
{89BA6B4F-1F08-4327-B88B-E48335742088}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89BA6B4F-1F08-4327-B88B-E48335742088}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89BA6B4F-1F08-4327-B88B-E48335742088}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89BA6B4F-1F08-4327-B88B-E48335742088}.Release|Any CPU.Build.0 = Release|Any CPU
{33BCF269-AF60-4E7E-9F3B-2ECEDCEBF8F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33BCF269-AF60-4E7E-9F3B-2ECEDCEBF8F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33BCF269-AF60-4E7E-9F3B-2ECEDCEBF8F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33BCF269-AF60-4E7E-9F3B-2ECEDCEBF8F9}.Release|Any CPU.Build.0 = Release|Any CPU
{2920D9E3-AE18-4914-BD43-C04D9123FBD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2920D9E3-AE18-4914-BD43-C04D9123FBD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2920D9E3-AE18-4914-BD43-C04D9123FBD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2920D9E3-AE18-4914-BD43-C04D9123FBD7}.Release|Any CPU.Build.0 = Release|Any CPU
{E46007E3-F3EC-4551-A203-19361E7B1B8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E46007E3-F3EC-4551-A203-19361E7B1B8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E46007E3-F3EC-4551-A203-19361E7B1B8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E46007E3-F3EC-4551-A203-19361E7B1B8D}.Release|Any CPU.Build.0 = Release|Any CPU
{42A59EB5-A475-4CEF-AE2F-1396D6BFD143}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42A59EB5-A475-4CEF-AE2F-1396D6BFD143}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42A59EB5-A475-4CEF-AE2F-1396D6BFD143}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42A59EB5-A475-4CEF-AE2F-1396D6BFD143}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,18 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels
{
public class FoodBindingModel : IFoodModel
{
public string ComponentName { get; set; } = string.Empty;
public double Price { get; set; }
public int ID { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using DinerDataModels.Enums;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels
{
public class OrderBindingModel : IOrderModel
{
public int ProductID { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime? DateImplement { get; set; }
public int ID { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels
{
public class SnackBindingModel : ISnackModel
{
public string ProductName { get; set; } = string.Empty;
public double Price { get; set; }
public Dictionary<int, (IFoodModel, int)> ProductComponents { get; set; } = new();
public int ID { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContacts
{
public interface IFoodLogic
{
List<FoodViewModel>? ReadList(FoodSearchModel? model);
FoodViewModel? ReadElement(FoodSearchModel model);
bool Create(FoodBindingModel model);
bool Update(FoodBindingModel model);
bool Delete(FoodBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContacts
{
public interface IOrderLogic
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContacts
{
public interface ISnackLogic
{
List<SnackViewModel>? ReadList(SnackSearchModel? model);
SnackViewModel? ReadElement(SnackSearchModel model);
bool Create(SnackBindingModel model);
bool Update(SnackBindingModel model);
bool Delete(SnackBindingModel model);
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DinerDataModels\DinerDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels
{
public class FoodSearchModel
{
public int? ID { get; set; }
public string? ComponentName { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels
{
public class OrderSearchModel
{
public int? ID { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels
{
public class SnackSearchModel
{
public int? ID { get; set; }
public string? ProductName { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.StoragesContracts
{
public interface IFoodStorage
{
List<FoodViewModel> GetFullList();
List<FoodViewModel> GetFilteredList(FoodSearchModel model);
FoodViewModel? GetElement(FoodSearchModel model);
FoodViewModel? Insert(FoodBindingModel model);
FoodViewModel? Update(FoodBindingModel model);
FoodViewModel? Delete(FoodBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.StoragesContracts
{
public interface IOrderStorage
{
List<OrderViewModel> GetFullList();
List<OrderViewModel> GetFilteredList(OrderSearchModel model);
OrderViewModel? GetElement(OrderSearchModel model);
OrderViewModel? Insert(OrderBindingModel model);
OrderViewModel? Update(OrderBindingModel model);
OrderViewModel? Delete(OrderBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.StoragesContracts
{
public interface ISnackStorage
{
List<SnackViewModel> GetFullList();
List<SnackViewModel> GetFilteredList(SnackSearchModel model);
SnackViewModel? GetElement(SnackSearchModel model);
SnackViewModel? Insert(SnackBindingModel model);
SnackViewModel? Update(SnackBindingModel model);
SnackViewModel? Delete(SnackBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.ViewModels
{
public class FoodViewModel : IFoodModel
{
public int ID { get; set; }
[DisplayName("Название еды для изготовления")]
public string ComponentName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
}
}

View File

@ -0,0 +1,38 @@
using DinerDataModels.Enums;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
public int ProductID { get; set; }
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public Double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
[DisplayName("Номер")]
public int ID { get; set; }
[DisplayName("Снэк")]
// какой снэк изготавливается в рамках заказа
public string ProductName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,23 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.ViewModels
{
public class SnackViewModel : ISnackModel
{
[DisplayName("Название снэка")]
public string ProductName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IFoodModel, int)> ProductComponents { get; set; } = new();
public int ID { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using DinerDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace DinerDataBaseImplement
{
public class DinerDataBase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
if (optionsBuilder.IsConfigured == false) {
optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-O0N00SH\SQLEXPRESS;Initial Catalog=DinerDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
public virtual DbSet<Food> Components { get; set; }
public virtual DbSet<Snack> Products { get; set; }
public virtual DbSet<SnackFood> ProductComponents { get; set; }
public virtual DbSet<Order> Orders { get; set; }
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DinerContracts\DinerContracts.csproj" />
<ProjectReference Include="..\DinerDataModels\DinerDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,86 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Migrations;
using DinerDataBaseImplement.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Implements
{
public class FoodStorage : IFoodStorage
{
public FoodViewModel? Delete(FoodBindingModel model)
{
using var context = new DinerDataBase();
var element = context.Components.FirstOrDefault(x => x.ID == model.ID);
if (element != null)
{
context.Components.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public FoodViewModel? GetElement(FoodSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) {
return null;
}
using var context = new DinerDataBase();
return context.Components
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) &&
x.ComponentName == model.ComponentName) || model.ID.HasValue &&
x.ID == model.ID)?.GetViewModel;
}
public List<FoodViewModel> GetFilteredList(FoodSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName)) {
return new();
}
using var context = new DinerDataBase();
return context.Components.Where(x => x.ComponentName.Contains(model.ComponentName))
.Select(x => x.GetViewModel).ToList();
}
public List<FoodViewModel> GetFullList()
{
using var context = new DinerDataBase();
return context.Components.Select(x => x.GetViewModel).ToList();
}
public FoodViewModel? Insert(FoodBindingModel model)
{
var newComponent = Food.Create(model);
if (newComponent == null) {
return null;
}
using var context = new DinerDataBase();
context.Components.Add(newComponent);
context.SaveChanges();
return newComponent.GetViewModel;
}
public FoodViewModel? Update(FoodBindingModel model)
{
using var context = new DinerDataBase();
var component = context.Components.FirstOrDefault(x => x.ID == model.ID);
if (component == null) {
return null;
}
component.Update(model);
context.SaveChanges();
return component.GetViewModel;
}
}
}

View File

@ -0,0 +1,86 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Implements
{
public class OrderStorage : IOrderStorage
{
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new DinerDataBase();
var element = context.Orders.FirstOrDefault(x => x.ID == model.ID);
if (element != null)
{
context.Orders.Remove(element);
context.SaveChanges();
return GetViewModel(element);
}
return null;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.ID.HasValue) {
return null;
}
using var context = new DinerDataBase();
return context.Orders
.FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID)?.GetViewModel;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.ID.HasValue) {
return new();
}
using var context = new DinerDataBase();
return context.Orders.Where(x => x.ID == model.ID).Select(GetViewModel).ToList();
}
public List<OrderViewModel> GetFullList()
{
using var context = new DinerDataBase();
return context.Orders.Select(GetViewModel).ToList();
}
public OrderViewModel? Insert(OrderBindingModel model)
{
using var context = new DinerDataBase();
var newOrder = Order.Create(model);
if (newOrder == null) {
return null;
}
context.Orders.Add(newOrder);
context.SaveChanges();
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new DinerDataBase();
var order = context.Orders.FirstOrDefault(x => x.ID == model.ID);
if (order == null) { return null; }
order.Update(model);
context.SaveChanges();
return GetViewModel(order);
}
private OrderViewModel GetViewModel(Order order)
{
using var context = new DinerDataBase();
var viewModel = order.GetViewModel;
foreach (var pr in context.Products) {
if (pr.ID == order.ProductID) {
viewModel.ProductName = pr.ProductName;
break;
}
}
return viewModel;
}
}
}

View File

@ -0,0 +1,106 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Implements
{
public class SnackStorage : ISnackStorage
{
public SnackViewModel? Delete(SnackBindingModel model)
{
using var context = new DinerDataBase();
var element = context.Products
.Include(x => x.Components)
.FirstOrDefault(rec => rec.ID == model.ID);
if (element != null)
{
context.Products.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public SnackViewModel? GetElement(SnackSearchModel model)
{
if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) {
return null;
}
using var context = new DinerDataBase();
return context.Products
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ProductName) && x.ProductName == model.ProductName) ||
(model.ID.HasValue && x.ID == model.ID))
?.GetViewModel;
}
public List<SnackViewModel> GetFilteredList(SnackSearchModel model)
{
if (string.IsNullOrEmpty(model.ProductName)) {
return new();
}
using var context = new DinerDataBase();
return context.Products
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.Where(x => x.ProductName.Contains(model.ProductName))
.ToList()
.Select(x => x.GetViewModel).ToList();
}
public List<SnackViewModel> GetFullList()
{
using var context = new DinerDataBase();
return context.Products
.Include(x => x.Components)
.ThenInclude(x => x.Component).ToList()
.Select(x => x.GetViewModel).ToList();
}
public SnackViewModel? Insert(SnackBindingModel model)
{
using var context = new DinerDataBase();
var newProduct = Snack.Create(context, model);
if (newProduct == null) {
return null;
}
context.Products.Add(newProduct);
context.SaveChanges();
return newProduct.GetViewModel;
}
public SnackViewModel? Update(SnackBindingModel model)
{
using var context = new DinerDataBase();
using var transcation = context.Database.BeginTransaction();
try
{
var product = context.Products.FirstOrDefault(rec => rec.ID == model.ID);
if (product == null) {
return null;
}
product.Update(model);
context.SaveChanges();
product.UpdateComponents(context, model);
transcation.Commit();
return product.GetViewModel;
}
catch
{
transcation.Rollback();
throw;
}
}
}
}

View File

@ -0,0 +1,157 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDataBase))]
[Migration("20240321182759_InitMigration")]
partial class InitMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.IsRequired()
.HasColumnType("datetime2");
b.Property<int>("ProductID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Products");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ProductID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("ProductID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("ProductID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,114 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Components",
columns: table => new
{
ID = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ComponentName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Price = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Components", x => x.ID);
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
ID = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ProductID = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateImplement = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.ID);
});
migrationBuilder.CreateTable(
name: "Products",
columns: table => new
{
ID = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ProductName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Price = table.Column<double>(type: "float", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.ID);
});
migrationBuilder.CreateTable(
name: "ProductComponents",
columns: table => new
{
ID = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ProductID = table.Column<int>(type: "int", nullable: false),
ComponentID = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductComponents", x => x.ID);
table.ForeignKey(
name: "FK_ProductComponents_Components_ComponentID",
column: x => x.ComponentID,
principalTable: "Components",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ProductComponents_Products_ProductID",
column: x => x.ProductID,
principalTable: "Products",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ProductComponents_ComponentID",
table: "ProductComponents",
column: "ComponentID");
migrationBuilder.CreateIndex(
name: "IX_ProductComponents_ProductID",
table: "ProductComponents",
column: "ProductID");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "ProductComponents");
migrationBuilder.DropTable(
name: "Components");
migrationBuilder.DropTable(
name: "Products");
}
}
}

View File

@ -0,0 +1,156 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDataBase))]
[Migration("20240403124835_Migration02")]
partial class Migration02
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("ProductID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Products");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ProductID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("ProductID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("ProductID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Migration02 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "DateImplement",
table: "Orders",
type: "datetime2",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "DateImplement",
table: "Orders",
type: "datetime2",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
}
}
}

View File

@ -0,0 +1,170 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDataBase))]
[Migration("20240405063803_Migration03")]
partial class Migration03
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("ProductID")
.HasColumnType("int");
b.Property<int?>("SnackID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.HasIndex("SnackID");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Products");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ProductID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("ProductID");
b.ToTable("ProductComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany()
.HasForeignKey("SnackID");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("ProductID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class Migration03 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "SnackID",
table: "Orders",
type: "int",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Orders_SnackID",
table: "Orders",
column: "SnackID");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Products_SnackID",
table: "Orders",
column: "SnackID",
principalTable: "Products",
principalColumn: "ID");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Products_SnackID",
table: "Orders");
migrationBuilder.DropIndex(
name: "IX_Orders_SnackID",
table: "Orders");
migrationBuilder.DropColumn(
name: "SnackID",
table: "Orders");
}
}
}

View File

@ -0,0 +1,167 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDataBase))]
partial class DinerDataBaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("ID");
b.ToTable("Components", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("ProductID")
.HasColumnType("int");
b.Property<int?>("SnackID")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("ID");
b.HasIndex("SnackID");
b.ToTable("Orders", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("ProductName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("ID");
b.ToTable("Products", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
b.Property<int>("ComponentID")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ProductID")
.HasColumnType("int");
b.HasKey("ID");
b.HasIndex("ComponentID");
b.HasIndex("ProductID");
b.ToTable("ProductComponents", (string)null);
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany()
.HasForeignKey("SnackID");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackFood", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Food", "Component")
.WithMany("SnackFood")
.HasForeignKey("ComponentID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Product")
.WithMany("Components")
.HasForeignKey("ProductID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Product");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Food", b =>
{
b.Navigation("SnackFood");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,60 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerDataBaseImplement.Models
{
public class Food : IFoodModel
{
[Required]
public string ComponentName { get; set; } = string.Empty;
[Required]
public double Price { get; set; }
public int ID { get; set; }
[ForeignKey("ComponentID")]
public virtual List<SnackFood> SnackFood { get; set;} = new();
public static Food? Create(FoodBindingModel? model)
{
if (model == null) return null;
return new Food()
{
ID = model.ID,
ComponentName = model.ComponentName,
Price = model.Price,
};
}
public static Food? Create(FoodViewModel model)
{
return new Food
{
ID = model.ID,
ComponentName = model.ComponentName,
Price = model.Price,
};
}
public void Update(FoodBindingModel? model)
{
if (model == null) return;
ComponentName = model.ComponentName;
Price = model.Price;
}
public FoodViewModel GetViewModel => new()
{
ID = ID,
ComponentName = ComponentName,
Price = Price,
};
}
}

View File

@ -0,0 +1,66 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Implements;
using DinerDataModels.Enums;
using DinerDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.Xml.Linq;
namespace DinerDataBaseImplement.Models
{
public class Order : IOrderModel
{
[Required]
public int ProductID { get; set; }
[Required]
public int Count { get; set; }
[Required]
public double Sum { get; private set; }
[Required]
public OrderStatus Status { get; set; }
[Required]
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; set; }
public int ID { get; private set; }
public virtual Snack? Snack { get; set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null) return null;
return new Order()
{
ID = model.ID,
ProductID = model.ProductID,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
};
}
public void Update(OrderBindingModel? model)
{
if (model == null) return;
Status = model.Status;
DateImplement = model?.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
ID = ID,
ProductID = ProductID,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement
};
}
}

View File

@ -0,0 +1,96 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerDataBaseImplement.Models
{
public class Snack : ISnackModel
{
[Required]
public string ProductName { get; private set; } = string.Empty;
[Required]
public double Price { get; private set; }
public int ID { get; private set; }
private Dictionary<int, (IFoodModel, int)>? _productComponents = null;
[NotMapped]
public Dictionary<int, (IFoodModel, int)> ProductComponents
{
get
{
if (_productComponents == null)
{
_productComponents = Components
.ToDictionary(recPC => recPC.ComponentID, recPC => (recPC.Component as IFoodModel, recPC.Count));
}
return _productComponents;
}
}
[ForeignKey("ProductID")]
public virtual List<SnackFood> Components { get; set; } = new();
public static Snack? Create(DinerDataBase context,SnackBindingModel model)
{
return new Snack()
{
ID = model.ID,
ProductName = model.ProductName,
Price = model.Price,
Components = model.ProductComponents.Select(x => new SnackFood
{
Component = context.Components.First(y => y.ID == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(SnackBindingModel model)
{
ProductName = model.ProductName;
Price = model.Price;
}
public SnackViewModel GetViewModel => new()
{
ID = ID,
ProductName = ProductName,
Price = Price,
ProductComponents = ProductComponents
};
public void UpdateComponents(DinerDataBase context, SnackBindingModel model) {
var productComponents = context.ProductComponents.Where(rec => rec.ProductID == model.ID).ToList();
if (ProductComponents != null && ProductComponents.Count > 0) {
context.ProductComponents.RemoveRange(productComponents.Where(rec => !model.ProductComponents.ContainsKey(rec.ComponentID)));
context.SaveChanges();
foreach (var updateComponent in productComponents) {
updateComponent.Count = model.ProductComponents[updateComponent.ComponentID].Item2;
model.ProductComponents.Remove(updateComponent.ComponentID);
}
context.SaveChanges();
}
var product = context.Products.First(x => x.ID == ID);
foreach (var pc in model.ProductComponents) {
context.ProductComponents.Add(new SnackFood
{
Product = product,
Component = context.Components.First(x => x.ID == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_productComponents = null;
}
}
}

View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
namespace DinerDataBaseImplement.Models
{
public class SnackFood
{
public int ID { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
public int ComponentID { get; set; }
[Required]
public int Count { get; set; }
public virtual Food Component { get; set; } = new();
public virtual Snack Product { get; set; } = new();
}
}

View File

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

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels.Enums
{
public enum OrderStatus
{
Неизвестен = -1,
Принят = 0,
Выполняется = 1,
Готов = 2,
Выдан = 3
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels
{
public interface IID
{
int ID { get; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels.Models
{
public interface IFoodModel : IID
{
string ComponentName { get; }
double Price { get; }
}
}

View File

@ -0,0 +1,19 @@
using DinerDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels.Models
{
public interface IOrderModel : IID
{
int ProductID { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataModels.Models
{
public interface ISnackModel : IID
{
string ProductName { get; }
double Price { get; }
// словарь для компонент.
// <id,(модель компонент, количество)>
Dictionary<int, (IFoodModel, int)> ProductComponents { get; }
}
}

View File

@ -0,0 +1,28 @@
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement
{
internal class DataListSingleton
{
public static DataListSingleton? _instance;
public List<Food> Foods { get; set; }
public List<Snack> Snacks { get; set; }
public List<Order> Orders { get; set; }
private DataListSingleton() {
Foods = new List<Food>();
Snacks = new List<Snack>();
Orders = new List<Order>();
}
public static DataListSingleton GetInstance() {
if (_instance == null) _instance = new DataListSingleton();
return _instance;
}
}
}

View File

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

View File

@ -0,0 +1,98 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements
{
public class FoodStorage : IFoodStorage
{
private readonly DataListSingleton _source;
public FoodStorage() {
_source = DataListSingleton.GetInstance();
}
public FoodViewModel? Delete(FoodBindingModel model)
{
for (int i = 0; i < _source.Foods.Count; ++i) {
if (_source.Foods[i].ID == model.ID) {
var element = _source.Foods[i];
_source.Foods.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
public FoodViewModel? GetElement(FoodSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) {
return null;
}
foreach (var component in _source.Foods) {
if ((!string.IsNullOrEmpty(model.ComponentName) &&
component.ComponentName == model.ComponentName) ||
(model.ID.HasValue && component.ID == model.ID)) {
return component.GetViewModel;
}
}
return null;
}
public List<FoodViewModel> GetFilteredList(FoodSearchModel model)
{
var result = new List<FoodViewModel>();
if (string.IsNullOrEmpty(model.ComponentName)) {
return result;
}
foreach (var component in _source.Foods) {
if (component.ComponentName.Contains(model.ComponentName)) {
result.Add(component.GetViewModel);
}
}
return result;
}
public List<FoodViewModel> GetFullList()
{
var result = new List<FoodViewModel>();
foreach (var component in _source.Foods) {
result.Add(component.GetViewModel);
}
return result;
}
public FoodViewModel? Insert(FoodBindingModel model)
{
model.ID = 1;
foreach (var component in _source.Foods) {
if (model.ID <= component.ID) {
model.ID = component.ID + 1;
}
}
var newComponent = Food.Create(model);
if (newComponent == null) return null;
_source.Foods.Add(newComponent);
return newComponent.GetViewModel;
}
public FoodViewModel? Update(FoodBindingModel model)
{
foreach (var component in _source.Foods) {
if (component.ID == model.ID) {
component.Update(model);
return component.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,103 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements
{
public class OrderStorage : IOrderStorage
{
private readonly DataListSingleton _source;
public OrderStorage() {
_source = DataListSingleton.GetInstance();
}
public OrderViewModel? Delete(OrderBindingModel model)
{
for (int i = 0; i < _source.Orders.Count; ++i) {
if (_source.Orders[i].ID == model.ID) {
var element = _source.Orders[i];
_source.Orders.RemoveAt(i);
return GetViewModel(element);
}
}
return null;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.ID.HasValue) return null;
foreach (var order in _source.Orders) {
if (model.ID.HasValue && order.ID == model.ID) {
return GetViewModel(order);
}
}
return null;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
var result = new List<OrderViewModel>();
if (!model.ID.HasValue) return result;
foreach (var order in _source.Orders) {
if (order.ID == model.ID) {
result.Add(GetViewModel(order));
}
}
return result;
}
public List<OrderViewModel> GetFullList()
{
var result = new List<OrderViewModel>();
foreach (var order in _source.Orders) {
result.Add(GetViewModel(order));
}
return result;
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
foreach (var product in _source.Snacks)
{
if (product.ID == order.ProductID)
{
viewModel.ProductName = product.ProductName;
break;
}
}
return viewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.ID = 1;
foreach (var order in _source.Orders) {
if (model.ID <= order.ID) {
model.ID = order.ID + 1;
}
}
var newOrder = Order.Create(model);
if (newOrder == null) return null;
_source.Orders.Add(newOrder);
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
foreach (var order in _source.Orders) {
if (order.ID == model.ID) {
order.Update(model);
return GetViewModel(order);
}
}
return null;
}
}
}

View File

@ -0,0 +1,97 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements
{
public class SnackStorage : ISnackStorage
{
private readonly DataListSingleton _source;
public SnackStorage() {
_source = DataListSingleton.GetInstance();
}
public SnackViewModel? Delete(SnackBindingModel model)
{
for (int i = 0; i < _source.Snacks.Count; ++i) {
if (_source.Snacks[i].ID == model.ID) {
var element = _source.Snacks[i];
_source.Snacks.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
public SnackViewModel? GetElement(SnackSearchModel model)
{
if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) {
return null;
}
foreach (var product in _source.Snacks) {
if ((!string.IsNullOrEmpty(model.ProductName) &&
product.ProductName == model.ProductName) ||
(model.ID.HasValue && product.ID == model.ID)) {
return product.GetViewModel;
}
}
return null;
}
public List<SnackViewModel> GetFilteredList(SnackSearchModel model)
{
var result = new List<SnackViewModel>();
if (string.IsNullOrEmpty(model.ProductName)) {
return result;
}
foreach (var product in _source.Snacks) {
if (product.ProductName.Contains(model.ProductName)) {
result.Add(product.GetViewModel);
}
}
return result;
}
public List<SnackViewModel> GetFullList()
{
var result = new List<SnackViewModel>();
foreach (var product in _source.Snacks) {
result.Add(product.GetViewModel);
}
return result;
}
public SnackViewModel? Insert(SnackBindingModel model)
{
model.ID = 1;
foreach (var product in _source.Snacks) {
if (model.ID <= product.ID) {
model.ID = product.ID + 1;
}
}
var newProduct = Snack.Create(model);
if (newProduct == null) return null;
_source.Snacks.Add(newProduct);
return newProduct.GetViewModel;
}
public SnackViewModel? Update(SnackBindingModel model)
{
foreach (var product in _source.Snacks) {
if (product.ID == model.ID) {
product.Update(model);
return product.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,39 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Models
{
internal class Food : IFoodModel
{
public string ComponentName { get; private set; } = string.Empty;
public double Price { get; set; }
public int ID { get; private set; }
public static Food? Create(FoodBindingModel? model) {
if (model == null) return null;
return new Food() {
ID = model.ID,
ComponentName = model.ComponentName,
Price = model.Price,
};
}
public void Update(FoodBindingModel? model) {
if (model == null) return;
ComponentName = model.ComponentName;
Price = model.Price;
}
public FoodViewModel GetViewModel => new(){
ID = ID,
ComponentName = ComponentName,
Price = Price,
};
}
}

View File

@ -0,0 +1,58 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Enums;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Models
{
internal class Order : IOrderModel
{
public int ProductID { get; private set; }
public int Count { get; set; }
public double Sum { get; private set; }
public OrderStatus Status { get; set; }
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; set; }
public int ID { get; private set; }
public static Order? Create(OrderBindingModel? model) {
if (model == null) return null;
return new Order()
{
ID = model.ID,
ProductID = model.ProductID,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
};
}
public void Update(OrderBindingModel? model) {
if (model == null) return;
Status = model.Status;
DateImplement = model?.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
ID = ID,
ProductID = ProductID,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
};
}
}

View File

@ -0,0 +1,46 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Models
{
internal class Snack : ISnackModel
{
public string ProductName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, (IFoodModel, int)> ProductComponents { get; private set; } =
new Dictionary<int, (IFoodModel, int)>();
public int ID { get; private set; }
public static Snack? Create(SnackBindingModel? model) {
if (model == null) return null;
return new Snack() {
ID = model.ID,
ProductName = model.ProductName,
Price = model.Price,
ProductComponents = model.ProductComponents
};
}
public void Update(SnackBindingModel? model) {
if (model == null) return;
ProductName = model.ProductName;
Price = model.Price;
ProductComponents = model.ProductComponents;
}
public SnackViewModel GetViewModel => new()
{
ID = ID,
ProductName = ProductName,
Price = Price,
ProductComponents = ProductComponents
};
}
}

View File

@ -0,0 +1,59 @@
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement
{
internal class DataFileSingleton
{
private static DataFileSingleton? instance;
private readonly string FoodFileName = "Food.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string SnackFileName = "Snack.xml";
public List<Food> Foods { get; set; }
public List<Order> Orders { get; private set; }
public List<Snack> Snacks { get; private set; }
private DataFileSingleton() {
Foods = LoadData(FoodFileName, "Food", x => Food.Create(x)!)!;
Snacks = LoadData(SnackFileName, "Snack", x => Snack.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
}
public static DataFileSingleton GetInstance() {
if (instance == null) instance = new DataFileSingleton();
return instance;
}
public void SaveFoods() => SaveData(Foods, FoodFileName, "Foods",
x => x.GetXElement);
public void SaveSnacks() => SaveData(Snacks, SnackFileName, "Snacks",
x => x.GetXElement);
public void SaveOrder() => SaveData(Orders, OrderFileName, "Orders",
x => x.GetXElement);
private static void SaveData<T>(List<T> data, string filename, string xmlNodeName,
Func<T, XElement> selectFunction)
{
if (data != null) {
new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray()))
.Save(filename);
}
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction)
{
if (File.Exists(filename))
{
return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?
.Select(selectFunction)?.ToList();
}
return new List<T>();
}
}
}

View File

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

View File

@ -0,0 +1,75 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements
{
public class FoodStorage : IFoodStorage
{
private readonly DataFileSingleton _source;
public FoodStorage()
{
_source = DataFileSingleton.GetInstance();
}
public FoodViewModel? Delete(FoodBindingModel model)
{
var element = _source.Foods.FirstOrDefault(x => x.ID == model.ID);
if (element != null) {
_source.Foods.Remove(element);
_source.SaveFoods();
return element.GetViewModel;
}
return null;
}
public FoodViewModel? GetElement(FoodSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.ID.HasValue) { return null; }
return _source.Foods
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ComponentName) &&
x.ComponentName == model.ComponentName) || model.ID.HasValue &&
x.ID == model.ID)?.GetViewModel;
}
public List<FoodViewModel> GetFilteredList(FoodSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName)) { return new(); }
return _source.Foods.Where(x => x.ComponentName.Contains(model.ComponentName))
.Select(x => x.GetViewModel).ToList();
}
public List<FoodViewModel> GetFullList()
{
return _source.Foods.Select(x => x.GetViewModel).ToList();
}
public FoodViewModel? Insert(FoodBindingModel model)
{
model.ID = _source.Foods.Count > 0 ? _source.Foods.Max(x => x.ID) + 1 : 1;
var newComponent = Food.Create(model);
if (newComponent == null) { return null; }
_source.Foods.Add(newComponent);
_source.SaveFoods();
return newComponent.GetViewModel;
}
public FoodViewModel? Update(FoodBindingModel model)
{
var component = _source.Foods.FirstOrDefault(x => x.ID == model.ID);
if (component == null) { return null; }
component.Update(model);
_source.SaveFoods();
return component.GetViewModel;
}
}
}

View File

@ -0,0 +1,81 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements
{
public class OrderStorage : IOrderStorage
{
private readonly DataFileSingleton _source;
public OrderStorage()
{
_source = DataFileSingleton.GetInstance();
}
public OrderViewModel? Delete(OrderBindingModel model)
{
var element = _source.Orders.FirstOrDefault(x => x.ID == model.ID);
if (element != null) {
_source.Orders.Remove(element);
_source.SaveOrder();
return GetViewModel(element);
}
return null;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.ID.HasValue) { return null; }
return _source.Orders
.FirstOrDefault(x => model.ID.HasValue && x.ID == model.ID)?.GetViewModel;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.ID.HasValue) { return new(); }
return _source.Orders.Where(x => x.ID == model.ID).Select(GetViewModel).ToList();
}
public List<OrderViewModel> GetFullList()
{
return _source.Orders.Select(GetViewModel).ToList();
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
var tmp = from p in _source.Snacks
where p.ID == order.ProductID
select p.ProductName;
viewModel.ProductName = tmp.FirstOrDefault(string.Empty);
return viewModel;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.ID = _source.Orders.Count > 0 ? _source.Orders.Max(x => x.ID) + 1 : 1;
var newOrder = Order.Create(model);
if (newOrder == null) { return null; }
_source.Orders.Add(newOrder);
_source.SaveOrder();
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
var order = _source.Orders.FirstOrDefault(x => x.ID == model.ID);
if (order == null) { return null; }
order.Update(model);
_source.SaveOrder();
return GetViewModel(order);
}
}
}

View File

@ -0,0 +1,74 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements
{
public class SnackStorage : ISnackStorage
{
private readonly DataFileSingleton _source;
public SnackStorage()
{
_source = DataFileSingleton.GetInstance();
}
public SnackViewModel? Delete(SnackBindingModel model)
{
var element = _source.Snacks.FirstOrDefault(x => x.ID == model.ID);
if (element != null) {
_source.Snacks.Remove(element);
_source.SaveSnacks();
return element.GetViewModel;
}
return null;
}
public SnackViewModel? GetElement(SnackSearchModel model)
{
if (string.IsNullOrEmpty(model.ProductName) && !model.ID.HasValue) { return null; }
return _source.Snacks
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ProductName) &&
x.ProductName == model.ProductName) || model.ID.HasValue &&
x.ID == model.ID)?.GetViewModel;
}
public List<SnackViewModel> GetFilteredList(SnackSearchModel model)
{
if (string.IsNullOrEmpty(model.ProductName)) { return new(); }
return _source.Snacks.Where(x => x.ProductName.Contains(model.ProductName))
.Select(x => x.GetViewModel).ToList();
}
public List<SnackViewModel> GetFullList()
{
return _source.Snacks.Select(x => x.GetViewModel).ToList();
}
public SnackViewModel? Insert(SnackBindingModel model)
{
model.ID = _source.Snacks.Count > 0 ? _source.Snacks.Max(x => x.ID) + 1 : 1;
var newProduct = Snack.Create(model);
if (newProduct == null) { return null; }
_source.Snacks.Add(newProduct);
_source.SaveSnacks();
return newProduct.GetViewModel;
}
public SnackViewModel? Update(SnackBindingModel model)
{
var product = _source.Snacks.FirstOrDefault(x => x.ID == model.ID);
if (product == null) { return null; }
product.Update(model);
_source.SaveSnacks();
return product.GetViewModel;
}
}
}

View File

@ -0,0 +1,57 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
internal class Food : IFoodModel
{
public string ComponentName { get; set; } = string.Empty;
public double Price { get; set; }
public int ID { get; set; }
public static Food? Create(FoodBindingModel? model)
{
if (model == null) return null;
return new Food()
{
ID = model.ID,
ComponentName = model.ComponentName,
Price = model.Price,
};
}
public static Food? Create(XElement element) {
if (element == null) return null;
return new Food()
{
ID = Convert.ToInt32(element.Attribute("ID")!.Value),
ComponentName = element.Element("ComponentName")!.Value,
Price = Convert.ToDouble(element.Element("Price")!.Value)
};
}
public void Update(FoodBindingModel? model)
{
if (model == null) return;
ComponentName = model.ComponentName;
Price = model.Price;
}
public FoodViewModel GetViewModel => new()
{
ID = ID,
ComponentName = ComponentName,
Price = Price,
};
public XElement GetXElement => new("Food", new XAttribute("ID", ID),
new XElement("ComponentName", ComponentName),
new XElement("Price", Price.ToString()));
}
}

View File

@ -0,0 +1,84 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Enums;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
internal class Order : IOrderModel
{
public int ProductID { get; private set; }
public int Count { get; set; }
public double Sum { get; private set; }
public OrderStatus Status { get; set; }
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; set; }
public int ID { get; private set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null) return null;
return new Order()
{
ID = model.ID,
ProductID = model.ProductID,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement,
};
}
public static Order? Create(XElement element) {
if (element == null) return null;
return new Order()
{
ID = Convert.ToInt32(element.Attribute("ID")!.Value),
ProductID = Convert.ToInt32(element.Element("ProductID")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value),
DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value),
DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null :
Convert.ToDateTime(element.Element("DateImplement")!.Value),
};
}
public void Update(OrderBindingModel? model)
{
if (model == null) return;
Status = model.Status;
DateImplement = model?.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
ID = ID,
ProductID = ProductID,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
};
public XElement GetXElement => new("Order", new XAttribute("ID", ID),
new XElement("ProductID", ProductID),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),
new XElement("DateCreate", DateCreate.ToString()),
new XElement("DateImplement", DateImplement.ToString()));
}
}

View File

@ -0,0 +1,83 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;
namespace DinerFileImplement.Models
{
internal class Snack : ISnackModel
{
public string ProductName { get; private set; } = string.Empty;
public double Price { get; private set; }
public int ID { get; private set; }
public Dictionary<int, int> Components { get; private set; } = new();
private Dictionary<int, (IFoodModel, int)>? _productComponents = null;
public Dictionary<int, (IFoodModel, int)> ProductComponents
{
get
{
if (_productComponents == null) {
var source = DataFileSingleton.GetInstance();
_productComponents = Components.ToDictionary(x => x.Key, y => ((source.Foods.FirstOrDefault(z => z.ID ==
y.Key) as IFoodModel)!, y.Value));
}
return _productComponents;
}
}
public static Snack? Create(SnackBindingModel? model)
{
if (model == null) return null;
return new Snack()
{
ID = model.ID,
ProductName = model.ProductName,
Price = model.Price,
Components = model.ProductComponents.ToDictionary(x => x.Key, x => x.Value.Item2)
};
}
public static Snack? Create(XElement element)
{
if (element == null) return null;
return new Snack()
{
ID = Convert.ToInt32(element.Attribute("ID")!.Value),
ProductName = element.Element("ProductName")!.Value,
Price = Convert.ToDouble(element.Element("Price")!.Value),
Components = element.Element("ProductComponents")!.Elements("ProductComponent")
.ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value))
};
}
public void Update(SnackBindingModel? model)
{
if (model == null) return;
ProductName = model.ProductName;
Price = model.Price;
Components = model.ProductComponents.ToDictionary(x => x.Key, x => x.Value.Item2);
_productComponents = null;
}
public SnackViewModel GetViewModel => new()
{
ID = ID,
ProductName = ProductName,
Price = Price,
ProductComponents = ProductComponents
};
public XElement GetXElement => new("Snack", new XAttribute("ID", ID),
new XElement("ProductName", ProductName),
new XElement("Price", Price.ToString()),
new XElement("ProductComponents", Components.Select(x => new XElement("ProductComponent",
new XElement("Key", x.Key),
new XElement("Value", x.Value))).ToArray()));
}
}

View File

@ -2,10 +2,53 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="Nlog.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DinerContracts\DinerContracts.csproj" />
<ProjectReference Include="..\DinerDataBaseImplement\DinerDataBaseImplement.csproj" />
<ProjectReference Include="..\DinerShopImplement\DinerFileImplement.csproj" />
<ProjectReference Include="..\DineryBusinessLogic\DineryBusinessLogic.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -1,39 +0,0 @@
namespace DinerView
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace DinerView
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,146 @@
namespace DinerView
{
partial class FormCreateOrder
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelProduct = new Label();
comboBoxProduct = new ComboBox();
labelCount = new Label();
textBoxCount = new TextBox();
label1 = new Label();
textBoxSum = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// labelProduct
//
labelProduct.AutoSize = true;
labelProduct.Location = new Point(12, 9);
labelProduct.Name = "labelProduct";
labelProduct.Size = new Size(37, 15);
labelProduct.TabIndex = 0;
labelProduct.Text = "Cнэк:";
//
// comboBoxProduct
//
comboBoxProduct.BackColor = SystemColors.ButtonShadow;
comboBoxProduct.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxProduct.FormattingEnabled = true;
comboBoxProduct.Location = new Point(93, 6);
comboBoxProduct.Name = "comboBoxProduct";
comboBoxProduct.Size = new Size(289, 23);
comboBoxProduct.TabIndex = 3;
comboBoxProduct.SelectedIndexChanged += comboBoxProduct_SelectedIndexChanged;
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(12, 37);
labelCount.Name = "labelCount";
labelCount.Size = new Size(75, 15);
labelCount.TabIndex = 4;
labelCount.Text = "Количество:";
//
// textBoxCount
//
textBoxCount.Location = new Point(93, 34);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(289, 23);
textBoxCount.TabIndex = 5;
textBoxCount.TextChanged += textBoxCount_TextChanged;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 66);
label1.Name = "label1";
label1.Size = new Size(48, 15);
label1.TabIndex = 6;
label1.Text = "Сумма:";
//
// textBoxSum
//
textBoxSum.Location = new Point(93, 63);
textBoxSum.Name = "textBoxSum";
textBoxSum.ReadOnly = true;
textBoxSum.Size = new Size(289, 23);
textBoxSum.TabIndex = 7;
//
// buttonCancel
//
buttonCancel.Location = new Point(307, 92);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 8;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(226, 92);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 9;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormCreateOrder
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(394, 122);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(textBoxSum);
Controls.Add(label1);
Controls.Add(textBoxCount);
Controls.Add(labelCount);
Controls.Add(comboBoxProduct);
Controls.Add(labelProduct);
Name = "FormCreateOrder";
Text = "Заказ";
Load += FormCreateOrder_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelProduct;
private ComboBox comboBoxProduct;
private Label labelCount;
private TextBox textBoxCount;
private Label label1;
private TextBox textBoxSum;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,123 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using DinerDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormCreateOrder : Form
{
private readonly ILogger _logger;
private readonly ISnackLogic _logicSnack;
private readonly IOrderLogic _logicOrder;
public FormCreateOrder(ILogger<FormCreateOrder> logger, ISnackLogic logicSnack, IOrderLogic logicOrder)
{
InitializeComponent();
_logger = logger;
_logicSnack = logicSnack;
_logicOrder = logicOrder;
}
private void CalcSum()
{
if (comboBoxProduct.SelectedValue != null && !string.IsNullOrEmpty(textBoxCount.Text))
{
try
{
int id = Convert.ToInt32(comboBoxProduct.SelectedValue);
var product = _logicSnack.ReadElement(new SnackSearchModel { ID = id });
int count = Convert.ToInt32(textBoxCount.Text);
textBoxSum.Text = Math.Round(count * (product?.Price ?? 0), 2).ToString();
_logger.LogInformation("Расчет суммы заказа");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка расчета суммы заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void textBoxCount_TextChanged(object sender, EventArgs e)
{
CalcSum();
}
private void comboBoxProduct_SelectedIndexChanged(object sender, EventArgs e)
{
CalcSum();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxProduct.SelectedValue == null)
{
MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание заказа");
try
{
var operationResult = _logicOrder.CreateOrder(new OrderBindingModel
{
ProductID = Convert.ToInt32(comboBoxProduct.SelectedValue),
Count = Convert.ToInt32(textBoxCount.Text),
Sum = Convert.ToDouble(textBoxSum.Text),
});
if (!operationResult) throw new Exception("Ошибка при создании заказа. Дополнительная информация в логах.");
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void FormCreateOrder_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка Снэков");
try
{
var list = _logicSnack.ReadList(null);
if (list != null)
{
comboBoxProduct.DisplayMember = "ProductName";
comboBoxProduct.ValueMember = "ID";
comboBoxProduct.DataSource = list;
comboBoxProduct.SelectedItem = null;
}
}
catch (Exception ex) {
_logger.LogError(ex, "Ошибка загрузки списка снэков");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

118
Diner/DinerView/FormFood.Designer.cs generated Normal file
View File

@ -0,0 +1,118 @@
namespace DinerView
{
partial class FormFood
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelName = new Label();
labelPrice = new Label();
textBoxName = new TextBox();
textBoxPrice = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(12, 9);
labelName.Name = "labelName";
labelName.Size = new Size(62, 15);
labelName.TabIndex = 0;
labelName.Text = "Название:";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(12, 38);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(38, 15);
labelPrice.TabIndex = 1;
labelPrice.Text = "Цена:";
//
// textBoxName
//
textBoxName.Location = new Point(77, 6);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(305, 23);
textBoxName.TabIndex = 2;
//
// textBoxPrice
//
textBoxPrice.Location = new Point(77, 38);
textBoxPrice.Name = "textBoxPrice";
textBoxPrice.Size = new Size(305, 23);
textBoxPrice.TabIndex = 3;
//
// buttonCancel
//
buttonCancel.Location = new Point(307, 67);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(226, 67);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 5;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormFood
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(394, 101);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(textBoxPrice);
Controls.Add(textBoxName);
Controls.Add(labelPrice);
Controls.Add(labelName);
Name = "FormFood";
Text = "Продукт питания";
Load += FormComponent_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelPrice;
private TextBox textBoxName;
private TextBox textBoxPrice;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,89 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormFood : Form
{
private readonly ILogger _logger;
private readonly IFoodLogic _logic;
private int? _ID;
public int ID { set { _ID = value; } }
public FormFood(ILogger<FormFood> logger, IFoodLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormComponent_Load(object sender, EventArgs e)
{
if (_ID.HasValue)
{
try
{
_logger.LogInformation("Получение продукта");
var view = _logic.ReadElement(new FoodSearchModel { ID = _ID.Value });
if (view != null)
{
textBoxName.Text = view.ComponentName;
textBoxPrice.Text = view.Price.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения продукта");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение продукта");
try
{
var model = new FoodBindingModel
{
ID = _ID ?? 0,
ComponentName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text)
};
var operationResult = _ID.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
throw new Exception("Ошибка при сохранении. Дополнителльная информация в логах.");
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при сохронении продукта");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

122
Diner/DinerView/FormFoods.Designer.cs generated Normal file
View File

@ -0,0 +1,122 @@
namespace DinerView
{
partial class FormFoods
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
buttonAdd = new Button();
buttonChange = new Button();
buttonRemove = new Button();
buttonUpdate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = SystemColors.ButtonHighlight;
dataGridView.BorderStyle = BorderStyle.None;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(563, 450);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(578, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(219, 41);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// buttonChange
//
buttonChange.Location = new Point(578, 59);
buttonChange.Name = "buttonChange";
buttonChange.Size = new Size(219, 41);
buttonChange.TabIndex = 2;
buttonChange.Text = "Изменить";
buttonChange.UseVisualStyleBackColor = true;
buttonChange.Click += buttonChange_Click;
//
// buttonRemove
//
buttonRemove.Location = new Point(578, 106);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(219, 41);
buttonRemove.TabIndex = 3;
buttonRemove.Text = "Удалить";
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(578, 153);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(219, 41);
buttonUpdate.TabIndex = 4;
buttonUpdate.Text = "Обновить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// FormFoods
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ScrollBar;
ClientSize = new Size(800, 450);
Controls.Add(buttonUpdate);
Controls.Add(buttonRemove);
Controls.Add(buttonChange);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormFoods";
Text = "Продукты";
Load += FormComponents_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonChange;
private Button buttonRemove;
private Button buttonUpdate;
}
}

View File

@ -0,0 +1,104 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormFoods : Form
{
private readonly ILogger _logger;
private readonly IFoodLogic _logic;
public FormFoods(ILogger<FormFoods> logger, IFoodLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ID"].Visible = false;
dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка продуктов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки продуктов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFood));
if (service is FormFood form) {
if (form.ShowDialog() == DialogResult.OK) LoadData();
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ID"].Value);
_logger.LogInformation("Удаление продукта");
try
{
if (!_logic.Delete(new FoodBindingModel { ID = id }))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления продукта");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
LoadData();
}
private void buttonChange_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFood));
if (service is FormFood form)
{
form.ID = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ID"].Value);
if (form.ShowDialog() == DialogResult.OK) LoadData();
}
}
}
private void FormComponents_Load(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

180
Diner/DinerView/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,180 @@
namespace DinerView
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip = new MenuStrip();
toolStripMenuItemMenu = new ToolStripMenuItem();
toolStripMenuItemFoods = new ToolStripMenuItem();
toolStripMenuItemSnacks = new ToolStripMenuItem();
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonInWork = new Button();
buttonIsReady = new Button();
buttonIsDelivery = new Button();
buttonUpdateList = new Button();
menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip
//
menuStrip.BackColor = SystemColors.Control;
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItemMenu });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(951, 24);
menuStrip.TabIndex = 0;
menuStrip.Text = "Справочник";
//
// toolStripMenuItemMenu
//
toolStripMenuItemMenu.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItemFoods, toolStripMenuItemSnacks });
toolStripMenuItemMenu.Name = "toolStripMenuItemMenu";
toolStripMenuItemMenu.Size = new Size(94, 20);
toolStripMenuItemMenu.Text = "Справочники";
//
// toolStripMenuItemFoods
//
toolStripMenuItemFoods.Name = "toolStripMenuItemFoods";
toolStripMenuItemFoods.Size = new Size(180, 22);
toolStripMenuItemFoods.Text = "Продукты";
toolStripMenuItemFoods.Click += toolStripMenuItemFoods_Click;
//
// toolStripMenuItemSnacks
//
toolStripMenuItemSnacks.Name = "toolStripMenuItemSnacks";
toolStripMenuItemSnacks.Size = new Size(180, 22);
toolStripMenuItemSnacks.Text = "Снэки";
toolStripMenuItemSnacks.Click += toolStripMenuItemSnacks_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
dataGridView.BackgroundColor = SystemColors.Control;
dataGridView.BorderStyle = BorderStyle.None;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 24);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(726, 426);
dataGridView.TabIndex = 0;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(732, 36);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(212, 39);
buttonCreateOrder.TabIndex = 2;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonInWork
//
buttonInWork.Location = new Point(732, 81);
buttonInWork.Name = "buttonInWork";
buttonInWork.Size = new Size(212, 39);
buttonInWork.TabIndex = 3;
buttonInWork.Text = "Отдать на выполнение";
buttonInWork.UseVisualStyleBackColor = true;
buttonInWork.Click += buttonInWork_Click;
//
// buttonIsReady
//
buttonIsReady.Location = new Point(732, 126);
buttonIsReady.Name = "buttonIsReady";
buttonIsReady.Size = new Size(212, 39);
buttonIsReady.TabIndex = 4;
buttonIsReady.Text = "Заказ готов";
buttonIsReady.UseVisualStyleBackColor = true;
buttonIsReady.Click += buttonIsReady_Click;
//
// buttonIsDelivery
//
buttonIsDelivery.Location = new Point(732, 171);
buttonIsDelivery.Name = "buttonIsDelivery";
buttonIsDelivery.Size = new Size(212, 39);
buttonIsDelivery.TabIndex = 5;
buttonIsDelivery.Text = "Заказ выдан";
buttonIsDelivery.UseVisualStyleBackColor = true;
buttonIsDelivery.Click += buttonIsDelivery_Click;
//
// buttonUpdateList
//
buttonUpdateList.Location = new Point(732, 216);
buttonUpdateList.Name = "buttonUpdateList";
buttonUpdateList.Size = new Size(212, 39);
buttonUpdateList.TabIndex = 6;
buttonUpdateList.Text = "Обновить список";
buttonUpdateList.UseVisualStyleBackColor = true;
buttonUpdateList.Click += buttonUpdateList_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ScrollBar;
ClientSize = new Size(951, 450);
Controls.Add(buttonUpdateList);
Controls.Add(buttonIsDelivery);
Controls.Add(buttonIsReady);
Controls.Add(buttonInWork);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Заказы";
Load += FormMain_Load;
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem toolStripMenuItemMenu;
private DataGridView dataGridView;
private ToolStripMenuItem toolStripMenuItemFoods;
private ToolStripMenuItem toolStripMenuItemSnacks;
private Button buttonCreateOrder;
private Button buttonInWork;
private Button buttonIsReady;
private Button buttonIsDelivery;
private Button buttonUpdateList;
}
}

157
Diner/DinerView/FormMain.cs Normal file
View File

@ -0,0 +1,157 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
_logger.LogInformation("Загрузка заказов");
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ProductID"].Visible = false;
dataGridView.Columns["Sum"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void toolStripMenuItemFoods_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFoods));
if (service is FormFoods form) {
form.ShowDialog();
LoadData();
}
}
private void toolStripMenuItemSnacks_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnacks));
if (service is FormSnacks form) {
form.ShowDialog();
LoadData();
}
}
private void buttonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void buttonInWork_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ID"].Value);
_logger.LogInformation("Заказ №{ID}. Меняется статус на 'В работе'", id);
try
{
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { ID = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonIsReady_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id);
try
{
var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { ID = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonIsDelivery_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel { ID = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonUpdateList_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

242
Diner/DinerView/FormSnack.Designer.cs generated Normal file
View File

@ -0,0 +1,242 @@
namespace DinerView
{
partial class FormSnack
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelName = new Label();
labelPrice = new Label();
textBoxName = new TextBox();
textBoxPrice = new TextBox();
groupBoxFoods = new GroupBox();
buttonUpdate = new Button();
buttonRemove = new Button();
buttonChange = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
ColumnID = new DataGridViewTextBoxColumn();
ColumnFood = new DataGridViewTextBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
buttonCancel = new Button();
buttonSave = new Button();
groupBoxFoods.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// labelName
//
labelName.AutoSize = true;
labelName.Location = new Point(12, 9);
labelName.Name = "labelName";
labelName.Size = new Size(62, 15);
labelName.TabIndex = 0;
labelName.Text = "Название:";
//
// labelPrice
//
labelPrice.AutoSize = true;
labelPrice.Location = new Point(12, 36);
labelPrice.Name = "labelPrice";
labelPrice.Size = new Size(70, 15);
labelPrice.TabIndex = 1;
labelPrice.Text = "Стоимость:";
//
// textBoxName
//
textBoxName.Location = new Point(85, 6);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(367, 23);
textBoxName.TabIndex = 2;
//
// textBoxPrice
//
textBoxPrice.Enabled = false;
textBoxPrice.Location = new Point(85, 36);
textBoxPrice.Name = "textBoxPrice";
textBoxPrice.Size = new Size(367, 23);
textBoxPrice.TabIndex = 3;
//
// groupBoxFoods
//
groupBoxFoods.BackColor = SystemColors.ControlDark;
groupBoxFoods.Controls.Add(buttonUpdate);
groupBoxFoods.Controls.Add(buttonRemove);
groupBoxFoods.Controls.Add(buttonChange);
groupBoxFoods.Controls.Add(buttonAdd);
groupBoxFoods.Controls.Add(dataGridView);
groupBoxFoods.ForeColor = SystemColors.Control;
groupBoxFoods.Location = new Point(12, 65);
groupBoxFoods.Name = "groupBoxFoods";
groupBoxFoods.Size = new Size(657, 373);
groupBoxFoods.TabIndex = 4;
groupBoxFoods.TabStop = false;
groupBoxFoods.Text = "Используемые продукты";
//
// buttonUpdate
//
buttonUpdate.ForeColor = Color.Black;
buttonUpdate.Location = new Point(446, 148);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(205, 37);
buttonUpdate.TabIndex = 4;
buttonUpdate.Text = "Обновить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.ForeColor = Color.Black;
buttonRemove.Location = new Point(446, 105);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(205, 37);
buttonRemove.TabIndex = 3;
buttonRemove.Text = "Удалить";
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonChange
//
buttonChange.ForeColor = Color.Black;
buttonChange.Location = new Point(446, 62);
buttonChange.Name = "buttonChange";
buttonChange.Size = new Size(205, 37);
buttonChange.TabIndex = 2;
buttonChange.Text = "Изменить";
buttonChange.UseVisualStyleBackColor = true;
buttonChange.Click += buttonChange_Click;
//
// buttonAdd
//
buttonAdd.ForeColor = Color.Black;
buttonAdd.Location = new Point(446, 19);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(205, 37);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = SystemColors.ButtonFace;
dataGridView.BorderStyle = BorderStyle.None;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnID, ColumnFood, ColumnCount });
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(3, 19);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.DefaultCellStyle.ForeColor = Color.Black;
dataGridView.RowTemplate.Height = 22;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(437, 351);
dataGridView.TabIndex = 0;
//
// ColumnID
//
ColumnID.HeaderText = "ID";
ColumnID.Name = "ColumnID";
ColumnID.ReadOnly = true;
ColumnID.Visible = false;
//
// ColumnFood
//
ColumnFood.HeaderText = "Продукт";
ColumnFood.Name = "ColumnFood";
ColumnFood.ReadOnly = true;
ColumnFood.Width = 337;
//
// ColumnCount
//
ColumnCount.HeaderText = "Количество";
ColumnCount.Name = "ColumnCount";
ColumnCount.ReadOnly = true;
//
// buttonCancel
//
buttonCancel.Location = new Point(587, 30);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(82, 27);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(499, 30);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(82, 27);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormSnack
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(681, 450);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(groupBoxFoods);
Controls.Add(textBoxPrice);
Controls.Add(textBoxName);
Controls.Add(labelPrice);
Controls.Add(labelName);
Name = "FormSnack";
Text = "Снэки";
Load += FormSnack_Load;
groupBoxFoods.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelName;
private Label labelPrice;
private TextBox textBoxName;
private TextBox textBoxPrice;
private GroupBox groupBoxFoods;
private DataGridView dataGridView;
private Button buttonChange;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonRemove;
private Button buttonCancel;
private Button buttonSave;
private DataGridViewTextBoxColumn ColumnID;
private DataGridViewTextBoxColumn ColumnFood;
private DataGridViewTextBoxColumn ColumnCount;
}
}

View File

@ -0,0 +1,203 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using DinerDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormSnack : Form
{
private readonly ILogger _logger;
private readonly ISnackLogic _logic;
private int? _ID;
private Dictionary<int, (IFoodModel, int)> _productComponents;
public int ID { set { _ID = value; } }
public FormSnack(ILogger<FormSnack> logger, ISnackLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
_productComponents = new Dictionary<int, (IFoodModel, int)>();
}
private void FormSnack_Load(object sender, EventArgs e)
{
if (_ID.HasValue)
{
_logger.LogInformation("Загрузка снэка");
try
{
var view = _logic.ReadElement(new SnackSearchModel { ID = _ID.Value });
if (view != null)
{
textBoxName.Text = view.ProductName;
textBoxPrice.Text = view.Price.ToString();
_productComponents = view.ProductComponents ?? new Dictionary<int, (IFoodModel, int)>();
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки продуктов снэка");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка продукта снэка");
try
{
if (_productComponents != null)
{
dataGridView.Rows.Clear();
foreach (var elem in _productComponents)
{
dataGridView.Rows.Add(new object[] { elem.Key, elem.Value.Item1.ComponentName, elem.Value.Item2 });
}
textBoxPrice.Text = CalcPrice().ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки продукта снэка");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private double CalcPrice()
{
double price = 0;
foreach (var elem in _productComponents)
price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2);
return Math.Round(price * 1.1, 2);
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnackFood));
if (service is FormSnackFood form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.foodModel == null) return;
_logger.LogInformation("Добавление нового снэка: {ComponentName} - {Count}", form.foodModel.ComponentName, form.Count);
if (_productComponents.ContainsKey(form.ID))
{
_productComponents[form.ID] = (form.foodModel, form.Count);
}
else
{
_productComponents.Add(form.ID, (form.foodModel, form.Count));
}
LoadData();
}
}
}
private void buttonChange_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnackFood));
if (service is FormSnackFood form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.ID = id;
form.Count = _productComponents[id].Item2;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.foodModel == null) return;
_logger.LogInformation("Изменение снэка: {ComponentName} - {Count}", form.foodModel.ComponentName, form.Count);
_productComponents[form.ID] = (form.foodModel, form.Count);
LoadData();
}
}
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление снэка: {ComponentName}", dataGridView.SelectedRows[0].Cells[1].Value);
_productComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
LoadData();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxPrice.Text))
{
MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_productComponents == null || _productComponents.Count == 0)
{
MessageBox.Show("Заполните компоненты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение изделия");
try
{
var model = new SnackBindingModel
{
ID = _ID ?? 0,
ProductName = textBoxName.Text,
Price = Convert.ToDouble(textBoxPrice.Text),
ProductComponents = _productComponents
};
var operationResult = _ID.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения изделия");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="ColumnID.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnFood.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

120
Diner/DinerView/FormSnackFood.Designer.cs generated Normal file
View File

@ -0,0 +1,120 @@
namespace DinerView
{
partial class FormSnackFood
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
labelComponent = new Label();
labelCount = new Label();
comboBoxComponent = new ComboBox();
textBoxCount = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// labelComponent
//
labelComponent.AutoSize = true;
labelComponent.Location = new Point(12, 9);
labelComponent.Name = "labelComponent";
labelComponent.Size = new Size(28, 15);
labelComponent.TabIndex = 0;
labelComponent.Text = "Еда:";
//
// labelCount
//
labelCount.AutoSize = true;
labelCount.Location = new Point(12, 35);
labelCount.Name = "labelCount";
labelCount.Size = new Size(77, 15);
labelCount.TabIndex = 1;
labelCount.Text = "Количесиво:";
//
// comboBoxComponent
//
comboBoxComponent.BackColor = SystemColors.ButtonShadow;
comboBoxComponent.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxComponent.FormattingEnabled = true;
comboBoxComponent.Location = new Point(91, 6);
comboBoxComponent.Name = "comboBoxComponent";
comboBoxComponent.Size = new Size(291, 23);
comboBoxComponent.TabIndex = 2;
//
// textBoxCount
//
textBoxCount.Location = new Point(91, 35);
textBoxCount.Name = "textBoxCount";
textBoxCount.Size = new Size(291, 23);
textBoxCount.TabIndex = 3;
//
// buttonCancel
//
buttonCancel.Location = new Point(307, 64);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 4;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(226, 66);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 5;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormSnackFood
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(394, 101);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(textBoxCount);
Controls.Add(comboBoxComponent);
Controls.Add(labelCount);
Controls.Add(labelComponent);
Name = "FormSnackFood";
Text = "Продукты для снэков";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label labelComponent;
private Label labelCount;
private ComboBox comboBoxComponent;
private TextBox textBoxCount;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,89 @@
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormSnackFood : Form
{
private readonly List<FoodViewModel>? _list;
public int ID
{
get
{
return Convert.ToInt32(comboBoxComponent.SelectedValue);
}
set
{
comboBoxComponent.SelectedValue = value;
}
}
public IFoodModel? foodModel
{
get
{
if (_list == null) return null;
foreach (var elem in _list)
{
if (elem.ID == ID) return elem;
}
return null;
}
}
public int Count
{
get
{
return Convert.ToInt32(textBoxCount.Text);
}
set
{
textBoxCount.Text = value.ToString();
}
}
public FormSnackFood(IFoodLogic logic)
{
InitializeComponent();
_list = logic.ReadList(null);
if (_list != null)
{
comboBoxComponent.DisplayMember = "ComponentName";
comboBoxComponent.ValueMember = "ID";
comboBoxComponent.DataSource = _list;
comboBoxComponent.SelectedItem = null;
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCount.Text))
{
MessageBox.Show("Заполните поле количесвто", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxComponent.SelectedValue == null)
{
MessageBox.Show("Выберите продукт", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult = DialogResult.OK;
Close();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

122
Diner/DinerView/FormSnacks.Designer.cs generated Normal file
View File

@ -0,0 +1,122 @@
namespace DinerView
{
partial class FormSnacks
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
buttonUpdate = new Button();
buttonRemove = new Button();
buttonChange = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonUpdate
//
buttonUpdate.Location = new Point(578, 153);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(219, 41);
buttonUpdate.TabIndex = 9;
buttonUpdate.Text = "Обновить";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.Location = new Point(578, 106);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(219, 41);
buttonRemove.TabIndex = 8;
buttonRemove.Text = "Удалить";
buttonRemove.UseVisualStyleBackColor = true;
buttonRemove.Click += buttonRemove_Click;
//
// buttonChange
//
buttonChange.Location = new Point(578, 59);
buttonChange.Name = "buttonChange";
buttonChange.Size = new Size(219, 41);
buttonChange.TabIndex = 7;
buttonChange.Text = "Изменить";
buttonChange.UseVisualStyleBackColor = true;
buttonChange.Click += buttonChange_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(578, 12);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(219, 41);
buttonAdd.TabIndex = 6;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = SystemColors.ButtonHighlight;
dataGridView.BorderStyle = BorderStyle.None;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(563, 450);
dataGridView.TabIndex = 5;
//
// FormSnacks
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ScrollBar;
ClientSize = new Size(800, 450);
Controls.Add(buttonUpdate);
Controls.Add(buttonRemove);
Controls.Add(buttonChange);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormSnacks";
Text = "Снэки";
Load += FormSnacks_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonUpdate;
private Button buttonRemove;
private Button buttonChange;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,103 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DinerView
{
public partial class FormSnacks : Form
{
private readonly ILogger _logger;
private readonly ISnackLogic _logic;
public FormSnacks(ILogger<FormSnacks> logger, ISnackLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ID"].Visible = false;
dataGridView.Columns["ProductComponents"].Visible = false;
dataGridView.Columns["ProductName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка снэков");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки продуктов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnack));
if (service is FormSnack form) {
if (form.ShowDialog() == DialogResult.OK) LoadData();
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ID"].Value);
_logger.LogInformation("Удаление снэка");
try
{
if (!_logic.Delete(new SnackBindingModel { ID = id }))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления снэка");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonChange_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnack));
if (service is FormSnack form)
{
form.ID = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ID"].Value);
if (form.ShowDialog() == DialogResult.OK) LoadData();
}
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
LoadData();
}
private void FormSnacks_Load(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="log-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="tofile" />
</rules>
</nlog>
</configuration>

View File

@ -1,7 +1,17 @@
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements;
using DineryBusinessLogic.BusinessLogic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
namespace DinerView
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@ -11,7 +21,34 @@ namespace DinerView
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
services.AddTransient<IFoodStorage, FoodStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<ISnackStorage, SnackStorage>();
services.AddTransient<IFoodLogic, FoodLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<ISnackLogic, SnackLogic>();
services.AddTransient<FormMain>();
services.AddTransient<FormFood>();
services.AddTransient<FormFoods>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormSnack>();
services.AddTransient<FormSnackFood>();
services.AddTransient<FormSnacks>();
}
}
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DinerView.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DinerView.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,96 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.BusinessLogic
{
public class FoodLogic : IFoodLogic
{
private readonly ILogger _logger;
private readonly IFoodStorage _componentStorage;
public FoodLogic(ILogger<FoodLogic> logger, IFoodStorage componentStorage) {
_logger = logger;
_componentStorage = componentStorage;
}
public bool Create(FoodBindingModel model)
{
CheckModel(model);
if (_componentStorage.Insert(model) == null) {
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(FoodBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. ID:{ID}", model.ID);
if (_componentStorage.Delete(model) == null) {
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public FoodViewModel? ReadElement(FoodSearchModel model)
{
if (model == null) throw new ArgumentNullException(nameof(model));
_logger.LogInformation("ReadElement. ComponentName:{ComponentName}. ID:{ID}", model.ComponentName, model.ID);
var element = _componentStorage.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<FoodViewModel>? ReadList(FoodSearchModel? model)
{
_logger.LogInformation("ReadList. ComponentName:{ComponentName}. ID:{ID}", model?.ComponentName, model?.ID);
var list = model == null ? _componentStorage.GetFullList() : _componentStorage.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(FoodBindingModel model)
{
CheckModel(model);
if (_componentStorage.Update(model) == null) {
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(FoodBindingModel model, bool withParams = true) {
if (model == null) throw new ArgumentNullException(nameof(model));
if (!withParams) return;
if (string.IsNullOrEmpty(model.ComponentName))
throw new ArgumentNullException("Нет названия компонента", nameof(model.ComponentName));
if (model.Price <= 0)
throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(model.Price));
_logger.LogInformation("Component. ComponentName:{ComponentName}. Price:{Price}. ID:{ID}",
model.ComponentName, model.Price, model.ID);
var element = _componentStorage.GetElement(new FoodSearchModel { ComponentName = model.ComponentName });
if (element != null && element.ID != model.ID)
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}

View File

@ -0,0 +1,101 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataModels.Enums;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.BusinessLogic
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) {
_logger = logger;
_orderStorage = orderStorage;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) {
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool DeliveryOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выдан);
}
public bool FinishOrder(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Готов);
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. ID:{ID}", model?.ID);
var list = model == null? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null) {
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выполняется);
}
private void CheckModel(OrderBindingModel model, bool withParams = true) {
if (model == null) throw new ArgumentNullException(nameof(model));
if (!withParams) return;
if (string.IsNullOrEmpty((model.ID).ToString()))
throw new ArgumentNullException("Нет ID заказа", nameof(model.ID));
if (model.Sum <= 0)
throw new ArgumentNullException("Цена заказа должна быть больше 0", nameof(model.Sum));
_logger.LogInformation("Order. ProductID:{ProductID}. Count:{Count}. Sum:{Sum}. Status:{Status}. " +
"DateCreate:{DateCreate}. DateImplement:{DateImplement}. ID:{ID}",
model.ProductID, model.Count, model.Sum, model.Status, model.DateCreate, model.DateImplement, model.ID);
}
private bool StatusUpdate(OrderBindingModel model, OrderStatus newOrderStatus) {
CheckModel(model, false);
var viewModel = _orderStorage.GetElement(new OrderSearchModel { ID = model.ID });
if (viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
if (viewModel.Status + 1 != newOrderStatus) {
_logger.LogWarning("Status update to " + newOrderStatus.ToString() + " operation failed.");
return false;
}
model.Status = newOrderStatus;
if (model.Status == OrderStatus.Готов) {
model.DateImplement = DateTime.Now;
}
else {
model.DateImplement = viewModel.DateImplement;
}
if (_orderStorage.Update(model) == null) {
_logger.LogWarning("Update operarion failed");
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,95 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContacts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DineryBusinessLogic.BusinessLogic
{
public class SnackLogic : ISnackLogic
{
private readonly ILogger _logger;
private readonly ISnackStorage _productStorage;
public SnackLogic(ILogger<SnackLogic> logger, ISnackStorage productStorage) {
_logger = logger;
_productStorage = productStorage;
}
public bool Create(SnackBindingModel model)
{
CheckModel(model);
if (_productStorage.Insert(model) == null) {
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(SnackBindingModel model)
{
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 SnackViewModel? ReadElement(SnackSearchModel model)
{
if (model == null) throw new ArgumentNullException(nameof(model));
_logger.LogInformation("ReadElement. ProductName:{ProductName}. ID:{ID}", model.ProductName, model.ID);
var element = _productStorage.GetElement(model);
if (element == null) {
_logger.LogWarning("ReadElement. elementn not found");
return null;
}
_logger.LogInformation("ReadElement find. ID:{ID}", element.ID);
return element;
}
public List<SnackViewModel>? ReadList(SnackSearchModel? model)
{
_logger.LogInformation("ReadList. ProductName:{ProductName}. ID:{ID}", model?.ProductName, 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(SnackBindingModel model)
{
CheckModel(model);
if (_productStorage.Update(model) == null) {
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(SnackBindingModel model, bool withParams = true) {
if (model == null) throw new ArgumentNullException(nameof(model));
if (!withParams) return;
if (string.IsNullOrEmpty(model.ProductName))
throw new ArgumentNullException("Нет названия продукта", nameof(model.ProductName));
if (model.Price <= 0)
throw new ArgumentNullException("Цена продукта должна быть больше 0", nameof(model.Price));
_logger.LogInformation("Product. ProductName:{ProductName}. Price:{Price}. ID:{ID}",
model.ProductName, model.Price, model.ID);
var element = _productStorage.GetElement(new SnackSearchModel { ProductName = model.ProductName });
if (element != null && element.ID != model.ID)
throw new InvalidOperationException("Продукт с таким названием уже есть");
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DinerContracts\DinerContracts.csproj" />
</ItemGroup>
</Project>