Compare commits

...

49 Commits

Author SHA1 Message Date
b854ae9980 надеюсь починила 2024-05-22 11:49:32 +04:00
6d6b9e1ed6 ломаю 2024-05-22 11:48:57 +04:00
102d8b3209 проект не сломался но получилось не то 2024-05-22 11:43:37 +04:00
1c861981b0 еще правки лабы 8 надеюсь проект не сломается 2024-05-22 11:38:53 +04:00
0d059a18c8 точно итоговая лаба 8 2024-05-22 11:26:07 +04:00
6cd3d8dd1d лаба 8 готова не знаю работает или нет но у меня ноут сдох 2024-05-19 19:03:16 +04:00
46e9841ebd почти готовая лаба 8 2024-05-19 14:37:57 +04:00
677190ee63 начало работы над лабой 8 2024-05-19 12:15:07 +04:00
9ffc761a2a лаба 7 вроде готовая 2024-05-18 17:52:58 +04:00
54593e8d41 лаба 7 по новой 2024-05-18 15:44:04 +04:00
602f2fe18f какие то правки лаба 6 2024-05-12 12:36:27 +04:00
9af6400a62 6 лаба))) вроде готовая 2024-05-08 09:35:27 +04:00
686c850a1f лаба 6 вроде готовая 2024-05-05 16:00:24 +04:00
f367e8f391 6 лаба полуработает 2024-05-05 13:22:21 +04:00
d1973efdce 6 лаба беда бедовая не работает 2024-05-05 12:47:03 +04:00
2878ea7bbb лаба 6 не могу найти ошибку( 2024-05-05 01:25:26 +04:00
5c705ba1c6 лаба 6 ломаю бд 2024-05-05 00:58:09 +04:00
eb7626e75e лаба 6 почти готовая 2024-05-04 23:59:55 +04:00
24e94a520f лаба 6 начало работы 2024-05-04 15:51:52 +04:00
a9d1612819 итогововые правки 5 лаба 2024-04-24 09:14:37 +04:00
fed4dd969e готовая лаба 5!!!!!! (вроде) 2024-04-22 23:44:49 +04:00
aa3ac27c73 почистила таблички 2024-04-22 16:29:07 +04:00
0ea451ab43 лаба 5 оно не работает я скоро выкину ноут в окно 2024-04-21 13:35:23 +04:00
3bffef1d0d работа над лабой 5 продолжение 2024-04-21 12:18:48 +04:00
12b16be979 вообще не готовая лаба 5 но я пыталась как могла 2024-04-20 23:00:09 +04:00
c201889188 итоговые правки 2024-04-20 16:17:34 +04:00
9986b09119 точно готовая лаба 4 2024-04-20 15:51:24 +04:00
9591bd189e полурабочая лаба 4 2024-04-09 15:45:07 +04:00
bdc1f0d440 работаю над 4 лабой 2024-04-08 22:00:27 +04:00
fdc97f3c79 лаба 4 в процессе 2024-04-08 21:48:15 +04:00
ea75c323ef Merge branch 'LabWork_03' of http://student.git.athene.tech/chubykina_polina/PIbd-22_Chubykina_P.P._Confectionery into LabWork_03 2024-04-08 12:58:52 +04:00
8ec0755e6f вроде готовая лаба 3 2024-04-08 12:58:24 +04:00
0f60538d5f подкорректировала :) 2024-04-08 12:54:42 +04:00
f14a4ae2e1 вроде точно готовая лаба 3 2024-03-27 09:27:41 +04:00
65b5f5e0fb вроде готовая лаба 3 2024-03-25 22:59:49 +04:00
b2654e819c готовая лаба 2 2024-03-13 10:40:29 +04:00
851a875b08 поломала что-то 2024-03-13 10:15:47 +04:00
d5d622ed8e точно готовая лаба 1 2024-03-12 21:06:28 +04:00
35d8276190 точно готовая лаба 1 2024-03-12 21:04:18 +04:00
0fda2353bc еще раз готовая лаба 1 2024-03-09 14:59:05 +04:00
47e2bc50b8 лаба 1 готовая 2024-03-09 14:46:08 +04:00
deef66e3fc лаба 1 готовя 2024-02-28 10:03:27 +04:00
9210394589 почти готовая лаба 1 2024-02-27 23:07:55 +04:00
b4a88a1231 что-то делается 2024-02-27 22:14:35 +04:00
0763ef71df главная формочка готова 2024-02-27 15:58:29 +04:00
32d416e795 формочка с заказом 2024-02-27 15:35:42 +04:00
6706d82142 работа над формой 2024-02-27 15:14:49 +04:00
54775f3000 добавила форму 2024-02-27 13:00:47 +04:00
47211b373e сделала нерабочий кал 2024-02-27 12:37:50 +04:00
277 changed files with 88174 additions and 51 deletions

1
.gitignore vendored
View File

@ -398,3 +398,4 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
/Confectionery/ImplementationExtensions

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public ColumnAttribute(string title = "", bool visible = true, int width = 0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool isUseAutoSize = false)
{
Title = title;
Visible = visible;
Width = width;
GridViewAutoSize = gridViewAutoSize;
IsUseAutoSize = isUseAutoSize;
}
public string Title { get; private set; }
public bool Visible { get; private set; }
public int Width { get; private set; }
public GridViewAutoSize GridViewAutoSize { get; private set; }
public bool IsUseAutoSize { get; private set; }
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.Attributes
{
public enum GridViewAutoSize
{
NotSet = 0,
None = 1,
ColumnHeader = 2,
AllCellsExceptHeader = 4,
AllCells = 6,
DisplayedCellsExceptHeader = 8,
DisplayedCells = 10,
Fill = 16
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BindingModels
{
public class BackUpSaveBindingModel
{
public string FolderName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
namespace ConfectioneryContracts.BindingModels
{
public class ClientBindingModel : IClientModel
{
public int Id { get; set; }
public string ClientFIO { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
namespace ConfectioneryContracts.BindingModels
{
public class ComponentBindingModel : IComponentModel
{
public int Id { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using ConfectioneryDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BindingModels
{
public class ImplementerBindingModel : IImplementerModel
{
public int Id { get; set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
}
}

View File

@ -0,0 +1,17 @@
namespace ConfectioneryContracts.BindingModels
{
public class MailConfigBindingModel
{
public string MailLogin { get; set; } = string.Empty;
public string MailPassword { get; set; } = string.Empty;
public string SmtpClientHost { get; set; } = string.Empty;
public int SmtpClientPort { get; set; }
public string PopHost { get; set; } = string.Empty;
public int PopPort { get; set; }
}
}

View File

@ -0,0 +1,11 @@
namespace ConfectioneryContracts.BindingModels
{
public class MailSendInfoBindingModel
{
public string MailAddress { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,20 @@
using ConfectioneryDataModels.Models;
namespace ConfectioneryContracts.BindingModels
{
public class MessageInfoBindingModel : IMessageInfoModel
{
public int Id => throw new NotImplementedException();
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Enums;
using ConfectioneryDataModels.Models;
namespace ConfectioneryContracts.BindingModels
{
public class OrderBindingModel : IOrderModel
{
public int Id { get; set; }
public int PastryId { get; set; }
public int ClientId { get; set; }
public int? ImplementerId { 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; }
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
namespace ConfectioneryContracts.BindingModels
{
public class PastryBindingModel : IPastryModel
{
public int Id { get; set; }
public string PastryName { get; set; } = string.Empty;
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> PastryComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BindingModels
{
public class ReportBindingModel
{
public string FileName { get; set; } = string.Empty;
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.BindingModels;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IBackUpLogic
{
void CreateBackUp(BackUpSaveBindingModel model);
}
}

View File

@ -0,0 +1,20 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IClientLogic
{
List<ClientViewModel>? ReadList(ClientSearchModel? model);
ClientViewModel? ReadElement(ClientSearchModel model);
bool Create(ClientBindingModel model);
bool Update(ClientBindingModel model);
bool Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IComponentLogic
{
List<ComponentViewModel>? ReadList(ComponentSearchModel? model);
ComponentViewModel? ReadElement(ComponentSearchModel model);
bool Create(ComponentBindingModel model);
bool Update(ComponentBindingModel model);
bool Delete(ComponentBindingModel model);
}
}

View File

@ -0,0 +1,20 @@
using ConfectioneryContracts.BindingModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IImplementerLogic
{
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
ImplementerViewModel? ReadElement(ImplementerSearchModel model);
bool Create(ImplementerBindingModel model);
bool Update(ImplementerBindingModel model);
bool Delete(ImplementerBindingModel model);
}
}

View File

@ -0,0 +1,12 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model);
}
}

View File

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

View File

@ -0,0 +1,20 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IPastryLogic
{
List<PastryViewModel>? ReadList(PastrySearchModel? model);
PastryViewModel? ReadElement(PastrySearchModel model);
bool Create(PastryBindingModel model);
bool Update(PastryBindingModel model);
bool Delete(PastryBindingModel model);
}
}

View File

@ -0,0 +1,19 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IReportLogic
{
List<ReportPastryComponentViewModel> GetPastryComponent();
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
void SavePastriesToWordFile(ReportBindingModel model);
void SavePastryComponentToExcelFile(ReportBindingModel model);
void SaveOrdersToPdfFile(ReportBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.BusinessLogicsContracts
{
public interface IWorkProcess
{
/// <summary>
/// Запуск работ
/// </summary>
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConfectionaryDataModels\ConfectioneryDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,62 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.DI
{
public class DependencyManager
{
private readonly IDependencyContainer _dependencyManager;
private static DependencyManager? _manager;
private static readonly object _lockObject = new();
private DependencyManager()
{
_dependencyManager = new UnityDependencyContainer();
}
public static DependencyManager Instance { get { if (_manager == null) { lock (_lockObject) { _manager = new DependencyManager(); } } return _manager; } }
public static void InitDependency()
{
var ext = ServiceProviderLoader.GetImplementationExtensions();
if (ext == null)
{
throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям");
}
ext.RegisterServices();
}
/// <summary>
/// Регистрация логгера
/// </summary>
/// <param name="configure"></param>
public void AddLogging(Action<ILoggingBuilder> configure) => _dependencyManager.AddLogging(configure);
/// <summary>
/// Добавление зависимости
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
public void RegisterType<T, U>(bool isSingle = false) where U : class, T where T : class => _dependencyManager.RegisterType<T, U>(isSingle);
/// <summary>
/// Добавление зависимости
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
public void RegisterType<T>(bool isSingle = false) where T : class => _dependencyManager.RegisterType<T>(isSingle);
/// <summary>
/// Получение класса со всеми зависмостями
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>() => _dependencyManager.Resolve<T>();
}
}

View File

@ -0,0 +1,40 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.DI
{
public interface IDependencyContainer
{
/// <summary>
/// Регистрация логгера
/// </summary>
/// <param name="configure"></param>
void AddLogging(Action<ILoggingBuilder> configure);
/// <summary>
/// Добавление зависимости
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <param name="isSingle"></param>
void RegisterType<T, U>(bool isSingle) where U : class, T where T : class;
/// <summary>
/// Добавление зависимости
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="isSingle"></param>
void RegisterType<T>(bool isSingle) where T : class;
/// <summary>
/// Получение класса со всеми зависмостями
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Resolve<T>();
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.DI
{
public interface IImplementationExtension
{
public int Priority { get; }
/// <summary>
/// Регистрация сервисов
/// </summary>
public void RegisterServices();
}
}

View File

@ -0,0 +1,62 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.DI
{
public class ServiceDependencyContainer : IDependencyContainer
{
private ServiceProvider? _serviceProvider;
private readonly ServiceCollection _serviceCollection;
public ServiceDependencyContainer()
{
_serviceCollection = new ServiceCollection();
}
public void AddLogging(Action<ILoggingBuilder> configure)
{
_serviceCollection.AddLogging(configure);
}
public void RegisterType<T, U>(bool isSingle) where U : class, T where T : class
{
if (isSingle)
{
_serviceCollection.AddSingleton<T, U>();
}
else
{
_serviceCollection.AddTransient<T, U>();
}
_serviceProvider = null;
}
public void RegisterType<T>(bool isSingle) where T : class
{
if (isSingle)
{
_serviceCollection.AddSingleton<T>();
}
else
{
_serviceCollection.AddTransient<T>();
}
_serviceProvider = null;
}
public T Resolve<T>()
{
if (_serviceProvider == null)
{
_serviceProvider = _serviceCollection.BuildServiceProvider();
}
return _serviceProvider.GetService<T>()!;
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.DI
{
public class ServiceProviderLoader
{
/// <summary>
/// Загрузка всех классов-реализаций IImplementationExtension
/// </summary>
/// <returns></returns>
public static IImplementationExtension? GetImplementationExtensions()
{
IImplementationExtension? source = null;
var files = Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", SearchOption.AllDirectories);
foreach (var file in files.Distinct())
{
Assembly asm = Assembly.LoadFrom(file);
foreach (var t in asm.GetExportedTypes())
{
if (t.IsClass && typeof(IImplementationExtension).IsAssignableFrom(t))
{
if (source == null)
{
source = (IImplementationExtension)Activator.CreateInstance(t)!;
}
else
{
var newSource = (IImplementationExtension)Activator.CreateInstance(t)!;
if (newSource.Priority > source.Priority)
{
source = newSource;
}
}
}
}
}
return source;
}
private static string TryGetImplementationExtensionsFolder()
{
var directory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (directory != null && !directory.GetDirectories("ImplementationExtensions", SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions"))
{
directory = directory.Parent;
}
return $"{directory?.FullName}\\ImplementationExtensions";
}
}
}

View File

@ -0,0 +1,42 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Microsoft.Logging;
using Unity;
namespace ConfectioneryContracts.DI
{
public class UnityDependencyContainer : IDependencyContainer
{
private readonly IUnityContainer _container;
public UnityDependencyContainer()
{
_container = new UnityContainer();
}
public void AddLogging(Action<ILoggingBuilder> configure)
{
var factory = LoggerFactory.Create(configure);
_container.AddExtension(new LoggingExtension(factory));
}
public void RegisterType<T, U>(bool isSingle) where U : class, T where T : class
{
_container.RegisterType<T, U>(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
public void RegisterType<T>(bool isSingle) where T : class
{
_container.RegisterType<T>(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.SearchModels
{
public class ClientSearchModel
{
public int? Id { get; set; }
public string? ClientFIO { get; set; }
public string? Email { get; set; }
public string? Password { 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 ConfectioneryContracts.SearchModels
{
public class ComponentSearchModel
{
public int? Id { get; set; }
public string? ComponentName { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.SearchModels
{
public class ImplementerSearchModel
{
public int? Id { get; set; }
public string? ImplementerFIO { get; set; }
public string? Password { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace ConfectioneryContracts.SearchModels
{
public class MessageInfoSearchModel
{
public int? ClientId { get; set; }
public string? MessageId { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using ConfectioneryDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.SearchModels
{
public class OrderSearchModel
{
public int? Id { get; set; }
public int? ClientId { get; set; }
public int? ImplementerId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public OrderStatus? Status { 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 ConfectioneryContracts.SearchModels
{
public class PastrySearchModel
{
public int? Id { get; set; }
public string? PastryName { 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 ConfectioneryContracts.StoragesContracts
{
public interface IBackUpInfo
{
List<T>? GetList<T>() where T : class, new();
Type? GetTypeByModelInterface(string modelInterfaceName);
}
}

View File

@ -0,0 +1,21 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.StoragesContracts
{
public interface IClientStorage
{
List<ClientViewModel> GetFullList();
List<ClientViewModel> GetFilteredList(ClientSearchModel model);
ClientViewModel? GetElement(ClientSearchModel model);
ClientViewModel? Insert(ClientBindingModel model);
ClientViewModel? Update(ClientBindingModel model);
ClientViewModel? Delete(ClientBindingModel model);
}
}

View File

@ -0,0 +1,22 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.StoragesContracts
{
public interface IComponentStorage
{
List<ComponentViewModel> GetFullList();
List<ComponentViewModel> GetFilteredList(ComponentSearchModel model);
ComponentViewModel? GetElement(ComponentSearchModel model);
ComponentViewModel? Insert(ComponentBindingModel model);
ComponentViewModel? Update(ComponentBindingModel model);
ComponentViewModel? Delete(ComponentBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.StoragesContracts
{
public interface IImplementerStorage
{
List<ImplementerViewModel> GetFullList();
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
ImplementerViewModel? GetElement(ImplementerSearchModel model);
ImplementerViewModel? Insert(ImplementerBindingModel model);
ImplementerViewModel? Update(ImplementerBindingModel model);
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

@ -0,0 +1,17 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryContracts.StoragesContracts
{
public interface IMessageInfoStorage
{
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
}
}

View File

@ -0,0 +1,21 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.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,21 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.StoragesContracts
{
public interface IPastryStorage
{
List<PastryViewModel> GetFullList();
List<PastryViewModel> GetFilteredList(PastrySearchModel model);
PastryViewModel? GetElement(PastrySearchModel model);
PastryViewModel? Insert(PastryBindingModel model);
PastryViewModel? Update(PastryBindingModel model);
PastryViewModel? Delete(PastryBindingModel model);
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
using System.ComponentModel;
using ConfectioneryContracts.Attributes;
namespace ConfectioneryContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "ФИО клиента", width: 150)]
public string ClientFIO { get; set; } = string.Empty;
[Column(title: "Логин (эл. почта)", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string Email { get; set; } = string.Empty;
[Column(title: "Пароль", width: 150)]
public string Password { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
using System.ComponentModel;
using ConfectioneryContracts.Attributes;
namespace ConfectioneryContracts.ViewModels
{
public class ComponentViewModel : IComponentModel
{
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "Название компонента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string ComponentName { get; set; } = string.Empty;
[Column(title: "Цена", width: 150)]
public double Cost { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using ConfectioneryContracts.Attributes;
using ConfectioneryDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
{
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string ImplementerFIO { get; set; } = string.Empty;
[Column(title: "Пароль", width: 100)]
public string Password { get; set; } = string.Empty;
[Column(title: "Стаж работы", width: 100)]
public int WorkExperience { get; set; }
[Column(title: "Квалификация", width: 100)]
public int Qualification { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using ConfectioneryContracts.Attributes;
using ConfectioneryDataModels.Models;
using System.ComponentModel;
namespace ConfectioneryContracts.ViewModels
{
public class MessageInfoViewModel : IMessageInfoModel
{
[Column(visible: false)]
public int Id { get; set; }
[Column(visible: false)]
public string MessageId { get; set; } = string.Empty;
[Column(visible: false)]
public int? ClientId { get; set; }
[Column(title: "Отправитель", width: 150)]
public string SenderName { get; set; } = string.Empty;
[Column(title: "Дата письма", width: 120)]
public DateTime DateDelivery { get; set; }
[Column(title: "Дата письма", width: 150)]
public string Subject { get; set; } = string.Empty;
[Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string Body { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
using System.ComponentModel;
using ConfectioneryDataModels.Enums;
using ConfectioneryContracts.Attributes;
namespace ConfectioneryContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[Column(title: "Номер", width: 100)]
public int Id { get; set; }
[Column(visible: false)]
public int PastryId { get; set; }
[Column(title: "Выпечка", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string PastryName { get; set; } = string.Empty;
[Column(visible: false)]
public int ClientId { get; set; }
[Column(title: "ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string ClientFIO { get; set; } = string.Empty;
[Column(visible: false)]
public string ClientEmail { get; set; } = string.Empty;
[Column(visible: false)]
public int? ImplementerId { get; set; }
[Column(title: "ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string ImplementerFIO { get; set; } = string.Empty;
[Column(title: "Количество", width: 100)]
public int Count { get; set; }
[Column(title: "Сумма", width: 120)]
public double Sum { get; set; }
[Column(title: "Статус", width: 100)]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[Column(title: "Дата создания", width: 120)]
public DateTime DateCreate { get; set; } = DateTime.Now;
[Column(title: "Дата выполнения", width: 120)]
public DateTime? DateImplement { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryDataModels.Models;
using System.ComponentModel;
using ConfectioneryContracts.Attributes;
namespace ConfectioneryContracts.ViewModels
{
public class PastryViewModel : IPastryModel
{
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "Название выпечки", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string PastryName { get; set; } = string.Empty;
[Column(title: "Цена", width: 150)]
public double Price { get; set; }
[Column(visible: false)]
public Dictionary<int, (IComponentModel, int)> PastryComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.ViewModels
{
public class ReportOrdersViewModel
{
public int Id { get; set; }
public DateTime DateCreate { get; set; }
public string PastryName { get; set; } = string.Empty;
public string OrderStatus { get; set; } = string.Empty;
public double Sum { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryContracts.ViewModels
{
public class ReportPastryComponentViewModel
{
public string PastryName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<(string Component, int Count)> Components { get; set; } = new();
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,11 @@
namespace ConfectioneryDataModels.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 ConfectioneryDataModels
{
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IClientModel : IId
{
string ClientFIO { get; }
string Email { get; }
string Password { get; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IComponentModel : IId
{
string ComponentName { get; }
double Cost { get; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IImplementerModel : IId
{
string ImplementerFIO { get; }
string Password { get; }
int WorkExperience { get; }
int Qualification { get; }
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IMessageInfoModel : IId
{
string MessageId { get; }
int? ClientId { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@ -0,0 +1,21 @@
using ConfectioneryDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IOrderModel : IId
{
int PastryId { get; }
int ClientId { get; }
int? ImplementerId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryDataModels.Models
{
public interface IPastryModel : IId
{
string PastryName { get; }
double Price { get; }
Dictionary<int, (IComponentModel, int)> PastryComponents { get; }
}
}

View File

@ -3,7 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32825.248
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryView", "ConfectioneryView\ConfectioneryView.csproj", "{2DAD8519-A540-4312-B881-47D4AFE97E7F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryView", "ConfectioneryView\ConfectioneryView.csproj", "{2DAD8519-A540-4312-B881-47D4AFE97E7F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDataModels", "ConfectionaryDataModels\ConfectioneryDataModels.csproj", "{0E74E5DA-C6A4-4001-A02A-7B4316A1B9ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryContracts", "ConfectionaryContracts\ConfectioneryContracts.csproj", "{4BC782E2-5108-4C55-9F76-ACE5A56B8735}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryBusinessLogic", "ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{2822ACD8-8B94-4BF2-8C55-478677FDD1FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryListImplement", "ConfectioneryListImplement\ConfectioneryListImplement.csproj", "{EE30482F-8998-4178-8412-421A02F6A6B4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryFileImplement", "ConfectioneryFileImplement\ConfectioneryFileImplement.csproj", "{0607BCF8-D685-49A9-9C16-76BD0E8BAAA7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDatabaseImplement", "ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj", "{03D1ACA7-5F94-4B79-B558-7D5DADF11E1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryRestApi", "ConfectioneryRestApi\ConfectioneryRestApi.csproj", "{0C82BF93-B213-4046-B71D-99FA22FA27AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryClientApp", "ConfectioneryClientApp\ConfectioneryClientApp.csproj", "{40E995E9-03E4-4233-B7C7-9E5E26E8190F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +31,38 @@ Global
{2DAD8519-A540-4312-B881-47D4AFE97E7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DAD8519-A540-4312-B881-47D4AFE97E7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DAD8519-A540-4312-B881-47D4AFE97E7F}.Release|Any CPU.Build.0 = Release|Any CPU
{0E74E5DA-C6A4-4001-A02A-7B4316A1B9ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E74E5DA-C6A4-4001-A02A-7B4316A1B9ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E74E5DA-C6A4-4001-A02A-7B4316A1B9ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E74E5DA-C6A4-4001-A02A-7B4316A1B9ED}.Release|Any CPU.Build.0 = Release|Any CPU
{4BC782E2-5108-4C55-9F76-ACE5A56B8735}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BC782E2-5108-4C55-9F76-ACE5A56B8735}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BC782E2-5108-4C55-9F76-ACE5A56B8735}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BC782E2-5108-4C55-9F76-ACE5A56B8735}.Release|Any CPU.Build.0 = Release|Any CPU
{2822ACD8-8B94-4BF2-8C55-478677FDD1FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2822ACD8-8B94-4BF2-8C55-478677FDD1FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2822ACD8-8B94-4BF2-8C55-478677FDD1FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2822ACD8-8B94-4BF2-8C55-478677FDD1FE}.Release|Any CPU.Build.0 = Release|Any CPU
{EE30482F-8998-4178-8412-421A02F6A6B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE30482F-8998-4178-8412-421A02F6A6B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE30482F-8998-4178-8412-421A02F6A6B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE30482F-8998-4178-8412-421A02F6A6B4}.Release|Any CPU.Build.0 = Release|Any CPU
{0607BCF8-D685-49A9-9C16-76BD0E8BAAA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0607BCF8-D685-49A9-9C16-76BD0E8BAAA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0607BCF8-D685-49A9-9C16-76BD0E8BAAA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0607BCF8-D685-49A9-9C16-76BD0E8BAAA7}.Release|Any CPU.Build.0 = Release|Any CPU
{03D1ACA7-5F94-4B79-B558-7D5DADF11E1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03D1ACA7-5F94-4B79-B558-7D5DADF11E1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03D1ACA7-5F94-4B79-B558-7D5DADF11E1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03D1ACA7-5F94-4B79-B558-7D5DADF11E1E}.Release|Any CPU.Build.0 = Release|Any CPU
{0C82BF93-B213-4046-B71D-99FA22FA27AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C82BF93-B213-4046-B71D-99FA22FA27AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C82BF93-B213-4046-B71D-99FA22FA27AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C82BF93-B213-4046-B71D-99FA22FA27AC}.Release|Any CPU.Build.0 = Release|Any CPU
{40E995E9-03E4-4233-B7C7-9E5E26E8190F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40E995E9-03E4-4233-B7C7-9E5E26E8190F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40E995E9-03E4-4233-B7C7-9E5E26E8190F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40E995E9-03E4-4233-B7C7-9E5E26E8190F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,103 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryDataModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class BackUpLogic : IBackUpLogic
{
private readonly ILogger _logger;
private readonly IBackUpInfo _backUpInfo;
public BackUpLogic(ILogger<BackUpLogic> logger, IBackUpInfo backUpInfo)
{
_logger = logger;
_backUpInfo = backUpInfo;
}
public void CreateBackUp(BackUpSaveBindingModel model)
{
if (_backUpInfo == null)
{
return;
}
try
{
_logger.LogDebug("Clear folder");
// зачистка папки и удаление старого архива
var dirInfo = new DirectoryInfo(model.FolderName);
if (dirInfo.Exists)
{
foreach (var file in dirInfo.GetFiles())
{
file.Delete();
}
}
_logger.LogDebug("Delete archive");
string fileName = $"{model.FolderName}.zip";
if (File.Exists(fileName))
{
File.Delete(fileName);
}
// берем метод для сохранения
_logger.LogDebug("Get assembly");
var typeIId = typeof(IId);
var assembly = typeIId.Assembly;
if (assembly == null)
{
throw new ArgumentNullException("Сборка не найдена", nameof(assembly));
}
var types = assembly.GetTypes();
var method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance);
_logger.LogDebug("Find {count} types", types.Length);
foreach (var type in types)
{
if (type.IsInterface && type.GetInterface(typeIId.Name) != null)
{
var modelType = _backUpInfo.GetTypeByModelInterface(type.Name);
if (modelType == null)
{
throw new InvalidOperationException($"Не найден класс-модель для {type.Name}");
}
_logger.LogDebug("Call SaveToFile method for {name} type", type.Name);
// вызываем метод на выполнение
method?.MakeGenericMethod(modelType).Invoke(this, new object[] { model.FolderName });
}
}
_logger.LogDebug("Create zip and remove folder");
// архивируем
ZipFile.CreateFromDirectory(model.FolderName, fileName);
// удаляем папку
dirInfo.Delete(true);
}
catch (Exception)
{
throw;
}
}
private void SaveToFile<T>(string folderName) where T : class, new()
{
var records = _backUpInfo.GetList<T>();
if (records == null)
{
_logger.LogWarning("{type} type get null list", typeof(T).Name);
return;
}
var jsonFormatter = new DataContractJsonSerializer(typeof(List<T>));
using var fs = new FileStream(string.Format("{0}/{1}.json", folderName, typeof(T).Name), FileMode.OpenOrCreate);
jsonFormatter.WriteObject(fs, records);
}
}
}

View File

@ -0,0 +1,120 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. Email: {Email}. Id: {Id} ", model?.Email, model?.Id);
var list = (model == null) ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Client email: {Email}. Client id: {Id}", model.Email, model.Id);
var element = _clientStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_clientStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email) || !Regex.IsMatch(model.Email, @"^[a-z0-9._%+-]+\@([a-z0-9-]+\.)+[a-z]{2,4}$"))
{
throw new ArgumentNullException("Некорректно введен логин(почта) клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password) || !Regex.IsMatch(model.Password, @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9\n]).{10,50}$"))
{
throw new ArgumentNullException("Некорректно введен пароль клиента", nameof(model.Password));
}
_logger.LogInformation("Client. Id: {id}, FIO: {fio}, email: {email}, password: {password}", model.Id, model.ClientFIO, model.Email, model.Password);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким логином(почтой) уже есть");
}
}
}
}

View File

@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class ComponentLogic : IComponentLogic
{
private readonly ILogger _logger;
private readonly IComponentStorage _componentStorage;
public ComponentLogic(ILogger<ComponentLogic> logger, IComponentStorage componentStorage)
{
_logger = logger;
_componentStorage = componentStorage;
}
public List<ComponentViewModel>? ReadList(ComponentSearchModel? 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 ComponentViewModel? ReadElement(ComponentSearchModel 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 bool Create(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ComponentBindingModel 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;
}
private void CheckModel(ComponentBindingModel 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.Cost <= 0)
{
throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(model.Cost));
}
_logger.LogInformation("Component. ComponentName:{ComponentName}. Cost:{Cost}. Id:{Id}", model.ComponentName, model.Cost, model.Id);
var element = _componentStorage.GetElement(new ComponentSearchModel
{
ComponentName = model.ComponentName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,129 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
private readonly ILogger _logger;
private readonly IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<ImplementerLogic> logger, IImplementerStorage implementerStorage)
{
_logger = logger;
_implementerStorage = implementerStorage;
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model)
{
_logger.LogInformation("ReadList. ImplementerFIO: {ImplementerFIO}. Id: {Id}", model?.ImplementerFIO, model?.Id);
var list = model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public ImplementerViewModel? ReadElement(ImplementerSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ImplementerFIO: {ImplementerFIO}. Id: {Id}", model.ImplementerFIO, model.Id);
var element = _implementerStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ImplementerBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_implementerStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ImplementerBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.ImplementerFIO));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.Password));
}
if (model.WorkExperience <= 0)
{
throw new ArgumentNullException("Стаж работы исполнителя должен быть больше 0", nameof(model.WorkExperience));
}
if (model.Qualification <= 0)
{
throw new ArgumentNullException("Квалификация исполнителя должен быть больше 0", nameof(model.Qualification));
}
_logger.LogInformation("Implementer. Id: {Id}. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Qualification: {Qualification}. " +
"WorkExperience: {WorkExperience}", model.Id, model.ImplementerFIO, model.Password, model.Qualification, model.WorkExperience);
var element = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = model.ImplementerFIO
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Исполнитель с таким ФИО уже существует");
}
}
}
}

View File

@ -0,0 +1,90 @@
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
private readonly IClientStorage _clientStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage messageInfoStorage, IClientStorage clientStorage)
{
_logger = logger;
_messageInfoStorage = messageInfoStorage;
_clientStorage = clientStorage;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId: {MessageId}. ClientId: {ClientId}", model?.MessageId, model?.ClientId);
var list = model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public bool Create(MessageInfoBindingModel model)
{
CheckModel(model);
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(MessageInfoBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.MessageId))
{
throw new ArgumentNullException("Не указан id сообщения", nameof(model.MessageId));
}
if (string.IsNullOrEmpty(model.SenderName))
{
throw new ArgumentNullException("Не указана почта отправителя", nameof(model.SenderName));
}
if (string.IsNullOrEmpty(model.Subject))
{
throw new ArgumentNullException("Не указан заголовок", nameof(model.Subject));
}
if (string.IsNullOrEmpty(model.Body))
{
throw new ArgumentNullException("Не указан текст сообщения", nameof(model.Subject));
}
_logger.LogInformation("MessageInfo. MessageId: {MessageId}. SenderName: {SenderName}. DateDelivery: {DateDelivery} Subject: {Subject}. Body: {Body}", model.MessageId, model.SenderName, model.DateDelivery, model.Subject, model.Body);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.SenderName
});
if (element == null)
{
_logger.LogWarning("Не удалось найти клиента, отправившего письмо с адреса Email: {Email}", model.SenderName);
}
else
{
model.ClientId = element.Id;
}
}
}
}

View File

@ -0,0 +1,175 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels;
using ConfectioneryDataModels.Enums;
using ConfectioneryBusinessLogic.MailWorker;
using Microsoft.Extensions.Logging;
using System.Xml.Linq;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
static readonly object locker = new();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Invalid order status");
return false;
}
model.Status = OrderStatus.Принят;
var element = _orderStorage.Insert(model);
if (element == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = element.ClientEmail,
Subject = $"Новый заказ создан. Номер заказа - {element.Id}",
Text = $"Заказ №{element.Id} от {element.DateCreate} на сумму {element.Sum} принят."
}));
return true;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. OrderId: {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 OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id: {Id}", model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (locker)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.PastryId <= 0)
{
throw new ArgumentNullException("Некорректный идентификатор выпечки", nameof(model.PastryId));
}
if (model.ClientId <= 0)
{
throw new ArgumentNullException("Некорректный идентификатор клиента", nameof(model.ClientId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("В заказе должно быть хотя бы одна выпечка", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Стоимость заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. Id: {Id}. Sum: {Sum}. PastryId: {PastryId}. PastryCount: {Count}", model.Id, model.Sum,
model.PastryId, model.Count);
}
private bool ChangeStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (order == null)
{
_logger.LogWarning("Change status operation failed. Order not found");
return false;
}
if (order.Status + 1 != newStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {newStatus}. Current status: {currStatus}",
newStatus, order.Status);
return false;
}
model.Status = newStatus;
if (order.ImplementerId.HasValue)
{
model.ImplementerId = order.ImplementerId;
}
if (model.Status == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
}
else
{
model.DateImplement = order.DateImplement;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Change status operation failed");
return false;
}
string DateInfo = model.DateImplement.HasValue ? $"Дата выполнения {model.DateImplement}" : "";
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = order.ClientEmail,
Subject = $"Заказ №{order.Id}",
Text = $"Заказ №{order.Id} изменен статус на {model.Status}. {DateInfo}"
}));
return true;
}
}
}

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class PastryLogic : IPastryLogic
{
private readonly ILogger _logger;
private readonly IPastryStorage _pastryStorage;
public PastryLogic(ILogger<PastryLogic> logger, IPastryStorage pastryStorage)
{
_logger = logger;
_pastryStorage = pastryStorage;
}
public List<PastryViewModel>? ReadList(PastrySearchModel? model)
{
_logger.LogInformation("ReadList. PastryName: {PastryName}. Id: {Id}", model?.PastryName, model?.Id);
var list = model == null ? _pastryStorage.GetFullList() : _pastryStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public PastryViewModel? ReadElement(PastrySearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. PastryName: {PastryName}. Id: {Id}", model.PastryName, model.Id);
var element = _pastryStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(PastryBindingModel model)
{
CheckModel(model);
if (_pastryStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(PastryBindingModel model)
{
CheckModel(model);
if (_pastryStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(PastryBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id: {Id}", model.Id);
if (_pastryStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(PastryBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.PastryName))
{
throw new ArgumentNullException("Нет названия выпечки", nameof(model.PastryName));
}
if (model.Price <= 0)
{
throw new ArgumentNullException("Цена выпечки должна быть больше 0", nameof(model.Price));
}
if (model.PastryComponents == null || model.PastryComponents.Count == 0)
{
throw new ArgumentNullException("Выпечка должна состоять хотя бы из одного компонента");
}
_logger.LogInformation("Pastry. PastryName: {PastryName}. Price: {Price}. Id: {Id}", model.PastryName, model.Price, model.Id);
var element = _pastryStorage.GetElement(new PastrySearchModel
{
PastryName = model.PastryName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Выпечка с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class ReportLogic : IReportLogic
{
private readonly IComponentStorage _componentStorage;
private readonly IPastryStorage _pastryStorage;
private readonly IOrderStorage _orderStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IPastryStorage pastryStorage, IComponentStorage
componentStorage, IOrderStorage orderStorage,
AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord,
AbstractSaveToPdf saveToPdf)
{
_pastryStorage = pastryStorage;
_componentStorage = componentStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
/// <summary>
/// Получение списка компонент с указанием, в каких изделиях используются
/// </summary>
/// <returns></returns>
public List<ReportPastryComponentViewModel> GetPastryComponent()
{
var pastries = _pastryStorage.GetFullList();
var list = new List<ReportPastryComponentViewModel>();
foreach (var pastry in pastries)
{
var record = new ReportPastryComponentViewModel
{
PastryName = pastry.PastryName,
Components = new List<(string Component, int Count)>(),
TotalCount = 0,
};
foreach (var component in pastry.PastryComponents)
{
record.Components.Add(new(component.Value.Item1.ComponentName, component.Value.Item2));
record.TotalCount += component.Value.Item2;
}
list.Add(record);
}
return list;
}
/// <summary>
/// Получение списка заказов за определенный период
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel
{
DateFrom = model.DateFrom,
DateTo = model.DateTo
})
.Select(x => new ReportOrdersViewModel
{
Id = x.Id,
DateCreate = x.DateCreate,
PastryName = x.PastryName,
OrderStatus = x.Status.ToString(),
Sum = x.Sum
})
.ToList();
}
/// <summary>
/// Сохранение компонент в файл-Word
/// </summary>
/// <param name="model"></param>
public void SavePastriesToWordFile(ReportBindingModel model)
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список выпечки",
Pastries = _pastryStorage.GetFullList()
});
}
/// <summary>
/// Сохранение компонент с указаеним продуктов в файл-Excel
/// </summary>
/// <param name="model"></param>
public void SavePastryComponentToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список выпечки ",
PastryComponents = GetPastryComponent()
});
}
/// <summary>
/// Сохранение заказов в файл-Pdf
/// </summary>
/// <param name="model"></param>
public void SaveOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список заказов",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Orders = GetOrders(model)
});
}
}
}

View File

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryDataModels.Enums;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Исполнитель равен null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
/// <summary>
/// Иммитация работы исполнителя
/// </summary>
/// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order} ", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order} ", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id,
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Выполняется
}));
if (runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.6.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConfectionaryContracts\ConfectioneryContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,91 @@
using ConfectioneryBusinessLogic.BusinessLogics;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.MailWorker
{
public abstract class AbstractMailWorker
{
protected string _mailLogin = string.Empty;
protected string _mailPassword = string.Empty;
protected string _smtpClientHost = string.Empty;
protected int _smtpClientPort;
protected string _popHost = string.Empty;
protected int _popPort;
private readonly IMessageInfoLogic _messageInfoLogic;
private readonly ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
}
public void MailConfig(MailConfigBindingModel config)
{
_mailLogin = config.MailLogin;
_mailPassword = config.MailPassword;
_smtpClientHost = config.SmtpClientHost;
_smtpClientPort = config.SmtpClientPort;
_popHost = config.PopHost;
_popPort = config.PopPort;
_logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
}
public async void MailSendAsync(MailSendInfoBindingModel info)
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0)
{
return;
}
if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text))
{
return;
}
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
await SendMailAsync(info);
}
public async void MailCheck()
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_popHost) || _popPort == 0)
{
return;
}
if (_messageInfoLogic == null)
{
return;
}
var list = await ReceiveMailAsync();
_logger.LogDebug("Check Mail: {Count} new mails", list.Count);
foreach (var mail in list)
{
_messageInfoLogic.Create(mail);
}
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@ -0,0 +1,78 @@
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using MailKit.Net.Pop3;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace ConfectioneryBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic) : base(logger, messageInfoLogic) { }
protected override async Task SendMailAsync(MailSendInfoBindingModel info)
{
using var objMailMessage = new MailMessage();
using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
objMailMessage.From = new MailAddress(_mailLogin);
objMailMessage.To.Add(new MailAddress(info.MailAddress));
objMailMessage.Subject = info.Subject;
objMailMessage.Body = info.Text;
objMailMessage.SubjectEncoding = Encoding.UTF8;
objMailMessage.BodyEncoding = Encoding.UTF8;
objSmtpClient.UseDefaultCredentials = false;
objSmtpClient.EnableSsl = true;
objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => objSmtpClient.Send(objMailMessage));
}
catch (Exception)
{
throw;
}
}
protected override async Task<List<MessageInfoBindingModel>> ReceiveMailAsync()
{
var list = new List<MessageInfoBindingModel>();
using var client = new Pop3Client();
await Task.Run(() =>
{
try
{
client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect);
client.Authenticate(_mailLogin, _mailPassword);
for (int i = 0; i < client.Count; i++)
{
var message = client.GetMessage(i);
foreach (var mail in message.From.Mailboxes)
{
list.Add(new MessageInfoBindingModel
{
DateDelivery = message.Date.DateTime,
MessageId = message.MessageId,
SenderName = mail.Address,
Subject = message.Subject,
Body = message.TextBody
});
}
}
}
catch (AuthenticationException)
{ }
finally
{
client.Disconnect(true);
}
});
return list;
}
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
namespace ConfectioneryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
/// <summary>
/// Создание отчета
/// </summary>
/// <param name="info"></param>
public void CreateReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var pc in info.PastryComponents)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = pc.PastryName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var pastry in pc.Components)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = pastry.Item1,
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = pastry.Item2.ToString(),
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = pc.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info);
/// <summary>
/// Добавляем новую ячейку в лист
/// </summary>
/// <param name="cellParameters"></param>
protected abstract void InsertCellInWorksheet(ExcelCellParameters
excelParams);
/// <summary>
/// Объединение ячеек
/// </summary>
/// <param name="mergeParameters"></param>
protected abstract void MergeCells(ExcelMergeParameters excelParams);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@ -0,0 +1,82 @@
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style =
"NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"с { info.DateFrom.ToShortDateString() } по { info.DateTo.ToShortDateString() }", Style
= "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "2cm", "3cm", "6cm", "4cm", "3cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Номер", "Дата заказа", "Выпечка", "Статус", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var order in info.Orders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.PastryName,
order.OrderStatus, order.Sum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Rigth
});
SavePdf(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfo info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SavePdf(PdfInfo info);
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
namespace ConfectioneryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateDoc(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var pastry in info.Pastries)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {(pastry.PastryName + " - ", new WordTextProperties { Size = "24", Bold = true}),
(pastry.Price.ToString(), new WordTextProperties { Size = "24", })},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfo info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveWord(WordInfo info);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelCellParameters
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportPastryComponentViewModel> PastryComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryContracts.ViewModels;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportOrdersViewModel> Orders { get; set; } = new();
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using ConfectioneryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<PastryViewModel> Pastries { get; set; } = new();
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
namespace ConfectioneryBusinessLogic.OfficePackage.HelperModels
{
public class WordTextProperties
{
public string Size { get; set; } = string.Empty;
public bool Bold { get; set; }
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,356 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Office2016.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace ConfectioneryBusinessLogic.OfficePackage.Implements
{
public class SaveToExcel : AbstractSaveToExcel
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
/// <summary>
/// Настройка стилей для файла
/// </summary>
/// <param name="workbookpart"></param>
private static void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontUsual.Append(new FontName() { Val = "Times New Roman" });
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 14D });
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontTitle.Append(new FontName() { Val = "Times New Roman" });
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
fonts.Append(fontUsual);
fonts.Append(fontTitle);
var fills = new Fills() { Count = 2U };
var fill1 = new Fill();
fill1.Append(new PatternFill() { PatternType = PatternValues.None });
var fill2 = new Fill();
fill2.Append(new PatternFill()
{
PatternType = PatternValues.Gray125
});
fills.Append(fill1);
fills.Append(fill2);
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var rightBorder = new RightBorder()
{
Style = BorderStyleValues.Thin
};
rightBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var bottomBorder = new BottomBorder()
{
Style =
BorderStyleValues.Thin
};
bottomBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
var cellFormatStyle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 0U,
FillId = 0U,
BorderId = 0U
};
cellStyleFormats.Append(cellFormatStyle);
var cellFormats = new CellFormats() { Count = 3U };
var cellFormatFont = new CellFormat()
{
NumberFormatId = 0U,
FontId =
0U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
ApplyFont = true
};
var cellFormatFontAndBorder = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 1U,
FormatId = 0U,
ApplyFont = true,
ApplyBorder = true
};
var cellFormatTitle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 1U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
Alignment = new Alignment()
{
Vertical = VerticalAlignmentValues.Center,
WrapText = true,
Horizontal =
HorizontalAlignmentValues.Center
},
ApplyFont = true
};
cellFormats.Append(cellFormatFont);
cellFormats.Append(cellFormatFontAndBorder);
cellFormats.Append(cellFormatTitle);
var cellStyles = new CellStyles() { Count = 1U };
cellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0U,
BuiltinId = 0U
});
var differentialFormats = new
DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats()
{ Count = 0U };
var tableStyles = new TableStyles()
{
Count = 0U,
DefaultTableStyle =
"TableStyleMedium2",
DefaultPivotStyle = "PivotStyleLight16"
};
var stylesheetExtensionList = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension()
{
Uri =
"{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"
};
stylesheetExtension1.AddNamespaceDeclaration("x14",
"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
stylesheetExtension1.Append(new SlicerStyles()
{
DefaultSlicerStyle =
"SlicerStyleLight1"
});
var stylesheetExtension2 = new StylesheetExtension()
{
Uri =
"{9260A510-F301-46a8-8635-F512D64BE5F5}"
};
stylesheetExtension2.AddNamespaceDeclaration("x15",
"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
stylesheetExtension2.Append(new TimelineStyles()
{
DefaultTimelineStyle = "TimeSlicerStyleLight1"
});
stylesheetExtensionList.Append(stylesheetExtension1);
stylesheetExtensionList.Append(stylesheetExtension2);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellStyleFormats);
sp.Stylesheet.Append(cellFormats);
sp.Stylesheet.Append(cellStyles);
sp.Stylesheet.Append(differentialFormats);
sp.Stylesheet.Append(tableStyles);
sp.Stylesheet.Append(stylesheetExtensionList);
}
/// <summary>
/// Получение номера стиля из типа
/// </summary>
/// <param name="styleInfo"></param>
/// <returns></returns>
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBroder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfo info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName,
SpreadsheetDocumentType.Workbook);
// Создаем книгу (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
// Получаем/создаем хранилище текстов для книги
_shareStringPart =
_spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
?
_spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
:
_spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
// Создаем SharedStringTable, если его нет
if (_shareStringPart.SharedStringTable == null)
{
_shareStringPart.SharedStringTable = new SharedStringTable();
}
// Создаем лист в книгу
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Добавляем лист в книгу
var sheets =
_spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id =
_spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
_worksheet = worksheetPart.Worksheet;
}
protected override void InsertCellInWorksheet(ExcelCellParameters
excelParams)
{
if (_worksheet == null || _shareStringPart == null)
{
return;
}
var sheetData = _worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
// Ищем строку, либо добавляем ее
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex! ==
excelParams.RowIndex).Any())
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex! ==
excelParams.RowIndex).First();
}
else
{
row = new Row() { RowIndex = excelParams.RowIndex };
sheetData.Append(row);
}
// Ищем нужную ячейку
Cell cell;
if (row.Elements<Cell>().Where(c => c.CellReference!.Value ==
excelParams.CellReference).Any())
{
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value ==
excelParams.CellReference).First();
}
else
{
// Все ячейки должны быть последовательно друг за другом расположены
// нужно определить, после какой вставлять
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value,
excelParams.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell()
{
CellReference =
excelParams.CellReference
};
row.InsertBefore(newCell, refCell);
cell = newCell;
}
// вставляем новый текст
_shareStringPart.SharedStringTable.AppendChild(new
SharedStringItem(new Text(excelParams.Text)));
_shareStringPart.SharedStringTable.Save();
cell.CellValue = new
CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count(
) - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
}
protected override void MergeCells(ExcelMergeParameters excelParams)
{
if (_worksheet == null)
{
return;
}
MergeCells mergeCells;
if (_worksheet.Elements<MergeCells>().Any())
{
mergeCells = _worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (_worksheet.Elements<CustomSheetView>().Any())
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<CustomSheetView>().First());
}
else
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
protected override void SaveExcel(ExcelInfo info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Dispose();
}
}
}

View File

@ -0,0 +1,106 @@
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConfectioneryBusinessLogic.OfficePackage.Implements
{
public class SaveToPdf : AbstractSaveToPdf
{
private Document? _document;
private Section? _section;
private Table? _table;
private static ParagraphAlignment
GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Rigth => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
/// <summary>
/// Создание стилей для документа
/// </summary>
/// <param name="document"></param>
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfo info)
{
_document = new Document();
DefineStyles(_document);
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment =
GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment =
GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfo info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -0,0 +1,124 @@
using ConfectioneryBusinessLogic.OfficePackage.HelperEnums;
using ConfectioneryBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace ConfectioneryBusinessLogic.OfficePackage.Implements
{
public class SaveToWord : AbstractSaveToWord
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
/// <summary>
/// Получение типа выравнивания
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static JustificationValues
GetJustificationValues(WordJustificationType type)
{
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
/// <summary>
/// Настройки страницы
/// </summary>
/// <returns></returns>
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
/// <summary>
/// Задание форматирования для абзаца
/// </summary>
/// <param name="paragraphProperties"></param>
/// <returns></returns>
private static ParagraphProperties?
CreateParagraphProperties(WordTextProperties? paragraphProperties)
{
if (paragraphProperties == null)
{
return null;
}
var properties = new ParagraphProperties();
properties.AppendChild(new Justification()
{
Val = GetJustificationValues(paragraphProperties.JustificationType)
});
properties.AppendChild(new SpacingBetweenLines
{
LineRule = LineSpacingRuleValues.Auto
});
properties.AppendChild(new Indentation());
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (!string.IsNullOrEmpty(paragraphProperties.Size))
{
paragraphMarkRunProperties.AppendChild(new FontSize
{
Val =
paragraphProperties.Size
});
}
properties.AppendChild(paragraphMarkRunProperties);
return properties;
}
protected override void CreateWord(WordInfo info)
{
_wordDocument = WordprocessingDocument.Create(info.FileName,
WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
_docBody = mainPart.Document.AppendChild(new Body());
}
protected override void CreateParagraph(WordParagraph paragraph)
{
if (_docBody == null || paragraph == null)
{
return;
}
var docParagraph = new Paragraph();
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
foreach (var run in paragraph.Texts)
{
var docRun = new Run();
var properties = new RunProperties();
properties.AppendChild(new FontSize { Val = run.Item2.Size });
if (run.Item2.Bold)
{
properties.AppendChild(new Bold());
}
docRun.AppendChild(properties);
docRun.AppendChild(new Text
{
Text = run.Item1,
Space = SpaceProcessingModeValues.Preserve
});
docParagraph.AppendChild(docRun);
}
_docBody.AppendChild(docParagraph);
}
protected override void SaveWord(WordInfo info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Dispose();
}
}
}

View File

@ -0,0 +1,49 @@
using ConfectioneryContracts.ViewModels;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
namespace ConfectioneryClientApp
{
public class APIClient
{
private static readonly HttpClient _client = new();
public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration configuration)
{
_client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public static T? GetRequest<T>(string requestUrl)
{
var response = _client.GetAsync(requestUrl);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (response.Result.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(result);
}
else
{
throw new Exception(result);
}
}
public static void PostRequest<T>(string requestUrl, T model)
{
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var response = _client.PostAsync(requestUrl, data);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (!response.Result.IsSuccessStatusCode)
{
throw new Exception(result);
}
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConfectioneryBusinessLogic\ConfectioneryBusinessLogic.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,155 @@
using ConfectioneryClientApp.Models;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace ConfectioneryClientApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return
View(APIClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={APIClient.Client.Id}"));
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.Client);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/updatedata", new ClientBindingModel
{
Id = APIClient.Client.Id,
ClientFIO = fio,
Email = login,
Password = password
});
APIClient.Client.ClientFIO = fio;
APIClient.Client.Email = login;
APIClient.Client.Password = password;
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel
{
RequestId =
Activity.Current?.Id ?? HttpContext.TraceIdentifier
});
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
APIClient.Client =
APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/register", new
ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Pastries =
APIClient.GetRequest<List<PastryViewModel>>("api/main/getpastrylist");
return View();
}
[HttpPost]
public void Create(int pastry, int count)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (count <= 0)
{
throw new Exception("Количество и сумма должны быть больше 0");
}
APIClient.PostRequest("api/main/createorder", new
OrderBindingModel
{
ClientId = APIClient.Client.Id,
PastryId = pastry,
Count = count,
Sum = Calc(count, pastry)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int pastry)
{
var prod =
APIClient.GetRequest<PastryViewModel>($"api/main/getpastry?pastryId={pastry}"
);
return count * (prod?.Price ?? 1);
}
[HttpGet]
public IActionResult Mails()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}"));
}
}
}

View File

@ -0,0 +1,9 @@
namespace ConfectioneryClientApp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,22 @@
using ConfectioneryClientApp;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
APIClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59403",
"sslPort": 44389
}
},
"profiles": {
"ConfectioneryClientApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7271;http://localhost:5271",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,50 @@
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Выпечка:</div>
<div class="col-8">
<select id="pastry" name="pastry" class="form-control" asp-items="@(new SelectList(@ViewBag.Pastries,"Id", "PastryName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8"><input type="text" name="count" id="count" /></div>
</div>
<div class="row">
<div class="col-4">Сумма:</div>
<div class="col-8"><input type="text" id="sum" name="sum" readonly /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
</div>
</form>
<script>
$('#pastry').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var pastry = $('#pastry').val();
if (count && pastry) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, pastry: pastry },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@ -0,0 +1,20 @@
@{
ViewData["Title"] = "Enter";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btnprimary" /></div>
</div>
</form>

View File

@ -0,0 +1,75 @@
@using ConfectioneryContracts.ViewModels
@model List<OrderViewModel>
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Create">Создать заказ</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Выпечка
</th>
<th>
Дата создания
</th>
<th>
Количество
</th>
<th>
Сумма
</th>
<th>
Статус
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem =>
item.Id)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.PastryName)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.DateCreate)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Count)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Sum)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Status)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,54 @@
@using ConfectioneryContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.DateDelivery)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
}
</div>

Some files were not shown because too many files have changed in this diff Show More