3 Commits

Author SHA1 Message Date
Danil Kargin
b3e3a27133 Правки 2023-06-14 03:28:05 +04:00
Danil Kargin
5e4c544d14 Восьмая лаба 2023-06-14 03:20:46 +04:00
Danil Kargin
b9943b1dd9 Mails 2023-06-14 00:07:09 +04:00
87 changed files with 2825 additions and 310 deletions

2
.gitignore vendored
View File

@@ -14,6 +14,8 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
ImplementationExtensions
# Mono auto generated files
mono_crash.*

View File

@@ -0,0 +1,128 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.StoragesContracts;
using DinerDataModels;
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 DinerBusinessLogic.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(BackUpSaveBinidngModel 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)
{
//проверка на то, является ли тип интерфейсом и унаследован ли он от IId
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;
}
//три строчки ниже - сериализация файлов в json
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

@@ -4,6 +4,7 @@ using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace DinerBusinessLogic.BusinessLogics
{
@@ -103,7 +104,17 @@ namespace DinerBusinessLogic.BusinessLogics
throw new ArgumentNullException("Отсутствие пароля в учётной записи", nameof(model.Password));
}
_logger.LogInformation("WorkPiece. ClientFIO:{ClientFIO}. Email:{Email}. Password:{Password}. Id:{Id}",
if (!Regex.IsMatch(model.Email, @"^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$", RegexOptions.IgnoreCase))
{
throw new ArgumentException("Некорректная почта", nameof(model.Email));
}
if (!Regex.IsMatch(model.Password, @"^((\w+\d+\W+)|(\w+\W+\d+)|(\d+\w+\W+)|(\d+\W+\w+)|(\W+\w+\d+)|(\W+\d+\w+))[\w\d\W]*$", RegexOptions.IgnoreCase) && model.Password.Length < 10 && model.Password.Length > 50)
{
throw new ArgumentException("Необходимо придумать другой пароль", nameof(model.Password));
}
_logger.LogInformation("WorkPiece. ClientFIO:{ClientFIO}. Email:{Email}. Password:{Password}. Id:{Id}",
model.ClientFIO, model.Email, model.Password, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel
{

View File

@@ -0,0 +1,56 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerBusinessLogic.BusinessLogics
{
public class MessageInfoLogic : IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage messageInfoStorage)
{
_logger = logger;
_messageInfoStorage = messageInfoStorage;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId:{MessageId}", model?.MessageId);
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.OrderByDescending(x => x.DateDelivery).ToList();
}
public bool Create(MessageInfoBindingModel model)
{
if (_messageInfoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
}
}

View File

@@ -1,4 +1,5 @@
using DinerContracts.BindingModels;
using DinerBusinessLogic.MailWorker;
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
@@ -12,11 +13,15 @@ namespace DinerBusinessLogic.BusinessLogics
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
private readonly AbstractMailWorker _mailWorker;
private readonly IClientLogic _clientLogic;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic)
{
_logger = logger;
_orderStorage = orderStorage;
}
_mailWorker = mailWorker;
_clientLogic = clientLogic;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
@@ -57,12 +62,14 @@ namespace DinerBusinessLogic.BusinessLogics
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
var result = _orderStorage.Insert(model);
if (result == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
SendOrderMessage(result.ClientId, $"Закусочная, Заказ №{result.Id}", $"Заказ №{result.Id} от {result.DateCreate} на сумму {result.Sum:0.00} принят");
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
@@ -144,8 +151,8 @@ namespace DinerBusinessLogic.BusinessLogics
}
CheckModel(model, false);
if (_orderStorage.Update(model) == null)
var result = _orderStorage.Update(model);
if (result == null)
{
model.Status--;
@@ -153,6 +160,24 @@ namespace DinerBusinessLogic.BusinessLogics
return false;
}
SendOrderMessage(result.ClientId, $"Закусочная, Заказ №{result.Id}", $"Заказ №{model.Id} изменен статус на {result.Status}");
return true;
}
private bool SendOrderMessage(int clientId, string subject, string text)
{
var client = _clientLogic.ReadElement(new() { Id = clientId });
if (client == null)
{
return false;
}
_mailWorker.MailSendAsync(new()
{
MailAddress = client.Email,
Subject = subject,
Text = text
});
return true;
}

View File

@@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>

View File

@@ -0,0 +1,107 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerBusinessLogic.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 IClientLogic _clientLogic;
private readonly ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
_clientLogic = clientLogic;
}
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)
{
mail.ClientId = _clientLogic.ReadElement(new() { Email = mail.SenderName })?.Id;
_messageInfoLogic.Create(mail);
}
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@@ -0,0 +1,87 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System.Net.Mail;
using System.Net;
using System.Text;
using MailKit.Net.Pop3;
using MailKit.Security;
namespace DinerBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic, IClientLogic clientLogic)
: base(logger, messageInfoLogic, clientLogic) { }
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,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.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 DinerContracts.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 DinerContracts.BindingModels
{
public class BackUpSaveBinidngModel
{
public string FolderName { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels
{
public class MailConfigBindingModel
{
public int Id { get; set; }
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,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.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,24 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BindingModels
{
public class MessageInfoBindingModel : IMessageInfoModel
{
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
public string SenderName { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; } = DateTime.Now;
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.BusinessLogicsContracts
{
public interface IMessageInfoLogic
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model);
}
}

View File

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

View File

@@ -0,0 +1,25 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.DI
{
public interface IDependencyContainer
{
//Регистрация логгера
void AddLogging(Action<ILoggingBuilder> configure);
//Добавление зависимости
void RegisterType<T, U>(bool isSingle) where U : class, T where T :
class;
//Добавление зависимости
void RegisterType<T>(bool isSingle) where T : class;
//Получение класса со всеми зависмостями
T 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 DinerContracts.DI
{
public interface IImplementationExtension
{
public int Priority { get; }
//Регистрация сервисов
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 DinerContracts.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,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.DI
{
public static partial class ServiceProviderLoader
{
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,43 @@
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 DinerContracts.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>(bool isSingle) where T : class
{
_container.RegisterType<T>(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
void IDependencyContainer.RegisterType<T, U>(bool isSingle)
{
_container.RegisterType<T, U>(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient);
}
}
}

View File

@@ -6,6 +6,12 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AbstractShopDataModels\DinerDataModels.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.SearchModels
{
public class MessageInfoSearchModel
{
public string? MessageId { get; set; }
public int? ClientId { 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 DinerContracts.StoragesContracts
{
public interface IBackUpInfo
{
List<T>? GetList<T>() where T : class, new();
Type? GetTypeByModelInterface(string modelInterfaceName);
}
}

View File

@@ -0,0 +1,22 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerContracts.StoragesContracts
{
public interface IMessageInfoStorage
{
List<MessageInfoViewModel> GetFullList();
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
}
}

View File

@@ -1,21 +1,17 @@
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DinerContracts.Attributes;
using DinerDataModels.Models;
namespace DinerContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
public int Id { get; set; }
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Логин (эл. почта)")]
public string Email { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[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

@@ -1,14 +1,16 @@
using System.ComponentModel;
using DinerContracts.Attributes;
using DinerDataModels.Models;
namespace DinerContracts.ViewModels
{
public class ComponentViewModel : IComponentModel
{
public int Id { get; set; }
[DisplayName("Название компонента")]
public string ComponentName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Cost { get; set; }
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "Название компонента", width: 150)]
public string ComponentName { get; set; } = string.Empty;
[Column(title: "Цена", width: 150)]
public double Cost { get; set; }
}
}

View File

@@ -1,22 +1,24 @@
using DinerDataModels.Models;
using DinerContracts.Attributes;
using DinerDataModels.Models;
using System.ComponentModel;
namespace DinerContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
{
[Column(visible: false)]
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
[Column(title: "ФИО исполнителя", width: 150)]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
[Column(title: "Пароль", width: 150)]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж")]
[Column(title: "Стаж", width: 150)]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
[Column(title: "Квалификация", width: 150)]
public int Qualification { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using DinerContracts.Attributes;
using System.ComponentModel;
namespace DinerContracts.ViewModels
{
public class MessageInfoViewModel
{
[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: 150)]
public DateTime DateDelivery { get; set; } = DateTime.Now;
[Column(title: "Заголовок", width: 150)]
public string Subject { get; set; } = string.Empty;
[Column(title: "Текст", width: 150)]
public string Body { get; set; } = string.Empty;
}
}

View File

@@ -1,31 +1,35 @@
using System.ComponentModel;
using DinerDataModels.Models;
using DinerDataModels.Enum;
using DinerContracts.Attributes;
namespace DinerContracts.ViewModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int ClientId { get; set; }
[Column(visible: false)]
public int Id { get; set; }
[Column(visible: false)]
public int ClientId { get; set; }
[Column(visible: false)]
public int? ImplementerId { get; set; }
[Column(visible: false)]
public int SnackId { get; set; }
[DisplayName("Изделие")]
public string SnackName { get; set; } = string.Empty;
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Исполнитель")]
[Column(title: "Изделие", width: 150)]
public string SnackName { get; set; } = string.Empty;
[Column(title: "ФИО клиента", width: 150)]
public string ClientFIO { get; set; } = string.Empty;
[Column(title: "ФИО исполнителя", width: 150)]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
[Column(title: "Количество", width: 150)]
public int Count { get; set; }
[Column(title: "Сумма", width: 150)]
public double Sum { get; set; }
[Column(title: "Статус", width: 150)]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[Column(title: "Дата создания", width: 150)]
public DateTime DateCreate { get; set; } = DateTime.Now;
[Column(title: "Дата выполнения", width: 150)]
public DateTime? DateImplement { get; set; }
}
}

View File

@@ -1,16 +1,19 @@
using DinerDataModels.Models;
using DinerContracts.Attributes;
using DinerDataModels.Models;
using System.ComponentModel;
namespace DinerContracts.ViewModels
{
public class SnackViewModel : ISnackModel
{
public int Id { get; set; }
[DisplayName("Название изделия")]
public string SnackName { get; set; } = string.Empty;
[DisplayName("Цена")]
public double Price { get; set; }
public Dictionary<int, (IComponentModel, int)> SnackComponents { get; set; } = new();
[Column(visible: false)]
public int Id { get; set; }
[Column(title: "Навание изделия", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string SnackName { get; set; } = string.Empty;
[Column(title: "Цена", width: 150)]
public double Price { get; set; }
[Column(visible: false)]
public Dictionary<int, (IComponentModel, int)> SnackComponents { get; set; } = new();
}
}

View File

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

View File

@@ -15,6 +15,7 @@ namespace DinerListImplement
public List<Snack> Products { get; set; }
public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
public List<MessageInfo> MessageInfos { get; set; }
private DataListSingleton()
{
Components = new List<Component>();
@@ -22,6 +23,7 @@ namespace DinerListImplement
Products = new List<Snack>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
MessageInfos = new List<MessageInfo>();
}
public static DataListSingleton GetInstance()
{

View File

@@ -10,5 +10,8 @@
<ProjectReference Include="..\..\AbstractShopContracts\DinerContracts.csproj" />
<ProjectReference Include="..\..\AbstractShopDataModels\DinerDataModels.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@@ -0,0 +1,37 @@
using DinerContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
var source = DataListSingleton.GetInstance();
return (List<T>?)source.GetType().GetProperties()
.FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == typeof(T))
?.GetValue(source);
}
public Type? GetTypeByModelInterface(string modelInterfaceName)
{
var assembly = typeof(BackUpInfo).Assembly;
var types = assembly.GetTypes();
foreach (var type in types)
{
if (type.IsClass && type.GetInterface(modelInterfaceName) != null)
{
return type;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,87 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
var result = new List<MessageInfoViewModel>();
foreach (var messageInfo in _source.MessageInfos)
{
result.Add(messageInfo.GetViewModel);
}
return result;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
var result = new List<MessageInfoViewModel>();
if (string.IsNullOrEmpty(model.MessageId))
{
return result;
}
foreach (var messageInfo in _source.MessageInfos)
{
if (messageInfo.ClientId == model.ClientId)
{
result.Add(messageInfo.GetViewModel);
}
}
return result;
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
foreach (var messageInfo in _source.MessageInfos)
{
if (messageInfo.MessageId == model.MessageId)
{
return messageInfo.GetViewModel;
}
}
return null;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
_source.MessageInfos.Add(newMessage);
return newMessage.GetViewModel;
}
}
}

View File

@@ -0,0 +1,33 @@
using DinerContracts.DI;
using DinerContracts.StoragesContracts;
using DinerListImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement
{
public class ListImplementationExtension : IImplementationExtension
{
public int Priority => 0;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<ISnackStorage, SnackStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,67 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace DinerListImplement.Models
{
public class MessageInfo : IMessageInfoModel
{
public string MessageId { get; private set; } = string.Empty;
public int? ClientId { get; private set; }
public string SenderName { get; private set; } = string.Empty;
public DateTime DateDelivery { get; private set; } = DateTime.Now;
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel? model)
{
if (model == null)
{
return null;
}
return new MessageInfo()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body
};
}
public void Update(MessageInfoBindingModel? model)
{
if (model == null)
{
return;
}
MessageId = model.MessageId;
ClientId = model.ClientId;
SenderName = model.SenderName;
DateDelivery = model.DateDelivery;
Subject = model.Subject;
Body = model.Body;
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

11
Diner/Diner/App.config Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SmtpClientHost" value="smtp.gmail.com" />
<add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" />
<add key="MailLogin" value="forlabwork07@gmail.com" />
<add key="MailPassword" value="sicr cmdz jpor ikva" />
</appSettings>
</configuration>

View File

@@ -0,0 +1,59 @@
using DinerContracts.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Diner
{
public static class DataGridViewExtension
{
public static void FillandConfigGrid<T>(this DataGridView grid, List<T>? data)
{
if (data == null)
{
return;
}
grid.DataSource = data;
var type = typeof(T);
var properties = type.GetProperties();
foreach (DataGridViewColumn column in grid.Columns)
{
var property = properties.FirstOrDefault(x => x.Name == column.Name);
if (property == null)
{
throw new InvalidOperationException($"В типе {type.Name} не найдено свойство с именем {column.Name}");
}
var attribute = property.GetCustomAttributes(typeof(ColumnAttribute), true)?.SingleOrDefault();
if (attribute == null)
{
throw new InvalidOperationException($"Не найден атрибут типа ColumnAttribute для свойства {property.Name}");
}
// ищем нужный нам атрибут
if (attribute is ColumnAttribute columnAttr)
{
column.HeaderText = columnAttr.Title;
column.Visible = columnAttr.Visible;
if (columnAttr.IsUseAutoSize)
{
column.AutoSizeMode = (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode),
columnAttr.GridViewAutoSize.ToString());
}
else
{
column.Width = columnAttr.Width;
}
}
}
}
}
}

View File

@@ -40,4 +40,10 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -36,15 +36,9 @@ namespace Diner
_logger.LogInformation("Загрузка клиентов");
try
{
var list = _clientLogic.ReadList(null);
dataGridView.FillandConfigGrid(_clientLogic.ReadList(null));
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Успешная загрузка клиентов");
_logger.LogInformation("Успешная загрузка клиентов");
}
catch (Exception ex)
{

View File

@@ -1,5 +1,6 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.DI;
using Microsoft.Extensions.Logging;
namespace Diner
@@ -22,14 +23,8 @@ namespace Diner
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка компонентов");
dataGridView.FillandConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка компонентов");
}
catch (Exception ex)
{
@@ -40,29 +35,23 @@ namespace Diner
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponent));
if (service is FormComponent form)
{
if (form.ShowDialog() == DialogResult.OK)
var form = DependencyManager.Instance.Resolve<FormComponent>();
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponent));
if (service is FormComponent form)
{
form.Id =
var form = DependencyManager.Instance.Resolve<FormComponent>();
form.Id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)

View File

@@ -1,5 +1,6 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.DI;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -36,14 +37,7 @@ namespace Diner
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
dataGridView.FillandConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка исполнителей");
}
@@ -57,9 +51,9 @@ namespace Diner
private void ButtonCreate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
var form = DependencyManager.Instance.Resolve<FormImplementer>();
if (service is FormImplementer form)
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ShowDialog() == DialogResult.OK)
{
@@ -72,17 +66,14 @@ namespace Diner
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementer));
var form = DependencyManager.Instance.Resolve<FormImplementer>();
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (service is FormImplementer form)
if (form.ShowDialog() == DialogResult.OK)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
LoadData();
}
}
}

64
Diner/Diner/FormMails.Designer.cs generated Normal file
View File

@@ -0,0 +1,64 @@
using System.Windows.Forms;
namespace Diner
{
partial class FormMails
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
//
// FormMails
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Name = "FormMails";
Text = "Письма";
Load += FormMails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

50
Diner/Diner/FormMails.cs Normal file
View File

@@ -0,0 +1,50 @@
using DinerContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Diner
{
public partial class FormMails : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _messageLogic;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic messageLogic)
{
InitializeComponent();
_logger = logger;
_messageLogic = messageLogic;
}
private void FormMails_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
_logger.LogInformation("Загрузка писем");
try
{
dataGridView.FillandConfigGrid(_messageLogic.ReadList(null));
_logger.LogInformation("Успешная загрузка писем");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

120
Diner/Diner/FormMails.resx Normal file
View File

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

View File

@@ -43,8 +43,10 @@
listComponentsToolStripMenuItem = new ToolStripMenuItem();
componentSnacksToolStripMenuItem = new ToolStripMenuItem();
ordersToolStripMenuItem = new ToolStripMenuItem();
workWithClientsToolStripMenuItem = new ToolStripMenuItem();
toolStripDropDownButton1 = new ToolStripDropDownButton();
toolStripDropDownButtonMails = new ToolStripDropDownButton();
toolStripDropDownButtonBackup = new ToolStripDropDownButton();
workWithClientsToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
toolStrip.SuspendLayout();
SuspendLayout();
@@ -93,7 +95,7 @@
// toolStrip
//
toolStrip.ImageScalingSize = new Size(20, 20);
toolStrip.Items.AddRange(new ToolStripItem[] { manualsToolStripLabel, manualsStripDropDownButton, toolStripDropDownButton1 });
toolStrip.Items.AddRange(new ToolStripItem[] { manualsToolStripLabel, manualsStripDropDownButton, toolStripDropDownButton1, toolStripDropDownButtonMails, toolStripDropDownButtonBackup });
toolStrip.Location = new Point(0, 0);
toolStrip.Name = "toolStrip";
toolStrip.Size = new Size(1280, 27);
@@ -163,21 +165,38 @@
ordersToolStripMenuItem.Text = "Список заказов";
ordersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
//
// workWithClientsToolStripMenuItem
//
workWithClientsToolStripMenuItem.Name = "workWithClientsToolStripMenuItem";
workWithClientsToolStripMenuItem.Size = new Size(32, 19);
//
// toolStripDropDownButton1
//
toolStripDropDownButton1.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButton1.Image = (Image)resources.GetObject("toolStripDropDownButton1.Image");
toolStripDropDownButton1.ImageTransparentColor = Color.Magenta;
toolStripDropDownButton1.Name = "toolStripDropDownButton1";
toolStripDropDownButton1.Size = new Size(114, 24);
toolStripDropDownButton1.Text = "Запуск работ";
toolStripDropDownButton1.Click += WorkProcessToolStripDropDownButton1_Click;
//
// toolStripDropDownButtonMails
//
toolStripDropDownButtonMails.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButtonMails.ImageTransparentColor = Color.Magenta;
toolStripDropDownButtonMails.Name = "toolStripDropDownButtonMails";
toolStripDropDownButtonMails.Size = new Size(114, 24);
toolStripDropDownButtonMails.Text = "Письма";
toolStripDropDownButtonMails.Click += WorkProcessToolStripDropDownButtonMails_Click;
//
// toolStripDropDownButtonBackup
//
toolStripDropDownButtonBackup.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButtonBackup.ImageTransparentColor = Color.Magenta;
toolStripDropDownButtonBackup.Name = "toolStripDropDownButtonBackup";
toolStripDropDownButtonBackup.Size = new Size(114, 24);
toolStripDropDownButtonBackup.Text = "Создать бэкап";
toolStripDropDownButtonBackup.Click += WorkProcessToolStripDropDownButtonBackup_Click;
//
// workWithClientsToolStripMenuItem
//
workWithClientsToolStripMenuItem.Name = "workWithClientsToolStripMenuItem";
workWithClientsToolStripMenuItem.Size = new Size(32, 19);
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
@@ -216,5 +235,7 @@
private ToolStripMenuItem clientsToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripDropDownButton toolStripDropDownButton1;
private ToolStripDropDownButton toolStripDropDownButtonMails;
private ToolStripDropDownButton toolStripDropDownButtonBackup;
}
}

View File

@@ -1,5 +1,6 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.DI;
using DinerDataModels.Enum;
using Microsoft.Extensions.Logging;
@@ -13,13 +14,15 @@ namespace Diner
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
private readonly IBackUpLogic _backUpLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
_backUpLogic = backUpLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
@@ -27,20 +30,9 @@ namespace Diner
}
private void LoadData()
{
// прописать логику
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["SnackId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["SnackName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
dataGridView.FillandConfigGrid(_orderLogic.ReadList(null));
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
@@ -51,31 +43,22 @@ namespace Diner
}
private void ComponentToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
var form = DependencyManager.Instance.Resolve<FormComponents>();
form.ShowDialog();
}
private void ProductToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnacks));
if (service is FormSnacks form)
{
form.ShowDialog();
}
var form = DependencyManager.Instance.Resolve<FormSnacks>();
form.ShowDialog();
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
var form = DependencyManager.Instance.Resolve<FormCreateOrder>();
form.ShowDialog();
LoadData();
}
}
private void ButtonIssuedOrder_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
@@ -118,46 +101,60 @@ namespace Diner
private void ComponentSnacksToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportSnackComponents));
if (service is FormReportSnackComponents form)
{
form.ShowDialog();
}
var form = DependencyManager.Instance.Resolve<FormReportSnackComponents>();
form.ShowDialog();
}
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
var form = DependencyManager.Instance.Resolve<FormReportOrders>();
form.ShowDialog();
}
private void ClientsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
var form = DependencyManager.Instance.Resolve<FormClients>();
form.ShowDialog();
}
private void ImplementersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
var form = DependencyManager.Instance.Resolve<FormImplementers>();
form.ShowDialog();
}
}
private void WorkProcessToolStripDropDownButton1_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
_workProcess.DoWork(DependencyManager.Instance.Resolve<IImplementerLogic>()!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void WorkProcessToolStripDropDownButtonMails_Click(object sender, EventArgs e)
{
var form = DependencyManager.Instance.Resolve<FormMails>();
form.ShowDialog();
}
private void WorkProcessToolStripDropDownButtonBackup_Click(object sender, EventArgs e)
{
try
{
if (_backUpLogic != null)
{
var fbd = new FolderBrowserDialog(); if (fbd.ShowDialog() == DialogResult.OK)
{
_backUpLogic.CreateBackUp(new BackUpSaveBinidngModel
{
FolderName = fbd.SelectedPath
});
MessageBox.Show("Бекап создан", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@@ -64,12 +64,12 @@
<data name="toolStripDropDownButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAEISURBVEhL3ZErDsJAGIR7DlA47oArV8CDR9RiSDAQPBcA
Qx1BgUMQBEk1ooJAKE0I4Wlqf5gmu1n6oqW7hiZfthkx33aqeZ5HKvEFpmmSYRhSQScXINB1XSroDAke
96cUpAmupyPZsx7Z8x4drAnPpQmsgU7LdoHDJNIEYjnAlyBXJ3jPhVyaYLca8nLMhX+CPJXAOT+ouTj5
p5in4asApdWpS8XRwT+zShIFG/fOyxlZJbGC9f5G5bHzUf6LJFJQqTViyxlxEmRiHhLUW10qDbeRpUGC
ErwjE/OQoG9dIsviYGWsXMwxc24BYLcO5pgZc+cWJIG5MbsyAUDnHwlUAkFHJZraR9NeMVq3zi+WF/0A
AAAASUVORK5CYII=
YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAEKSURBVEhL3ZG9DsFQHMXvczDZvIOtXsHObuhqkViI3Quw
6CYmNoMYJJ0NBiFFIoIytOuf0+TeXP3yde+iyS+3OcP53Z4y3/dJJ4HAsiwyTVMp6BQCBIZhKAWdEcHV
vSlBmeB82NFy1KLluEWOPRC5MoHdMWhazwi4RJlALgf4EuT6BI+5kCsTrGddUY658E+QvyXYHq9UnRyC
U87f4aUApcXhnrI9Jzg/laQKFntXlHM+lSQK5psL5fvbp/JvJLGCQqmSWM5JkiCT84igXGtSrruKLQ0T
luAdmZxHBG37FFuWBC/j5XKOmX8WAH7rcI6ZMffPgjQwN2bXJgDo/COBTpjneQ2dML0PY3cISreGe8HM
qgAAAABJRU5ErkJggg==
</value>
</data>
</root>

View File

@@ -1,5 +1,6 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.DI;
using DinerContracts.SearchModels;
using DinerDataModels.Models;
using Microsoft.Extensions.Logging;
@@ -70,10 +71,7 @@ namespace Diner
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormSnackComponent));
if (service is FormSnackComponent form)
{
var form = DependencyManager.Instance.Resolve<FormSnackComponent>();
if (form.ShowDialog() == DialogResult.OK)
{
if (form.ComponentModel == null)
@@ -92,17 +90,13 @@ namespace Diner
form.Count));
}
LoadData();
}
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormSnackComponent));
if (service is FormSnackComponent form)
{
var form = DependencyManager.Instance.Resolve<FormSnackComponent>();
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
@@ -117,7 +111,6 @@ namespace Diner
_productComponents[form.Id] = (form.ComponentModel, form.Count);
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)

View File

@@ -1,5 +1,6 @@
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.DI;
using Microsoft.Extensions.Logging;
namespace Diner
@@ -19,17 +20,8 @@ namespace Diner
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["SnackName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridView.Columns["SnackComponents"].Visible = false;
}
_logger.LogInformation("Загрузка компонентов");
dataGridView.FillandConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка компонентов");
}
catch (Exception ex)
@@ -41,31 +33,23 @@ namespace Diner
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnack));
if (service is FormSnack form)
{
if (form.ShowDialog() == DialogResult.OK)
var form = DependencyManager.Instance.Resolve<FormSnack>();
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormSnack));
if (service is FormSnack form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
var form = DependencyManager.Instance.Resolve<FormSnack>();
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)

View File

@@ -7,13 +7,14 @@ using NLog.Extensions.Logging;
using DinerBusinessLogic.BusinessLogics;
using DinerBusinessLogic.OfficePackage;
using DinerBusinessLogic.OfficePackage.Implements;
using DinerBusinessLogic.MailWorker;
using DinerContracts.BindingModels;
using DinerContracts.DI;
namespace Diner
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
@@ -24,47 +25,72 @@ namespace Diner
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
InitDependency();
try
{
var mailSender = DependencyManager.Instance.Resolve<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000);
}
catch (Exception ex)
{
var logger = DependencyManager.Instance.Resolve<ILogger>();
logger?.LogError(ex, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
Application.Run(DependencyManager.Instance.Resolve<FormMain>());
}
private static void InitDependency()
{
DependencyManager.InitDependency();
DependencyManager.Instance.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<ISnackStorage, SnackStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IComponentLogic, ComponentLogic>();
DependencyManager.Instance.RegisterType<IOrderLogic, OrderLogic>();
DependencyManager.Instance.RegisterType<ISnackLogic, SnackLogic>();
DependencyManager.Instance.RegisterType<IReportLogic, ReportLogic>();
DependencyManager.Instance.RegisterType<IClientLogic, ClientLogic>();
DependencyManager.Instance.RegisterType<IImplementerLogic, ImplementerLogic>();
DependencyManager.Instance.RegisterType<IMessageInfoLogic, MessageInfoLogic>();
DependencyManager.Instance.RegisterType<IBackUpLogic, BackUpLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<ISnackLogic, SnackLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
DependencyManager.Instance.RegisterType<AbstractSaveToExcel, SaveToExcel>();
DependencyManager.Instance.RegisterType<AbstractSaveToWord, SaveToWord>();
DependencyManager.Instance.RegisterType<AbstractSaveToPdf, SaveToPdf>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
DependencyManager.Instance.RegisterType<IWorkProcess, WorkModeling>();
DependencyManager.Instance.RegisterType<AbstractMailWorker, MailKitWorker>(true);
services.AddTransient<FormMain>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormSnack>();
services.AddTransient<FormSnackComponent>();
services.AddTransient<FormSnacks>();
services.AddTransient<FormReportSnackComponents>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormClients>();
services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>();
DependencyManager.Instance.RegisterType<FormMain>();
DependencyManager.Instance.RegisterType<FormComponent>();
DependencyManager.Instance.RegisterType<FormComponents>();
DependencyManager.Instance.RegisterType<FormCreateOrder>();
DependencyManager.Instance.RegisterType<FormSnack>();
DependencyManager.Instance.RegisterType<FormSnackComponent>();
DependencyManager.Instance.RegisterType<FormSnack>();
DependencyManager.Instance.RegisterType<FormReportSnackComponents>();
DependencyManager.Instance.RegisterType<FormReportOrders>();
DependencyManager.Instance.RegisterType<FormClients>();
DependencyManager.Instance.RegisterType<FormImplementer>();
DependencyManager.Instance.RegisterType<FormImplementers>();
DependencyManager.Instance.RegisterType<FormMails>();
}
}
private static void MailCheck(object obj) => DependencyManager.Instance.Resolve<AbstractMailWorker>()?.MailCheck();
}
}

View File

@@ -0,0 +1,33 @@
using DinerContracts.DI;
using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement
{
public class DataBaseImplementationExtension : IImplementationExtension
{
public int Priority => 2;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<ISnackStorage, SnackStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -19,5 +19,8 @@
<ProjectReference Include="..\..\AbstractShopContracts\DinerContracts.csproj" />
<ProjectReference Include="..\..\AbstractShopDataModels\DinerDataModels.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@@ -19,5 +19,6 @@ namespace DinerDataBaseImplement
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
}
public virtual DbSet<MessageInfo> Messages { set; get; }
}
}

View File

@@ -0,0 +1,35 @@
using DinerContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
using var context = new DinerDatabase();
return context.Set<T>().ToList();
}
public Type? GetTypeByModelInterface(string modelInterfaceName)
{
var assembly = typeof(BackUpInfo).Assembly;
var types = assembly.GetTypes();
foreach (var type in types)
{
if (type.IsClass && type.GetInterface(modelInterfaceName) != null)
{
return type;
}
}
return null;
}
}
}

View File

@@ -40,14 +40,21 @@ namespace DinerDataBaseImplement.Implements
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password))
if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password))
{
return context.Clients
.Include(x => x.Orders)
.FirstOrDefault(x => (x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
}
return new();
if (!string.IsNullOrEmpty(model.Email))
{
return context.Clients
.Include(x => x.Orders)
.FirstOrDefault(x => (x.Email == model.Email))
?.GetViewModel;
}
return new();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)

View File

@@ -0,0 +1,61 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Models;
namespace DinerDataBaseImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
using var context = new DinerDatabase();
return context.Messages
.FirstOrDefault(x => (x.MessageId == model.MessageId))
?.GetViewModel;
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
using var context = new DinerDatabase();
return context.Messages
.Where(x => x.ClientId.HasValue && x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFullList()
{
using var context = new DinerDatabase();
return context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
using var context = new DinerDatabase();
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
context.Messages.Add(newMessage);
context.SaveChanges();
return newMessage.GetViewModel;
}
}
}

View File

@@ -0,0 +1,298 @@
// <auto-generated />
using System;
using DinerDataBaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
[DbContext(typeof(DinerDatabase))]
[Migration("20230613190529_FourthMigration")]
partial class FourthMigration
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("SnackId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("SnackId");
b.ToTable("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("SnackName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Snacks");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("SnackId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("SnackId");
b.ToTable("SnackComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("MessageInfos")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany("Orders")
.HasForeignKey("SnackId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.SnackComponent", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Component", "Component")
.WithMany("SnackComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DinerDataBaseImplement.Models.Snack", "Snack")
.WithMany("Components")
.HasForeignKey("SnackId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Snack");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Navigation("MessageInfos");
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Component", b =>
{
b.Navigation("SnackComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Snack", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DinerDataBaseImplement.Migrations
{
/// <inheritdoc />
public partial class FourthMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("DELETE FROM [dbo].[Orders]");
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
MessageId = table.Column<string>(type: "nvarchar(450)", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: true),
SenderName = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateDelivery = table.Column<DateTime>(type: "datetime2", nullable: false),
Subject = table.Column<string>(type: "nvarchar(max)", nullable: false),
Body = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.MessageId);
table.ForeignKey(
name: "FK_Messages_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
}
}
}

View File

@@ -17,7 +17,7 @@ namespace DinerDataBaseImplement.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("ProductVersion", "7.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@@ -94,6 +94,36 @@ namespace DinerDataBaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@@ -183,6 +213,15 @@ namespace DinerDataBaseImplement.Migrations
b.ToTable("SnackComponents");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.MessageInfo", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
.WithMany("MessageInfos")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("DinerDataBaseImplement.Models.Order", b =>
{
b.HasOne("DinerDataBaseImplement.Models.Client", "Client")
@@ -229,6 +268,8 @@ namespace DinerDataBaseImplement.Migrations
modelBuilder.Entity("DinerDataBaseImplement.Models.Client", b =>
{
b.Navigation("MessageInfos");
b.Navigation("Orders");
});

View File

@@ -8,23 +8,31 @@ using System.Text;
using System.Threading.Tasks;
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using System.Runtime.Serialization;
namespace DinerDataBaseImplement.Models
{
public class Client : IClientModel
[DataContract]
public class Client : IClientModel
{
public int Id { get; set; }
[DataMember]
public int Id { get; set; }
[Required]
[DataMember]
public string ClientFIO { get; set; } = string.Empty;
[Required]
public string ClientFIO { get; set; } = string.Empty;
[DataMember]
public string Email { get; set; } = string.Empty;
[Required]
public string Email { get; set; } = string.Empty;
[DataMember]
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<MessageInfo> MessageInfos { get; set; } = new();
[Required]
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
public static Client? Create(ClientBindingModel model)

View File

@@ -3,16 +3,21 @@ using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace DinerDataBaseImplement.Models
{
public class Component : IComponentModel
[DataContract]
public class Component : IComponentModel
{
public int Id { get; private set; }
[DataMember]
public int Id { get; private set; }
[Required]
public string ComponentName { get; private set; } = string.Empty;
[DataMember]
public string ComponentName { get; private set; } = string.Empty;
[Required]
public double Cost { get; set; }
[DataMember]
public double Cost { get; set; }
[ForeignKey("ComponentId")]
public virtual List<SnackComponent> SnackComponents { get; set; } = new();
public static Component? Create(ComponentBindingModel model)

View File

@@ -8,23 +8,30 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace DinerDataBaseImplement.Models
{
[DataContract]
public class Implementer : IImplementerModel
{
[DataMember]
public int Id { get; set; }
[Required]
[DataMember]
public string ImplementerFIO { get; set; } = string.Empty;
[Required]
[DataMember]
public string Password { get; set; } = string.Empty;
[Required]
[DataMember]
public int WorkExperience { get; set; }
[Required]
[DataMember]
public int Qualification { get; set; }
[ForeignKey("ImplementerId")]

View File

@@ -0,0 +1,66 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Models
{
[DataContract]
public class MessageInfo : IMessageInfoModel
{
[Key]
[DataMember]
public string MessageId { get; set; } = string.Empty;
[DataMember]
[Required]
public int? ClientId { get; set; }
[DataMember]
[Required]
public string SenderName { get; set; } = string.Empty;
[DataMember]
[Required]
public DateTime DateDelivery { get; set; } = DateTime.Now;
[DataMember]
[Required]
public string Subject { get; set; } = string.Empty;
[DataMember]
[Required]
public string Body { get; set; } = string.Empty;
public virtual Client? Client { get; set; }
public static MessageInfo? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new MessageInfo()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
Body = model.Body,
DateDelivery = model.DateDelivery,
Subject = model.Subject
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
Body = Body,
DateDelivery = DateDelivery,
Subject = Subject
};
}
}

View File

@@ -4,28 +4,38 @@ using DinerContracts.ViewModels;
using DinerDataModels.Enum;
using DinerDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace DinerDataBaseImplement.Models
{
public class Order : IOrderModel
[DataContract]
public class Order : IOrderModel
{
public int Id { get; private set; }
[DataMember]
public int Id { get; private set; }
[Required]
public int ClientId { get; private set; }
[DataMember]
public int ClientId { get; private set; }
[DataMember]
public int? ImplementerId { get; private set; }
[Required]
public int SnackId { get; private set; }
[DataMember]
public int SnackId { get; private set; }
[Required]
public int Count { get; private set; }
[DataMember]
public int Count { get; private set; }
[Required]
public double Sum { get; private set; }
[DataMember]
public double Sum { get; private set; }
[Required]
public OrderStatus Status { get; private set; }
[DataMember]
public OrderStatus Status { get; private set; }
[Required]
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; }
[DataMember]
public DateTime DateCreate { get; private set; }
[DataMember]
public DateTime? DateImplement { get; private set; }
public virtual Snack Snack { get; set; }
public virtual Client Client { get; set; }

View File

@@ -3,19 +3,25 @@ using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;
namespace DinerDataBaseImplement.Models
{
public class Snack : ISnackModel
[DataContract]
public class Snack : ISnackModel
{
public int Id { get; set; }
[DataMember]
public int Id { get; set; }
[Required]
public string SnackName { get; set; } = string.Empty;
[DataMember]
public string SnackName { get; set; } = string.Empty;
[Required]
public double Price { get; set; }
[DataMember]
public double Price { get; set; }
private Dictionary<int, (IComponentModel, int)>? _snackComponents = null;
[NotMapped]
public Dictionary<int, (IComponentModel, int)> SnackComponents
[DataMember]
public Dictionary<int, (IComponentModel, int)> SnackComponents
{
get
{

View File

@@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace DinerDataBaseImplement.Models
{
public class SnackComponent
[DataContract]
public class SnackComponent
{
public int Id { get; set; }
[Required]

View File

@@ -11,11 +11,13 @@ namespace DinerFileImplement
private readonly string ProductFileName = "Snack.xml";
private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageFileName = "Message.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Snack> Snacks { get; private set; }
public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
public List<MessageInfo> Messages { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
@@ -29,6 +31,7 @@ namespace DinerFileImplement
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
@@ -36,6 +39,7 @@ namespace DinerFileImplement
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
Messages = LoadData(MessageFileName, "Messages", x => MessageInfo.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{

View File

@@ -9,6 +9,9 @@
<ItemGroup>
<ProjectReference Include="..\..\AbstractShopContracts\DinerContracts.csproj" />
<ProjectReference Include="..\..\AbstractShopDataModels\DinerDataModels.csproj" />
<ProjectReference Include="..\DinerDataBaseImplement\DinerDataBaseImplement.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy /Y &quot;$(TargetDir)*.dll&quot; &quot;$(SolutionDir)ImplementationExtensions\*.dll&quot;" />
</Target>
</Project>

View File

@@ -0,0 +1,33 @@
using DinerContracts.DI;
using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement
{
public class FileImplementationExtension : IImplementationExtension
{
public int Priority => 1;
public void RegisterServices()
{
DependencyManager.Instance.RegisterType<IClientStorage, ClientStorage>();
DependencyManager.Instance.RegisterType<IComponentStorage, ComponentStorage>();
DependencyManager.Instance.RegisterType<IImplementerStorage, ImplementerStorage>();
DependencyManager.Instance.RegisterType<IMessageInfoStorage, MessageInfoStorage>();
DependencyManager.Instance.RegisterType<IOrderStorage, OrderStorage>();
DependencyManager.Instance.RegisterType<ISnackStorage, SnackStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,37 @@
using DinerContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
var source = DataFileSingleton.GetInstance();
return (List<T>?)source.GetType().GetProperties()
.FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == typeof(T))
?.GetValue(source);
}
public Type? GetTypeByModelInterface(string modelInterfaceName)
{
var assembly = typeof(BackUpInfo).Assembly;
var types = assembly.GetTypes();
foreach (var type in types)
{
if (type.IsClass && type.GetInterface(modelInterfaceName) != null)
{
return type;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,74 @@
using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DinerFileImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataFileSingleton source;
public MessageInfoStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
return source.Messages.Select(x => GetViewModel(x)).ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return source.Messages
.Select(x => GetViewModel(x))
.ToList();
}
return source.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => GetViewModel(x))
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return null;
}
return source.Messages.FirstOrDefault(x => (model.ClientId.HasValue && x.ClientId == model.ClientId))?.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
model.MessageId = source.Messages.Count > 0 ? Convert.ToString(source.Messages.Count + 1) : "1";
var newMessage = MessageInfo.Create(model);
if (newMessage == null)
{
return null;
}
source.Messages.Add(newMessage);
source.SaveOrders();
return GetViewModel(newMessage);
}
private MessageInfoViewModel GetViewModel(MessageInfo message)
{
return message.GetViewModel;
}
}
}

View File

@@ -4,21 +4,24 @@ using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
internal class Client : IClientModel
[DataContract]
internal class Client : IClientModel
{
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
[DataMember]
public int Id { get; private set; }
[DataMember]
public string ClientFIO { get; private set; } = string.Empty;
[DataMember]
public string Email { get; private set; } = string.Empty;
[DataMember]
public string Password { get; private set; } = string.Empty;
public static Client? Create(ClientBindingModel model)
{

View File

@@ -1,15 +1,20 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
public class Component : IComponentModel
[DataContract]
public class Component : IComponentModel
{
public int Id { get; private set; }
public string ComponentName { get; private set; } = string.Empty;
public double Cost { get; set; }
[DataMember]
public int Id { get; private set; }
[DataMember]
public string ComponentName { get; private set; } = string.Empty;
[DataMember]
public double Cost { get; set; }
public static Component? Create(ComponentBindingModel model)
{
if (model == null)

View File

@@ -4,22 +4,24 @@ using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
[DataContract]
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
[DataMember]
public string ImplementerFIO { get; private set; } = string.Empty;
[DataMember]
public string Password { get; private set; } = string.Empty;
[DataMember]
public int WorkExperience { get; private set; }
[DataMember]
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel model)

View File

@@ -0,0 +1,99 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
[DataContract]
public class MessageInfo : IMessageInfoModel
{
[DataMember]
public string MessageId { get; private set; } = string.Empty;
[DataMember]
public int? ClientId { get; private set; }
[DataMember]
public string SenderName { get; private set; } = string.Empty;
[DataMember]
public DateTime DateDelivery { get; private set; } = DateTime.Now;
[DataMember]
public string Subject { get; private set; } = string.Empty;
[DataMember]
public string Body { get; private set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new MessageInfo()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
Body = model.Body,
Subject = model.Subject,
DateDelivery = model.DateDelivery
};
}
public static MessageInfo? Create(XElement element)
{
if (element == null)
{
return null;
}
return new MessageInfo()
{
MessageId = element.Element("MessageId")!.Value,
ClientId = Convert.ToInt32(element.Attribute("ClientId")!.Value),
SenderName = element.Element("SenderName")!.Value,
Body = element.Element("Body")!.Value,
Subject = element.Element("Subject")!.Value,
DateDelivery = Convert.ToDateTime(element.Element("DateDelivery")!.Value)
};
}
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
MessageId = model.MessageId;
ClientId = model.ClientId;
SenderName = model.SenderName;
Body = model.Body;
Subject = model.Subject;
DateDelivery = model.DateDelivery;
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery
};
public XElement GetXElement => new("MessageInfo",
new XAttribute("MessageId", MessageId),
new XElement("ClientId", ClientId.ToString()),
new XElement("SenderName", SenderName),
new XElement("Body", Body),
new XElement("Subject", Subject),
new XElement("DateDelivery", DateDelivery.ToString()));
}
}

View File

@@ -3,26 +3,32 @@ using DinerContracts.ViewModels;
using DinerDataModels.Enum;
using DinerDataModels.Models;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
public class Order : IOrderModel
[DataContract]
public class Order : IOrderModel
{
public int Id { get; private set; }
public int SnackID { get; private set; }
public int ClientId { get; private set; }
[DataMember]
public int Id { get; private set; }
[DataMember]
public int SnackID { get; private set; }
[DataMember]
public int ClientId { get; private set; }
[DataMember]
public int? ImplementerId { get; private set; }
[DataMember]
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; }
public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; }
[DataMember]
public double Sum { get; private set; }
[DataMember]
public OrderStatus Status { get; private set; }
[DataMember]
public DateTime DateCreate { get; private set; }
[DataMember]
public DateTime? DateImplement { get; private set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null)

View File

@@ -1,18 +1,25 @@
using DinerContracts.BindingModels;
using DinerContracts.ViewModels;
using DinerDataModels.Models;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace DinerFileImplement.Models
{
public class Snack : ISnackModel
[DataContract]
public class Snack : ISnackModel
{
public int Id { get; private set; }
public string SnackName { get; private set; } = string.Empty;
public double Price { get; private set; }
public Dictionary<int, int> Components { get; private set; } = new();
[DataMember]
public int Id { get; private set; }
[DataMember]
public string SnackName { get; private set; } = string.Empty;
[DataMember]
public double Price { get; private set; }
[DataMember]
public Dictionary<int, int> Components { get; private set; } = new();
private Dictionary<int, (IComponentModel, int)>? _snackComponents = null;
public Dictionary<int, (IComponentModel, int)> SnackComponents
[DataMember]
public Dictionary<int, (IComponentModel, int)> SnackComponents
{
get
{

View File

@@ -163,5 +163,16 @@ namespace DinerClientApp.Controllers
return count * (_snack?.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,51 @@
@using DinerContracts.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>

View File

@@ -27,6 +27,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@@ -13,11 +13,13 @@ namespace DinerRestApi.Controllers
private readonly ILogger _logger;
private readonly IClientLogic _logic;
private readonly IMessageInfoLogic _mailLogic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger)
public ClientController(IClientLogic logic, IMessageInfoLogic mailLogic, ILogger<ClientController> logger)
{
_logger = logger;
_logic = logic;
_mailLogic = mailLogic;
}
[HttpGet]
@@ -65,5 +67,22 @@ namespace DinerRestApi.Controllers
throw;
}
}
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
}
}

View File

@@ -1,4 +1,6 @@
using DinerBusinessLogic.BusinessLogics;
using DinerBusinessLogic.MailWorker;
using DinerContracts.BindingModels;
using DinerContracts.BusinessLogicsContracts;
using DinerContracts.StoragesContracts;
using DinerDataBaseImplement.Implements;
@@ -14,11 +16,15 @@ builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<ISnackStorage, SnackStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<ISnackLogic, SnackLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@@ -30,6 +36,18 @@ builder.Services.AddSwaggerGen(c =>
});
var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{

View File

@@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "forlabwork07@gmail.com",
"MailPassword": "sicr cmdz jpor ikva"
}