9 Commits

90 changed files with 3142 additions and 595 deletions

View File

@@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" /> <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="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.3" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.2.3" />
<PackageReference Include="PDFsharp-MigraDoc" Version="1.50.5147" /> <PackageReference Include="PDFsharp-MigraDoc" Version="1.50.5147" />

View File

@@ -0,0 +1,102 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersDataModels;
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 AbstractFoodOrdersBusinessLogic.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)
{
if (type.IsInterface && type.GetInterface(typeIId.Name) !=
null)
{
var modelType =
_backUpInfo.GetTypeByModelInterface(type.Name);
if (modelType == null)
{
throw new InvalidOperationException($"Не найден класс - модель для { type.Name }");
}
_logger.LogDebug("Call SaveToFile method for {name} type", type.Name);
// вызываем метод на выполнение
method?.MakeGenericMethod(modelType).Invoke(this, new object[] { model.FolderName });
}
}
_logger.LogDebug("Create zip and remove folder");
// архивируем
ZipFile.CreateFromDirectory(model.FolderName, fileName);
// удаляем папку
dirInfo.Delete(true);
}
catch (Exception)
{
throw;
}
}
private void SaveToFile<T>(string folderName) where T : class, new()
{
var records = _backUpInfo.GetList<T>();
if (records == null)
{
_logger.LogWarning("{type} type get null list", typeof(T).Name);
return;
}
var jsonFormatter = new DataContractJsonSerializer(typeof(List<T>));
using var fs = new FileStream(string.Format("{0}/{1}.json", folderName, typeof(T).Name), FileMode.OpenOrCreate);
jsonFormatter.WriteObject(fs, records);
}
}
}

View File

@@ -8,6 +8,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AbstractFoodOrdersBusinessLogic.BusinessLogics namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
@@ -17,7 +18,7 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientStorage _clientStorage; private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage) public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{ {
_logger = logger; _logger = logger;
_clientStorage = clientStorage; _clientStorage = clientStorage;
@@ -108,11 +109,20 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
{ {
throw new ArgumentNullException("Нет электронной почты клиента", nameof(model.Email)); throw new ArgumentNullException("Нет электронной почты клиента", nameof(model.Email));
} }
_logger.LogInformation("Client. ClientFIO:{ClientFIO}. Password:{Password}. Email:{Email}. Id:{Id}", model.ClientFIO, model.Password, model.Email, model.Id); if (!Regex.IsMatch(model.Email, @"^[-\w.]+@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,4}$"))
{
throw new ArgumentNullException("Введенное не является адресом электронной почты", nameof(model.Email));
}
if (!Regex.IsMatch(model.Password, @"^(?=.*\d)(?=.*\W)(?=.*[^\d\s]).+$"))
{
throw new ArgumentException("Некорректно введен пароль клиента", nameof(model.Password));
}
_logger.LogInformation("Client. ClientFIO:{ClientFIO}. Password:{Password}. Email:{Email}. Id:{Id}", model.ClientFIO, model.Password, model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel var element = _clientStorage.GetElement(new ClientSearchModel
{ {
Email = model.Email Email = model.Email
}); });
if (element != null && element.Id != model.Id) if (element != null && element.Id != model.Id)
{ {
throw new InvalidOperationException("Клиент с таким логином уже зарегистрирован"); throw new InvalidOperationException("Клиент с таким логином уже зарегистрирован");

View File

@@ -0,0 +1,82 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
{
public class MessageInfoLogic: IMessageInfoLogic
{
private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageStorage;
private readonly IClientLogic _clientLogic;
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage logic, IClientLogic clientLogic)
{
_logger = logger;
_messageStorage = logic;
_clientLogic = clientLogic;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId:{MessageId}. ClientId:{ClientId}.", model?.MessageId, model?.ClientId);
var list = model == null ? _messageStorage.GetFullList() : _messageStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Create(MessageInfoBindingModel model)
{
CheckModel(model);
model.ClientId = _clientLogic.ReadElement(new ClientSearchModel() { Email = model.SenderName })?.Id;
if (_messageStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(MessageInfoBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.MessageId))
{
throw new ArgumentNullException("Нет id письма", nameof(model.MessageId));
}
if (string.IsNullOrEmpty(model.SenderName))
{
throw new ArgumentNullException("Нет отправителя", nameof(model.SenderName));
}
if (string.IsNullOrEmpty(model.Subject))
{
throw new ArgumentNullException("Нет темы", nameof(model.Subject));
}
if (string.IsNullOrEmpty(model.Body))
{
throw new ArgumentNullException("Нет текста письма", nameof(model.Subject));
}
_logger.LogInformation("MessageInfo. MessageId:{MessageId}. SenderName:{SenderName}. Subject:{Subject}. Body:{Body}", model.MessageId, model.SenderName, model.Subject, model.Body);
}
}
}

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersBusinessLogic.MailWorker;
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.SearchModels; using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts; using AbstractFoodOrdersContracts.StoragesContracts;
@@ -17,70 +18,92 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
static readonly object _locker = new object(); static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker)
{ {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_mailWorker = mailWorker;
} }
public List<OrderViewModel>? ReadList(OrderSearchModel? model) public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{ {
_logger.LogInformation("ReadList. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", _logger.LogInformation("ReadList. Id:{Id}", model?.Id);
model?.ClientId, model?.OrderStatus, model?.ImplementerId, model?.DateFrom, model?.DateTo, model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null) if (list == null)
{ {
_logger.LogWarning("ReadList return null list"); _logger.LogWarning("ReadList return null list");
return null; return null;
} }
_logger.LogInformation("ReadList. Count:{Count}", list.Count); _logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list; return list;
} }
public OrderViewModel? ReadElement(OrderSearchModel model) public OrderViewModel? ReadElement(OrderSearchModel model)
{ {
if (model == null) if (model == null)
{ {
throw new ArgumentNullException(nameof(model)); throw new ArgumentNullException(nameof(model));
} }
_logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", _logger.LogInformation("ReadElement. ClientId: {ClientId}. ImplementerId: {ImplementerId}. Status: {Status}. DateFrom: {DateFrom}. DateTo: {DateTo}. Id: {Id}",
model.ClientId, model.OrderStatus, model.ImplementerId, model.DateFrom, model.DateTo, model.Id); model.ClientId, model.ImplementerId, model.OrderStatus, model.DateFrom, model.DateTo, model.Id);
var element = _orderStorage.GetElement(model); var element = _orderStorage.GetElement(model);
if (element == null) if (element == null)
{ {
_logger.LogWarning("ReadElement element not found"); _logger.LogWarning("ReadElement element not found");
return null; return null;
} }
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id); _logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element; return element;
} }
public bool CreateOrder(OrderBindingModel model) public bool CreateOrder(OrderBindingModel model)
{ {
CheckModel(model); CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) if (model.Status != OrderStatus.Неизвестен)
return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{ {
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Order status change failed");
return false; return false;
} }
model.Status = OrderStatus.Принят;
var orderView = _orderStorage.Insert(model);
if (orderView == null)
{
_logger.LogWarning("Order creation failed");
return false;
}
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = orderView.ClientEmail,
Subject = $"Новый заказ создан. Заказ №{orderView.Id}",
Text = $"Заказ №{orderView.Id} от {orderView.DateCreate} на сумму {orderView.Sum} принят."
}));
return true; return true;
} }
public bool TakeOrderInWork(OrderBindingModel model) public bool TakeOrderInWork(OrderBindingModel model)
{ {
lock (_locker) lock (_locker)
{ {
return ChangeStatus(model, OrderStatus.Выполняется); return ChangeOrderStatus(model, OrderStatus.Выполняется);
} }
} }
public bool FinishOrder(OrderBindingModel model) public bool FinishOrder(OrderBindingModel model)
{ {
return ChangeStatus(model, OrderStatus.Готов); return ChangeOrderStatus(model, OrderStatus.Готов);
} }
public bool DeliveryOrder(OrderBindingModel model) public bool DeliveryOrder(OrderBindingModel model)
{ {
return ChangeStatus(model, OrderStatus.Выдан); return ChangeOrderStatus(model, OrderStatus.Выдан);
} }
private void CheckModel(OrderBindingModel model, bool withParams = true) private void CheckModel(OrderBindingModel model, bool withParams = true)
{ {
if (model == null) if (model == null)
@@ -93,53 +116,50 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
} }
if (model.Count <= 0) if (model.Count <= 0)
{ {
throw new ArgumentException("Колличество изделий в заказе не может быть меньше 1", nameof(model.Count)); throw new ArgumentNullException("Кол-во изделий в заказе должно быть больше 0", nameof(model.Count));
} }
if (model.Sum <= 0) if (model.Sum <= 0)
{ {
throw new ArgumentException("Стоимость заказа на может быть меньше 1", nameof(model.Sum)); throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum));
} }
if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate) _logger.LogInformation("Order. Count: {Count}. Sum: {Sum} Id: {Id}", model.Count, model.Sum, model.Id);
{
throw new ArithmeticException($"Дата выдачи заказа {model.DateImplement} не может быть раньше даты его создания {model.DateCreate}");
}
_logger.LogInformation("Reinforced. ReinforcedId:{ReinforcedId}.Count:{Count}.Sum:{Sum}Id:{Id}",
model.DishId, model.Count, model.Sum, model.Id);
} }
private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus)
private bool ChangeOrderStatus(OrderBindingModel model, OrderStatus newStatus)
{ {
CheckModel(model, false); CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel() var orderView = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (orderView == null || newStatus - orderView.Status != 1)
{ {
Id = model.Id _logger.LogWarning("Order status change failed");
}); return false;
if (element == null)
{
throw new InvalidOperationException(nameof(element));
} }
model.DateCreate = element.DateCreate;
model.DishId = element.DishId; model.Status = newStatus;
model.DateImplement = element.DateImplement;
model.ClientId = element.ClientId;
if (!model.ImplementerId.HasValue) if (!model.ImplementerId.HasValue)
model.ImplementerId = element.ImplementerId; model.ImplementerId = orderView.ImplementerId;
model.Status = element.Status; model.DateImplement = orderView.DateImplement;
model.Count = element.Count;
model.Sum = element.Sum; if (newStatus == OrderStatus.Готов)
if (requiredStatus - model.Status == 1)
{ {
model.Status = requiredStatus; model.DateImplement = DateTime.Now;
if (model.Status == OrderStatus.Готов)
model.DateImplement = DateTime.Now;
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
} }
_logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus);
throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Order status change failed");
return false;
}
Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = orderView.ClientEmail,
Subject = $"Заказ №{orderView.Id}",
Text = $"Заказ №{orderView.Id} изменен статус на {newStatus}."
}));
return true;
} }
} }
} }

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.ViewModels; using AbstractFoodOrdersContracts.ViewModels;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Diagnostics; using System.Diagnostics;
namespace AbstractFoodOrdersClientApp.Controllers namespace AbstractFoodOrdersClientApp.Controllers
@@ -142,5 +143,16 @@ namespace AbstractFoodOrdersClientApp.Controllers
); );
return count * (prod?.Price ?? 1); return count * (prod?.Price ?? 1);
} }
[HttpGet]
public IActionResult Mails()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return
View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={ APIClient.Client.Id}"));
}
} }
} }

View File

@@ -0,0 +1,51 @@
@using AbstractFoodOrdersContracts.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

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

View File

@@ -9,6 +9,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.2" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.2.2" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.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,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.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 AbstractFoodOrdersContracts.BindingModels
{
public class BackUpSaveBinidngModel
{
public string FolderName { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.BindingModels
{
public class MailConfigBindingModel
{
public string MailLogin { get; set; } = string.Empty;
public string MailPassword { get; set; } = string.Empty;
public string SmtpClientHost { get; set; } = string.Empty;
public int SmtpClientPort { get; set; }
public string PopHost { get; set; } = string.Empty;
public int PopPort { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.BindingModels
{
public class MailSendInfoBindingModel
{
public string MailAddress { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,20 @@
using AbstractFoodOrdersDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.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; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public int Id { get; set; }
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.DI
{
/// <summary>
/// Интерфейс для регистрации зависимостей в модулях
/// </summary>
public interface IImplementationExtension
{
public int Priority { get; }
/// <summary>
/// Регистрация сервисов
/// </summary>
public void RegisterServices();
}
}

View File

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

View File

@@ -0,0 +1,55 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using Unity.Microsoft.Logging;
namespace AbstractFoodOrdersContracts.DI
{
public class UnityDependencyContainer : IDependencyContainer
{
private readonly UnityContainer _unityContainer;
public UnityDependencyContainer()
{
_unityContainer = new UnityContainer();
}
public void AddLogging(Action<ILoggingBuilder> configure)
{
_unityContainer.AddExtension(new LoggingExtension(LoggerFactory.Create(configure)));
}
public void RegisterType<T, U>(bool isSingle) where U : class, T where T : class
{
if (isSingle)
{
_unityContainer.RegisterSingleton<T, U>();
}
else
{
_unityContainer.RegisterType<T, U>();
}
}
public void RegisterType<T>(bool isSingle) where T : class
{
if (isSingle)
{
_unityContainer.RegisterSingleton<T>();
}
else
{
_unityContainer.RegisterType<T>();
}
}
public T Resolve<T>()
{
return _unityContainer.Resolve<T>();
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.SearchModels
{
public class MessageInfoSearchModel
{
public string? MessageId { get; set; }
public int? ClientId { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.StoragesContracts
{
public interface IBackUpInfo
{
List<T>? GetList<T>() where T : class, new();
Type? GetTypeByModelInterface(string modelInterfaceName);
}
}

View File

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

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -10,13 +11,14 @@ namespace AbstractFoodOrdersContracts.ViewModels
{ {
public class ClientViewModel:IClientModel public class ClientViewModel:IClientModel
{ {
public int Id { get; set; } [Column(visible: false)]
[DisplayName("ФИО клиента")] public int Id { get; set; }
public string ClientFIO { get; set; } = string.Empty; [Column(title: "ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
[DisplayName("Логин (эл. почта)")] public string ClientFIO { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty; [Column(title: "Логин (эл. почта)", width: 200)]
[DisplayName("Пароль")] public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty; [Column(title: "Пароль", width: 150)]
public string Password { get; set; } = string.Empty;
} }
} }

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -10,11 +11,12 @@ namespace AbstractFoodOrdersContracts.ViewModels
{ {
public class ComponentViewModel : IComponentModel public class ComponentViewModel : IComponentModel
{ {
public int Id { get; set; } [Column(visible: false)]
[DisplayName("Название компонента")] public int Id { get; set; }
public string ComponentName { get; set; } = string.Empty; [Column(title: "Название компонента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
[DisplayName("Цена")] public string ComponentName { get; set; } = string.Empty;
public double Cost { get; set; } [Column(title: "Цена", width: 50)]
} public double Cost { get; set; }
}
} }

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -10,12 +11,18 @@ namespace AbstractFoodOrdersContracts.ViewModels
{ {
public class DishViewModel : IDishModel public class DishViewModel : IDishModel
{ {
public int Id { get; set; } [Column(visible: false)]
[DisplayName("Название изделия")] public int Id { get; set; }
public string DishName { get; set; } = string.Empty; [Column(title: "Название блюда", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
[DisplayName("Цена")] public string DishName { get; set; } = string.Empty;
public double Price { get; set; } [Column(title: "Цена", width: 75)]
public Dictionary<int, (IComponentModel, int)> DishComponents { get; set; } = new(); public double Price { get; set; }
} [Column(visible: false)]
public Dictionary<int, (IComponentModel, int)> DishComponents
{
get;
set;
} = new();
}
} }

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@@ -10,14 +11,15 @@ namespace AbstractFoodOrdersContracts.ViewModels
{ {
public class ImplementerViewModel:IImplementerModel public class ImplementerViewModel:IImplementerModel
{ {
[Column(visible: false)]
public int Id { get; set; } public int Id { get; set; }
[DisplayName("ФИО")] [Column(title: "ФИО", width: 150)]
public string ImplementerFIO { get; set; } = String.Empty; public string ImplementerFIO { get; set; } = String.Empty;
[DisplayName("Пароль")] [Column(title: "Пароль", width: 150)]
public string Password { get; set; } = String.Empty; public string Password { get; set; } = String.Empty;
[DisplayName("Опыт работы")] [Column(title: "Опыт работы", width: 120)]
public int WorkExperience { get; set; } public int WorkExperience { get; set; }
[DisplayName("Квалификация")] [Column(title: "Квалификация", width: 120)]
public int Qualification { get; set; } public int Qualification { get; set; }
} }
} }

View File

@@ -0,0 +1,30 @@
using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersContracts.ViewModels
{
public class MessageInfoViewModel:IMessageInfoModel
{
[Column(visible: false)]
public string MessageId { get; set; } = string.Empty;
[Column(visible: false)]
public int? ClientId { get; set; }
[Column(title: "Отправитель", width: 100)]
public string SenderName { get; set; } = string.Empty;
[Column(title: "Доставлено", width: 100)]
public DateTime DateDelivery { get; set; }
[Column(title: "Заголовок", width: 75)]
public string Subject { get; set; } = string.Empty;
[Column(title: "Текст", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
public string Body { get; set; } = string.Empty;
[Column(visible: false)]
public int Id { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using AbstractFoodOrdersDataModels.Enums; using AbstractFoodOrdersContracts.Attributes;
using AbstractFoodOrdersDataModels.Enums;
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -11,26 +12,31 @@ namespace AbstractFoodOrdersContracts.ViewModels
{ {
public class OrderViewModel : IOrderModel public class OrderViewModel : IOrderModel
{ {
[DisplayName("Номер")] [Column(title: "Номер", width: 80)]
public int Id { get; set; } public int Id { get; set; }
public int DishId { get; set; } [Column(visible: false)]
[DisplayName("Изделие")] public int DishId { get; set; }
public string DishName { get; set; } = string.Empty; [Column(title: "Блюдо", width: 90)]
public string DishName { get; set; } = string.Empty;
[Column(visible: false)]
public int? ImplementerId { get; set; } public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")] [Column(title: "Исполнитель", width: 120)]
public string? ImplementerFIO { get; set; } public string? ImplementerFIO { get; set; }
[Column(visible: false)]
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("ФИО клиента")] [Column(title: "ФИО клиента", width: 120)]
public string ClientFIO { get; set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Количество")] [Column(visible: false)]
public int Count { get; set; } public string ClientEmail { get; set; } = string.Empty;
[DisplayName("Сумма")] [Column(title: "Количество", width: 100)]
public double Sum { get; set; } public int Count { get; set; }
[DisplayName("Статус")] [Column(title: "Сумма", width: 100)]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; public double Sum { get; set; }
[DisplayName("Дата создания")] [Column(title: "Статус", width: 100)]
public DateTime DateCreate { get; set; } = DateTime.Now; public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата выполнения")] [Column(title: "Дата создания", width: 120)]
public DateTime? DateImplement { get; set; } public DateTime DateCreate { get; set; } = DateTime.Now;
} [Column(title: "Дата выполнения", width: 120)]
public DateTime? DateImplement { get; set; }
}
} }

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,27 @@
using AbstractFoodOrdersContracts.DI;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersDatabaseImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersDatabaseImplement
{
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<IDishStorage, DishStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,32 @@
using AbstractFoodOrdersContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersDatabaseImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
using var context = new AbstractFoodOrdersDatabase();
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

@@ -0,0 +1,59 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersDatabaseImplement.Implements
{
public class MessageInfoStorage:IMessageInfoStorage
{
public List<MessageInfoViewModel> GetFullList()
{
using var context = new AbstractFoodOrdersDatabase();
return context.MessageInfos
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return new();
}
using var context = new AbstractFoodOrdersDatabase();
return context.MessageInfos
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return new();
}
using var context = new AbstractFoodOrdersDatabase();
return context.MessageInfos
.FirstOrDefault(x => x.MessageId.Equals(model.MessageId) && x.ClientId == model.ClientId)
?.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null)
{
return null;
}
using var context = new AbstractFoodOrdersDatabase();
context.MessageInfos.Add(newMessageInfo);
context.SaveChanges();
return newMessageInfo.GetViewModel;
}
}
}

View File

@@ -0,0 +1,285 @@
// <auto-generated />
using System;
using AbstractFoodOrdersDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AbstractFoodOrdersDatabaseImplement.Migrations
{
[DbContext(typeof(AbstractFoodOrdersDatabase))]
[Migration("20230530143643_MailInfo")]
partial class MailInfo
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.Models.Dish", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("DishName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Dishes");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", 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>("DishId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("DishId");
b.ToTable("DishComponents");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.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.ToTable("MessageInfos");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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>("DishId")
.HasColumnType("int");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("DishId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", b =>
{
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Component", "Component")
.WithMany("DishComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish")
.WithMany("Components")
.HasForeignKey("DishId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Dish");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b =>
{
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Client", "Client")
.WithMany("ClientOrders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish")
.WithMany("Orders")
.HasForeignKey("DishId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Dish");
b.Navigation("Implementer");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Client", b =>
{
b.Navigation("ClientOrders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Component", b =>
{
b.Navigation("DishComponents");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Dish", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AbstractFoodOrdersDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class MailInfo : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "MessageInfos",
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_MessageInfos", x => x.MessageId);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "MessageInfos");
}
}
}

View File

@@ -0,0 +1,285 @@
// <auto-generated />
using System;
using AbstractFoodOrdersDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AbstractFoodOrdersDatabaseImplement.Migrations
{
[DbContext(typeof(AbstractFoodOrdersDatabase))]
[Migration("20230601100316_MessageInfoUpdate")]
partial class MessageInfoUpdate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.Models.Dish", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("DishName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Dishes");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", 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>("DishId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("DishId");
b.ToTable("DishComponents");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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("AbstractFoodOrdersDatabaseImplement.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.ToTable("MessageInfos");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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>("DishId")
.HasColumnType("int");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("DishId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.DishComponent", b =>
{
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Component", "Component")
.WithMany("DishComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish")
.WithMany("Components")
.HasForeignKey("DishId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Dish");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b =>
{
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Client", "Client")
.WithMany("ClientOrders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Dish", "Dish")
.WithMany("Orders")
.HasForeignKey("DishId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AbstractFoodOrdersDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Dish");
b.Navigation("Implementer");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Client", b =>
{
b.Navigation("ClientOrders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Component", b =>
{
b.Navigation("DishComponents");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Dish", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AbstractFoodOrdersDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class MessageInfoUpdate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@@ -140,6 +140,34 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
b.ToTable("Implementers"); b.ToTable("Implementers");
}); });
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.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.ToTable("MessageInfos");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b => modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")

View File

@@ -6,19 +6,25 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AbstractFoodOrdersDatabaseImplement.Models namespace AbstractFoodOrdersDatabaseImplement.Models
{ {
public class Client:IClientModel [DataContract]
public class Client:IClientModel
{ {
public int Id { get; set; } [DataMember]
[Required] public int Id { get; set; }
[DataMember]
[Required]
public string ClientFIO { get; private set; } = string.Empty; public string ClientFIO { get; private set; } = string.Empty;
[Required] [DataMember]
[Required]
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;
[Required] [DataMember]
[Required]
public string Email { get; private set; } = string.Empty; public string Email { get; private set; } = string.Empty;
[ForeignKey("ClientId")] [ForeignKey("ClientId")]
public virtual List<Order> ClientOrders { get; set; } = new(); public virtual List<Order> ClientOrders { get; set; } = new();

View File

@@ -3,15 +3,20 @@ using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace AbstractFoodOrdersDatabaseImplement.Models namespace AbstractFoodOrdersDatabaseImplement.Models
{ {
public class Component : IComponentModel [DataContract]
public class Component : IComponentModel
{ {
public int Id { get; private set; } [DataMember]
[Required] public int Id { get; private set; }
[DataMember]
[Required]
public string ComponentName { get; private set; } = string.Empty; public string ComponentName { get; private set; } = string.Empty;
[Required] [DataMember]
[Required]
public double Cost { get; set; } public double Cost { get; set; }
[ForeignKey("ComponentId")] [ForeignKey("ComponentId")]
public virtual List<DishComponent> DishComponents { get; set; } = new(); public virtual List<DishComponent> DishComponents { get; set; } = new();

View File

@@ -8,15 +8,20 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.ViewModels; using AbstractFoodOrdersContracts.ViewModels;
using System.Runtime.Serialization;
namespace AbstractFoodOrdersDatabaseImplement.Models namespace AbstractFoodOrdersDatabaseImplement.Models
{ {
[DataContract]
public class Dish : IDishModel public class Dish : IDishModel
{ {
public int Id { get; set; } [DataMember]
[Required] public int Id { get; set; }
[DataMember]
[Required]
public string DishName { get; set; } = string.Empty; public string DishName { get; set; } = string.Empty;
[Required] [DataMember]
[Required]
public double Price { get; set; } public double Price { get; set; }
private Dictionary<int, (IComponentModel, int)>? _dishComponents = null; private Dictionary<int, (IComponentModel, int)>? _dishComponents = null;
[NotMapped] [NotMapped]

View File

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

View File

@@ -0,0 +1,67 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace AbstractFoodOrdersDatabaseImplement.Models
{
[DataContract]
public class MessageInfo:IMessageInfoModel
{
[DataMember]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string MessageId { get; set; } = string.Empty;
[DataMember]
public int? ClientId { get; set; }
[DataMember]
[Required]
public string SenderName { get; set; } = string.Empty;
[DataMember]
[Required]
public DateTime DateDelivery { get; set; }
[DataMember]
[Required]
public string Subject { get; set; } = string.Empty;
[DataMember]
[Required]
public string Body { get; set; } = string.Empty;
[NotMapped]
public int Id { get; private 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,
Subject = model.Subject,
DateDelivery = model.DateDelivery
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery
};
}
}

View File

@@ -7,6 +7,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -14,23 +15,32 @@ namespace AbstractFoodOrdersDatabaseImplement.Models
{ {
public class Order : IOrderModel public class Order : IOrderModel
{ {
public int Id { get; private set; } [DataMember]
[Required] public int Id { get; private set; }
[DataMember]
[Required]
public int DishId { get; private set; } public int DishId { get; private set; }
[Required] [DataMember]
[Required]
public int ClientId { get; set; } public int ClientId { get; set; }
public virtual Client Client { get; set; } = new(); public virtual Client Client { get; set; } = new();
[DataMember]
public int? ImplementerId { get; set; } public int? ImplementerId { get; set; }
public virtual Implementer? Implementer { get; set; } = new(); public virtual Implementer? Implementer { get; set; } = new();
[DataMember]
[Required] [Required]
public int Count { get; private set; } public int Count { get; private set; }
[Required] [DataMember]
[Required]
public double Sum { get; private set; } public double Sum { get; private set; }
[Required] [DataMember]
[Required]
public OrderStatus Status { get; private set; } public OrderStatus Status { get; private set; }
[Required] [DataMember]
[Required]
public DateTime DateCreate { get; private set; } public DateTime DateCreate { get; private set; }
public DateTime? DateImplement { get; private set; } [DataMember]
public DateTime? DateImplement { get; private set; }
public virtual Dish Dish { get; set; } public virtual Dish Dish { get; set; }
public static Order? Create(AbstractFoodOrdersDatabase data, OrderBindingModel? model) public static Order? Create(AbstractFoodOrdersDatabase data, OrderBindingModel? model)
{ {
@@ -70,6 +80,7 @@ namespace AbstractFoodOrdersDatabaseImplement.Models
DishId = DishId, DishId = DishId,
ClientId = ClientId, ClientId = ClientId,
ClientFIO = Client.ClientFIO, ClientFIO = Client.ClientFIO,
ClientEmail = Client.Email,
Count = Count, Count = Count,
Sum = Sum, Sum = Sum,
Status = Status, Status = Status,

View File

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

View File

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

View File

@@ -0,0 +1,22 @@
using AbstractFoodOrdersContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersListImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
public List<T>? GetList<T>() where T : class, new()
{
throw new NotImplementedException();
}
public Type? GetTypeByModelInterface(string modelInterfaceName)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,77 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersListImplement.Implements
{
public class MessageInfoStorage : IMessageInfoStorage
{
private readonly DataListSingleton _source;
public MessageInfoStorage(DataListSingleton source)
{
_source = source;
}
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) && !model.ClientId.HasValue)
{
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) && !model.ClientId.HasValue)
{
return null;
}
foreach (var messageInfo in _source.MessageInfos)
{
if (!string.IsNullOrEmpty(model.MessageId) && model.ClientId.HasValue && messageInfo.MessageId == model.MessageId && messageInfo.ClientId == model.ClientId)
{
return messageInfo.GetViewModel;
}
}
return null;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null)
{
return null;
}
_source.MessageInfos.Add(newMessageInfo);
return newMessageInfo.GetViewModel;
}
}
}

View File

@@ -0,0 +1,26 @@
using AbstractFoodOrdersContracts.DI;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersListImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersListImplement
{
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<IDishStorage, DishStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,49 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersListImplement.Models
{
public class MessageInfo : 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; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty;
public int Id { get; private 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,
Subject = model.Subject,
DateDelivery = model.DateDelivery
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery
};
}
}

View File

@@ -12,11 +12,13 @@ namespace AbstractFoodOrdersRestApi.Controllers
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController> private readonly IMessageInfoLogic _mailLogic;
public ClientController(IClientLogic logic, IMessageInfoLogic mailLogic, ILogger<ClientController>
logger) logger)
{ {
_logger = logger; _logger = logger;
_logic = logic; _logic = logic;
_mailLogic = mailLogic;
} }
[HttpGet] [HttpGet]
public ClientViewModel? Login(string login, string password) public ClientViewModel? Login(string login, string password)
@@ -61,5 +63,22 @@ namespace AbstractFoodOrdersRestApi.Controllers
throw; 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 AbstractFoodOrdersBusinessLogic.BusinessLogics; using AbstractFoodOrdersBusinessLogic.BusinessLogics;
using AbstractFoodOrdersBusinessLogic.MailWorker;
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.StoragesContracts; using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersDatabaseImplement.Implements; using AbstractFoodOrdersDatabaseImplement.Implements;
@@ -13,9 +15,16 @@ builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IDishStorage, DishStorage>(); builder.Services.AddTransient<IDishStorage, DishStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IDishLogic, DishLogic>(); builder.Services.AddTransient<IDishLogic, DishLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddTransient<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@@ -27,6 +36,18 @@ builder.Services.AddSwaggerGen(c =>
var app = builder.Build(); 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. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {

View File

@@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "labwork07mail@gmail.com",
"MailPassword": "ugqf vpli kqcu fjui"
} }

View File

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

View File

@@ -8,62 +8,58 @@ using System.Xml.Linq;
namespace AbstractFoodOrdersFileImplement namespace AbstractFoodOrdersFileImplement
{ {
internal class DataFileSingleton public class DataFileSingleton
{ {
private static DataFileSingleton? instance; private static DataFileSingleton? instance;
private readonly string ComponentFileName = "Component.xml"; private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml"; private readonly string OrderFileName = "Order.xml";
private readonly string DishFileName = "Dish.xml"; private readonly string DishFileName = "Dish.xml";
private readonly string ClientFileName = "Client.xml"; private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml"; private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageInfoFileName = "MessageInfo.xml";
public List<Component> Components { get; private set; } public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<Dish> Dishes { get; private set; } public List<Dish> Dishes { get; private set; }
public List<Client> Clients { get; private set; } public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; } public List<Implementer> Implementers { get; private set; }
public List<MessageInfo> MessageInfos { get; private set; }
public static DataFileSingleton GetInstance() public static DataFileSingleton GetInstance()
{ {
if (instance == null) if (instance == null)
{ {
instance = new DataFileSingleton(); instance = new DataFileSingleton();
} }
return instance; return instance;
}
public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
public void SaveDishes() => SaveData(Dishes, DishFileName, "Dishes", x => x.GetXElement);
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);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x =>
Component.Create(x)!)!;
Dishes = LoadData(DishFileName, "Dish", x =>
Dish.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x =>
Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x =>
Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
} }
private static List<T>? LoadData<T>(string filename, string xmlNodeName, public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
Func<XElement, T> selectFunction) public void SaveDishes() => SaveData(Dishes, DishFileName, "Dishes", x => x.GetXElement);
{ public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
if (File.Exists(filename)) public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
{ public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
return public void SaveMessageInfos() => SaveData(MessageInfos, MessageInfoFileName, "MessageInfos", x => x.GetXElement);
XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList(); private DataFileSingleton()
} {
return new List<T>(); Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
} Dishes = LoadData(DishFileName, "Dish", x => Dish.Create(x)!)!;
private static void SaveData<T>(List<T> data, string filename, string Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
xmlNodeName, Func<T, XElement> selectFunction) Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
{ Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
if (data != null) MessageInfos = LoadData(MessageInfoFileName, "MessageInfo", x => MessageInfo.Create(x)!)!;
{ }
new XDocument(new XElement(xmlNodeName, private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
data.Select(selectFunction).ToArray())).Save(filename); {
} if (File.Exists(filename))
} {
} return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList();
}
return new List<T>();
}
private static void SaveData<T>(List<T> data, string filename, string xmlNodeName, Func<T, XElement> selectFunction)
{
if (data != null)
{
new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray())).Save(filename);
}
}
}
} }

View File

@@ -0,0 +1,27 @@
using AbstractFoodOrdersContracts.DI;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersFileImplement.Implements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersFileImplement
{
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<IDishStorage, DishStorage>();
DependencyManager.Instance.RegisterType<IBackUpInfo, BackUpInfo>();
}
}
}

View File

@@ -0,0 +1,43 @@
using AbstractFoodOrdersContracts.StoragesContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersFileImplement.Implements
{
public class BackUpInfo : IBackUpInfo
{
private readonly DataFileSingleton source;
private readonly PropertyInfo[] sourceProps;
public BackUpInfo()
{
source = DataFileSingleton.GetInstance();
sourceProps = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
}
public List<T>? GetList<T>() where T : class, new()
{
return (List<T>?)sourceProps
.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,61 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AbstractFoodOrdersFileImplement.Implements
{
public class MessageInfoStorage:IMessageInfoStorage
{
private readonly DataFileSingleton source;
public MessageInfoStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<MessageInfoViewModel> GetFullList()
{
return source.MessageInfos
.Select(x => x.GetViewModel)
.ToList();
}
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return new();
}
return source.MessageInfos
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId) && !model.ClientId.HasValue)
{
return new();
}
return source.MessageInfos
.FirstOrDefault(x => x.MessageId.Equals(model.MessageId) && x.ClientId == model.ClientId)
?.GetViewModel;
}
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessageInfo = MessageInfo.Create(model);
if (newMessageInfo == null)
{
return null;
}
source.MessageInfos.Add(newMessageInfo);
source.SaveMessageInfos();
return newMessageInfo.GetViewModel;
}
}
}

View File

@@ -12,59 +12,61 @@ using System.Threading.Tasks;
namespace AbstractFoodOrdersFileImplement.Implements namespace AbstractFoodOrdersFileImplement.Implements
{ {
public class OrderStorage : IOrderStorage public class OrderStorage : IOrderStorage
{ {
private readonly DataFileSingleton source; private readonly DataFileSingleton source;
public OrderStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders
.Select(x => AccessDishStorage(x.GetViewModel))
.ToList();
}
public OrderStorage() public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{ {
source = DataFileSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => x.GetViewModel)
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue || !model.DateFrom.HasValue || !model.DateTo.HasValue || !model.OrderStatus.HasValue) if (!model.Id.HasValue || !model.DateFrom.HasValue || !model.DateTo.HasValue || !model.OrderStatus.HasValue)
{ {
return new(); return new();
} }
if (model.OrderStatus.HasValue) if (model.OrderStatus.HasValue)
{ {
return source.Orders.Where(x => x.ImplementerId == model.ImplementerId) return source.Orders
.Select(x => x.GetViewModel) .Where(x => x.ImplementerId == model.ImplementerId)
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); .Select(x => AccessDishStorage(x.GetViewModel))
} .ToList();
if (!model.DateFrom.HasValue || !model.DateTo.HasValue) }
{ if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
return source.Orders.Where(x => x.Id == model.Id) {
.Select(x => x.GetViewModel) return source.Orders
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); .Where(x => x.Id == model.Id)
} .Select(x => AccessDishStorage(x.GetViewModel))
else .ToList();
{ }
return source.Orders.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) else
.Select(x => x.GetViewModel) {
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList(); return source.Orders
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => AccessDishStorage(x.GetViewModel))
.ToList();
} }
} }
public OrderViewModel? GetElement(OrderSearchModel model) public OrderViewModel? GetElement(OrderSearchModel model)
{ {
if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue) if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue)
{ {
return null; return null;
} }
if (!model.Id.HasValue) if (!model.Id.HasValue)
{ {
return AccessDishStorage(source.Orders return AccessDishStorage(source.Orders
.FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue .FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue
&& x.ImplementerId == model.ImplementerId && x.Status == model.OrderStatus) && x.ImplementerId == model.ImplementerId && x.Status == model.OrderStatus)
?.GetViewModel); ?.GetViewModel);
} }
else else
{ {
@@ -74,16 +76,8 @@ namespace AbstractFoodOrdersFileImplement.Implements
} }
} }
//для загрузки названий изделия в заказе public OrderViewModel? Insert(OrderBindingModel model)
private OrderViewModel AccessDishStorage(OrderViewModel model) {
{
string? dishName = source.Dishes.FirstOrDefault(x => x.Id == model?.DishId)?.DishName;
if (dishName != null) model.DishName = dishName;
return model;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1; model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1;
var newOrder = Order.Create(model); var newOrder = Order.Create(model);
if (newOrder == null) if (newOrder == null)
@@ -95,8 +89,8 @@ namespace AbstractFoodOrdersFileImplement.Implements
return AccessDishStorage(newOrder.GetViewModel); return AccessDishStorage(newOrder.GetViewModel);
} }
public OrderViewModel? Update(OrderBindingModel model) public OrderViewModel? Update(OrderBindingModel model)
{ {
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id); var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null) if (order == null)
{ {
@@ -107,8 +101,8 @@ namespace AbstractFoodOrdersFileImplement.Implements
return AccessDishStorage(order.GetViewModel); return AccessDishStorage(order.GetViewModel);
} }
public OrderViewModel? Delete(OrderBindingModel model) public OrderViewModel? Delete(OrderBindingModel model)
{ {
var element = source.Orders.FirstOrDefault(x => x.Id == model.Id); var element = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (element != null) if (element != null)
{ {
@@ -118,5 +112,12 @@ namespace AbstractFoodOrdersFileImplement.Implements
} }
return null; return null;
} }
}
public OrderViewModel AccessDishStorage(OrderViewModel model)
{
string? pastryName = source.Dishes.FirstOrDefault(x => x.Id == model?.DishId)?.DishName;
if (pastryName != null) model.DishName = pastryName;
return model;
}
}
} }

View File

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

View File

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

View File

@@ -4,17 +4,22 @@ using AbstractFoodOrdersDataModels.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
namespace AbstractFoodOrdersFileImplement.Models namespace AbstractFoodOrdersFileImplement.Models
{ {
[DataContract]
public class Dish : IDishModel public class Dish : IDishModel
{ {
public int Id { get; private set; } [DataMember]
public string DishName { get; private set; } = string.Empty; public int Id { get; private set; }
public double Price { get; private set; } [DataMember]
public string DishName { get; private set; } = string.Empty;
[DataMember]
public double Price { get; private set; }
public Dictionary<int, int> Components { get; private set; } = new(); public Dictionary<int, int> Components { get; private set; } = new();
private Dictionary<int, (IComponentModel, int)>? _dishComponents = private Dictionary<int, (IComponentModel, int)>? _dishComponents =
null; null;

View File

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

View File

@@ -0,0 +1,83 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.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 AbstractFoodOrdersFileImplement.Models
{
[DataContract]
public class MessageInfo:IMessageInfoModel
{
[DataMember]
public string MessageId { get; set; } = string.Empty;
[DataMember]
public int? ClientId { get; set; }
[DataMember]
public string SenderName { get; set; } = string.Empty;
[DataMember]
public DateTime DateDelivery { get; set; }
[DataMember]
public string Subject { get; set; } = string.Empty;
[DataMember]
public string Body { get; set; } = string.Empty;
public int Id { get; private 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,
Subject = model.Subject,
DateDelivery = model.DateDelivery
};
}
public static MessageInfo? Create(XElement element)
{
if (element == null)
{
return null;
}
return new MessageInfo()
{
MessageId = element.Attribute("MessageId")!.Value,
ClientId = Convert.ToInt32(element.Element("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 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("Subject", Subject),
new XElement("Body", Body),
new XElement("DateDelivery", DateDelivery.ToString()));
}
}

View File

@@ -6,100 +6,102 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
namespace AbstractFoodOrdersFileImplement.Models namespace AbstractFoodOrdersFileImplement.Models
{ {
public class Order : IOrderModel [DataContract]
{ public class Order : IOrderModel
public int Id { get; private set; } {
public int DishId { get; private set; } [DataMember]
public int ClientId { get; private set; } public int Id { get; private set; }
[DataMember]
public int DishId { get; private set; }
[DataMember]
public int ClientId { get; private set; }
[DataMember]
public int? ImplementerId { get; private set; } public int? ImplementerId { get; private set; }
[DataMember]
public int Count { get; private set; } public int Count { get; private set; }
public double Sum { get; private set; } [DataMember]
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен; public double Sum { get; private set; }
public DateTime DateCreate { get; private set; } = DateTime.Now; [DataMember]
public DateTime? DateImplement { get; private set; } 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) public static Order? Create(OrderBindingModel? model)
{ {
if (model == null) if (model == null)
{ {
return null; return null;
} }
return new Order() return new Order()
{ {
Id = model.Id, Id = model.Id,
DishId = model.DishId, DishId = model.DishId,
ClientId = model.ClientId, Count = model.Count,
Count = model.Count, Sum = model.Sum,
Sum = model.Sum, Status = model.Status,
Status = model.Status, DateCreate = model.DateCreate,
DateCreate = model.DateCreate, DateImplement = model.DateImplement,
DateImplement = model.DateImplement, ImplementerId = model.ImplementerId
ImplementerId = model.ImplementerId };
}; }
}
public static Order? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Order()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
DishId = Convert.ToInt32(element.Element("DishId")!.Value),
ClientId = Convert.ToInt32(element.Element("ClientId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value),
DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value),
DateImplement = string.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null :
Convert.ToDateTime(element.Element("DateImplement")!.Value),
public static Order? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Order()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
DishId = Convert.ToInt32(element.Element("DishId")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Convert.ToInt32(element.Element("Status")!.Value),
DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value),
DateImplement = Convert.ToDateTime(String.IsNullOrEmpty(element.Element("DateImplement")!.Value) ? null : element.Element("DateImplement")!.Value),
ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value), ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value),
}; };
}
public void Update(OrderBindingModel? model)
{
if (model == null)
{
return;
}
DishId = model.DishId;
ClientId = model.ClientId;
Count = model.Count;
Sum = model.Sum;
Status = model.Status;
DateCreate = model.DateCreate;
DateImplement = model.DateImplement;
ImplementerId = model.ImplementerId;
} }
public OrderViewModel GetViewModel => new()
{ public void Update(OrderBindingModel model)
Id = Id, {
DishId = DishId, if (model == null)
ClientId = ClientId, {
Count = Count, return;
Sum = Sum, }
Status = Status, Status = model.Status;
DateCreate = DateCreate, ImplementerId = model.ImplementerId;
DateImplement = DateImplement, if (model.DateImplement.HasValue) DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
DishId = DishId,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
ImplementerId = ImplementerId ImplementerId = ImplementerId
}; };
public XElement GetXElement => new("Order", public XElement GetXElement => new("Order",
new XAttribute("Id", Id), new XAttribute("Id", Id),
new XElement("DishId", DishId), new XElement("DishId", DishId),
new XElement("ClientId", ClientId), new XElement("Count", Count.ToString()),
new XElement("ImplementerId", ImplementerId.ToString()), new XElement("Sum", Sum.ToString()),
new XElement("Count", Count.ToString()), new XElement("Status", ((int)Status).ToString()),
new XElement("Sum", Sum.ToString()), new XElement("DateCreate", DateCreate.ToString()),
new XElement("Status", Status.ToString()), new XElement("ImplementerId", ImplementerId.ToString()),
new XElement("DateCreate", DateCreate.ToString()), new XElement("DateImplement", DateImplement.ToString()));
new XElement("DateImplement", DateImplement.ToString())); }
}
} }

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="labwork07mail@gmail.com" />
<add key="MailPassword" value="ugqf vpli kqcu fjui" />
</appSettings>
</configuration>

View File

@@ -0,0 +1,55 @@
using AbstractFoodOrdersContracts.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FoodOrders
{
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

@@ -32,15 +32,9 @@ namespace FoodOrders
private void LoadData() private void LoadData()
{ {
try try
{ {
var list = _logic.ReadList(null); dataGridViewClients.FillAndConfigGrid(_logic.ReadList(null));
if (list != null)
{
dataGridViewClients.DataSource = list;
dataGridViewClients.Columns["Id"].Visible = false;
dataGridViewClients.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка клиентов"); _logger.LogInformation("Загрузка клиентов");
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -1,5 +1,6 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.DI;
using FoodOrders; using FoodOrders;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
@@ -30,51 +31,37 @@ namespace FoodOrders
} }
private void LoadData() private void LoadData()
{ {
try try
{ {
var list = _logic.ReadList(null); dataGridView.FillAndConfigGrid(_logic.ReadList(null));
if (list != null) _logger.LogInformation("Загрузка компонентов");
{ }
dataGridView.DataSource = list; catch (Exception ex)
dataGridView.Columns["Id"].Visible = false; {
dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _logger.LogError(ex, "Ошибка загрузки компонент");
} MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogInformation("Загрузка компонентов"); }
} }
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки компонентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e) private void ButtonAdd_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); var form = DependencyManager.Instance.Resolve<FormComponent>();
if (service is FormComponent form) if (form.ShowDialog() == DialogResult.OK)
{ {
if (form.ShowDialog() == DialogResult.OK) LoadData();
{ }
LoadData(); }
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e) private void ButtonUpd_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); var form = DependencyManager.Instance.Resolve<FormComponent>();
if (service is FormComponent form) form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
{ if (form.ShowDialog() == DialogResult.OK)
form.Id = {
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); LoadData();
if (form.ShowDialog() == DialogResult.OK) }
{ }
LoadData(); }
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e) private void ButtonDel_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)

View File

@@ -1,5 +1,6 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.DI;
using AbstractFoodOrdersContracts.SearchModels; using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersDataModels.Models; using AbstractFoodOrdersDataModels.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -38,8 +39,7 @@ namespace FoodOrders
{ {
var view = _logic.ReadElement(new DishSearchModel var view = _logic.ReadElement(new DishSearchModel
{ {
Id = Id = _id.Value
_id.Value
}); });
if (view != null) if (view != null)
{ {
@@ -82,9 +82,8 @@ namespace FoodOrders
} }
private void ButtonAdd_Click(object sender, EventArgs e) private void ButtonAdd_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormDishComponent)); var form = DependencyManager.Instance.Resolve<FormDishComponent>();
if (service is FormDishComponent form)
{
if (form.ShowDialog() == DialogResult.OK) if (form.ShowDialog() == DialogResult.OK)
{ {
if (form.ComponentModel == null) if (form.ComponentModel == null)
@@ -104,18 +103,15 @@ namespace FoodOrders
} }
LoadData(); LoadData();
} }
}
} }
private void ButtonUpd_Click(object sender, EventArgs e) private void ButtonUpd_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
var service = var form = DependencyManager.Instance.Resolve<FormDishComponent>();
Program.ServiceProvider?.GetService(typeof(FormDishComponent));
if (service is FormDishComponent form) int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
{
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id; form.Id = id;
form.Count = _productComponents[id].Item2; form.Count = _productComponents[id].Item2;
if (form.ShowDialog() == DialogResult.OK) if (form.ShowDialog() == DialogResult.OK)
@@ -128,7 +124,7 @@ namespace FoodOrders
_productComponents[form.Id] = (form.ComponentModel, form.Count); _productComponents[form.Id] = (form.ComponentModel, form.Count);
LoadData(); LoadData();
} }
}
} }
} }
private void ButtonDel_Click(object sender, EventArgs e) private void ButtonDel_Click(object sender, EventArgs e)

View File

@@ -1,5 +1,6 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.DI;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -32,52 +33,39 @@ namespace FoodOrders
private void LoadData() private void LoadData()
{ {
try try
{ {
var list = _logic.ReadList(null); dataGridView.FillAndConfigGrid(_logic.ReadList(null));
if (list != null) _logger.LogInformation("Загрузка изделий");
{ }
dataGridView.DataSource = list; catch (Exception ex)
dataGridView.Columns["Id"].Visible = false; {
dataGridView.Columns["DishComponents"].Visible = false; _logger.LogError(ex, "Ошибка загрузки изделий");
dataGridView.Columns["DishName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
_logger.LogInformation("Загрузка изделий"); }
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAdd_Click(object sender, EventArgs e) private void buttonAdd_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormDish)); var form = DependencyManager.Instance.Resolve<FormDish>();
if (service is FormDish form) if (form.ShowDialog() == DialogResult.OK)
{ {
if (form.ShowDialog() == DialogResult.OK) LoadData();
{ }
LoadData(); }
}
}
}
private void buttonUpd_Click(object sender, EventArgs e) private void buttonUpd_Click(object sender, EventArgs e)
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormDish)); var form = DependencyManager.Instance.Resolve<FormDish>();
if (service is FormDish form) form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
{ if (form.ShowDialog() == DialogResult.OK)
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); {
if (form.ShowDialog() == DialogResult.OK) LoadData();
{ }
LoadData(); }
} }
}
}
}
private void buttonDel_Click(object sender, EventArgs e) private void buttonDel_Click(object sender, EventArgs e)
{ {

View File

@@ -1,5 +1,6 @@
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.DI;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -33,13 +34,7 @@ namespace FoodOrders
{ {
try try
{ {
var list = _logic.ReadList(null); dataGridView.FillAndConfigGrid(_logic.ReadList(null));
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка исполнителей"); _logger.LogInformation("Загрузка исполнителей");
} }
catch (Exception ex) catch (Exception ex)
@@ -51,13 +46,10 @@ namespace FoodOrders
private void buttonAdd_Click(object sender, EventArgs e) private void buttonAdd_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer)); var form = DependencyManager.Instance.Resolve<FormCreateImplementer>();
if (service is FormCreateImplementer form) if (form.ShowDialog() == DialogResult.OK)
{ {
if (form.ShowDialog() == DialogResult.OK) LoadData();
{
LoadData();
}
} }
} }
@@ -65,14 +57,11 @@ namespace FoodOrders
{ {
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer)); var form = DependencyManager.Instance.Resolve<FormCreateImplementer>();
if (service is FormCreateImplementer form) form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{ {
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); LoadData();
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
} }
} }
} }

View File

@@ -0,0 +1,67 @@
namespace FoodOrders
{
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()
{
this.dataGridView = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.SuspendLayout();
//
// dataGridView
//
this.dataGridView.BackgroundColor = System.Drawing.Color.White;
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView.Location = new System.Drawing.Point(2, 1);
this.dataGridView.MultiSelect = false;
this.dataGridView.Name = "dataGridView";
this.dataGridView.RowHeadersVisible = false;
this.dataGridView.RowHeadersWidth = 51;
this.dataGridView.RowTemplate.Height = 29;
this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dataGridView.Size = new System.Drawing.Size(809, 292);
this.dataGridView.TabIndex = 6;
//
// FormMails
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(812, 298);
this.Controls.Add(this.dataGridView);
this.Name = "FormMails";
this.Text = "Письма";
this.Load += new System.EventHandler(this.FormMails_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
this.ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@@ -0,0 +1,40 @@
using AbstractFoodOrdersContracts.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 FoodOrders
{
public partial class FormMails : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormMails_Load(object sender, EventArgs e)
{
try
{
dataGridView.FillAndConfigGrid(_logic.ReadList(null));
_logger.LogInformation("Загрузка писем");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<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

@@ -33,6 +33,8 @@
КомпонентыToolStripMenuItem = new ToolStripMenuItem(); КомпонентыToolStripMenuItem = new ToolStripMenuItem();
БлюдаToolStripMenuItem = new ToolStripMenuItem(); БлюдаToolStripMenuItem = new ToolStripMenuItem();
ClientToolStripMenuItem = new ToolStripMenuItem(); ClientToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
письмаToolStripMenuItem = new ToolStripMenuItem();
отчётыToolStripMenuItem = new ToolStripMenuItem(); отчётыToolStripMenuItem = new ToolStripMenuItem();
ComponentToolStripMenuItem = new ToolStripMenuItem(); ComponentToolStripMenuItem = new ToolStripMenuItem();
ComponentProductsToolStripMenuItem = new ToolStripMenuItem(); ComponentProductsToolStripMenuItem = new ToolStripMenuItem();
@@ -42,7 +44,7 @@
ButtonCreateOrder = new Button(); ButtonCreateOrder = new Button();
ButtonIssuedOrder = new Button(); ButtonIssuedOrder = new Button();
ButtonRef = new Button(); ButtonRef = new Button();
исполнителиToolStripMenuItem = new ToolStripMenuItem(); создатьБекапToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout(); menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout(); SuspendLayout();
@@ -50,7 +52,7 @@
// menuStrip // menuStrip
// //
menuStrip.ImageScalingSize = new Size(20, 20); menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem }); menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem, создатьБекапToolStripMenuItem });
menuStrip.Location = new Point(0, 0); menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip"; menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1104, 28); menuStrip.Size = new Size(1104, 28);
@@ -59,7 +61,7 @@
// //
// справочникиToolStripMenuItem // справочникиToolStripMenuItem
// //
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, БлюдаToolStripMenuItem, ClientToolStripMenuItem, исполнителиToolStripMenuItem }); справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, БлюдаToolStripMenuItem, ClientToolStripMenuItem, исполнителиToolStripMenuItem, письмаToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem"; справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(117, 24); справочникиToolStripMenuItem.Size = new Size(117, 24);
справочникиToolStripMenuItem.Text = "Справочники"; справочникиToolStripMenuItem.Text = "Справочники";
@@ -67,24 +69,38 @@
// КомпонентыToolStripMenuItem // КомпонентыToolStripMenuItem
// //
КомпонентыToolStripMenuItem.Name = "КомпонентыToolStripMenuItem"; КомпонентыToolStripMenuItem.Name = "КомпонентыToolStripMenuItem";
КомпонентыToolStripMenuItem.Size = new Size(224, 26); КомпонентыToolStripMenuItem.Size = new Size(185, 26);
КомпонентыToolStripMenuItem.Text = "Компоненты"; КомпонентыToolStripMenuItem.Text = "Компоненты";
КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click; КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click;
// //
// БлюдаToolStripMenuItem // БлюдаToolStripMenuItem
// //
БлюдаToolStripMenuItem.Name = "БлюдаToolStripMenuItem"; БлюдаToolStripMenuItem.Name = "БлюдаToolStripMenuItem";
БлюдаToolStripMenuItem.Size = new Size(224, 26); БлюдаToolStripMenuItem.Size = new Size(185, 26);
БлюдаToolStripMenuItem.Text = "Блюда"; БлюдаToolStripMenuItem.Text = "Блюда";
БлюдаToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click; БлюдаToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click;
// //
// ClientToolStripMenuItem // ClientToolStripMenuItem
// //
ClientToolStripMenuItem.Name = "ClientToolStripMenuItem"; ClientToolStripMenuItem.Name = "ClientToolStripMenuItem";
ClientToolStripMenuItem.Size = new Size(224, 26); ClientToolStripMenuItem.Size = new Size(185, 26);
ClientToolStripMenuItem.Text = "Клиенты"; ClientToolStripMenuItem.Text = "Клиенты";
ClientToolStripMenuItem.Click += ClientToolStripMenuItem_Click; ClientToolStripMenuItem.Click += ClientToolStripMenuItem_Click;
// //
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(185, 26);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += ИсполнителиToolStripMenuItem_Click;
//
// письмаToolStripMenuItem
//
письмаToolStripMenuItem.Name = "письмаToolStripMenuItem";
письмаToolStripMenuItem.Size = new Size(185, 26);
письмаToolStripMenuItem.Text = "Письма";
письмаToolStripMenuItem.Click += письмаToolStripMenuItem_Click;
//
// отчётыToolStripMenuItem // отчётыToolStripMenuItem
// //
отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ComponentToolStripMenuItem, ComponentProductsToolStripMenuItem, OrdersToolStripMenuItem }); отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ComponentToolStripMenuItem, ComponentProductsToolStripMenuItem, OrdersToolStripMenuItem });
@@ -161,12 +177,12 @@
ButtonRef.UseVisualStyleBackColor = true; ButtonRef.UseVisualStyleBackColor = true;
ButtonRef.Click += ButtonRef_Click; ButtonRef.Click += ButtonRef_Click;
// //
// исполнителиToolStripMenuItem // создатьБекапToolStripMenuItem
// //
исполнителиToolStripMenuItem.Name = "исполнителиToolStripMenuItem"; создатьБекапToolStripMenuItem.Name = "создатьБекапToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(224, 26); создатьБекапToolStripMenuItem.Size = new Size(123, 24);
исполнителиToolStripMenuItem.Text = "Исполнители"; создатьБекапToolStripMenuItem.Text = "Создать Бекап";
исполнителиToolStripMenuItem.Click += ИсполнителиToolStripMenuItem_Click; создатьБекапToolStripMenuItem.Click += создатьБекапToolStripMenuItem_Click;
// //
// FormMain // FormMain
// //
@@ -206,5 +222,7 @@
private ToolStripMenuItem ClientToolStripMenuItem; private ToolStripMenuItem ClientToolStripMenuItem;
private ToolStripMenuItem запускРаботыToolStripMenuItem; private ToolStripMenuItem запускРаботыToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripMenuItem письмаToolStripMenuItem;
private ToolStripMenuItem создатьБекапToolStripMenuItem;
} }
} }

View File

@@ -1,6 +1,7 @@
using AbstractFoodOrdersBusinessLogic.BusinessLogics; using AbstractFoodOrdersBusinessLogic.BusinessLogics;
using AbstractFoodOrdersContracts.BindingModels; using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts; using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.DI;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -20,13 +21,15 @@ namespace FoodOrders
private readonly IOrderLogic _orderLogic; private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic; private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess; 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(); InitializeComponent();
_logger = logger; _logger = logger;
_orderLogic = orderLogic; _orderLogic = orderLogic;
_reportLogic = reportLogic; _reportLogic = reportLogic;
_workProcess = workProcess; _workProcess = workProcess;
_backUpLogic = backUpLogic;
} }
private void FormMain_Load(object sender, EventArgs e) private void FormMain_Load(object sender, EventArgs e)
{ {
@@ -34,95 +37,33 @@ namespace FoodOrders
} }
private void LoadData() private void LoadData()
{ {
try try
{ {
var list = _orderLogic.ReadList(null); dataGridView.FillAndConfigGrid(_orderLogic.ReadList(null));
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["DishId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов"); _logger.LogInformation("Загрузка заказов");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка загрузки заказов"); _logger.LogError(ex, "Ошибка загрузки изделий");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e) private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = var form = DependencyManager.Instance.Resolve<FormComponents>();
Program.ServiceProvider?.GetService(typeof(FormComponents)); form.ShowDialog();
if (service is FormComponents form)
{
form.ShowDialog();
}
} }
private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e) private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = var form = DependencyManager.Instance.Resolve<FormDishes>();
Program.ServiceProvider?.GetService(typeof(FormDishes)); form.ShowDialog();
if (service is FormDishes form)
{
form.ShowDialog();
}
} }
private void ButtonCreateOrder_Click(object sender, EventArgs e) private void ButtonCreateOrder_Click(object sender, EventArgs e)
{ {
var service = var form = DependencyManager.Instance.Resolve<FormCreateOrder>();
Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); form.ShowDialog();
if (service is FormCreateOrder form) LoadData();
{
form.ShowDialog();
LoadData();
}
}
private void ButtonTakeOrderInWork_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id);
try
{
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonOrderReady_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id);
try
{
var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
} }
private void ButtonIssuedOrder_Click(object sender, EventArgs e) private void ButtonIssuedOrder_Click(object sender, EventArgs e)
{ {
@@ -173,46 +114,62 @@ namespace FoodOrders
private void ComponentProductsToolStripMenuItem_Click(object sender, EventArgs e) private void ComponentProductsToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportDishComponents)); var form = DependencyManager.Instance.Resolve<FormReportDishComponents>();
if (service is FormReportDishComponents form) form.ShowDialog();
{
form.ShowDialog();
}
} }
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e) private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); var form = DependencyManager.Instance.Resolve<FormReportOrders>();
if (service is FormReportOrders form) form.ShowDialog();
{
form.ShowDialog();
}
} }
private void ClientToolStripMenuItem_Click(object sender, EventArgs e) private void ClientToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormClients)); var form = DependencyManager.Instance.Resolve<FormClients>();
if (service is FormClients form) form.ShowDialog();
{
form.ShowDialog();
}
} }
private void ИсполнителиToolStripMenuItem_Click(object sender, EventArgs e) private void ИсполнителиToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); var form = DependencyManager.Instance.Resolve<FormImplementers>();
if (service is FormImplementers form) form.ShowDialog();
{
form.ShowDialog();
}
} }
private void ЗапускРаботыToolStripMenuItem_Click(object sender, EventArgs e) private void ЗапускРаботыToolStripMenuItem_Click(object sender, EventArgs e)
{ {
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); _workProcess.DoWork(DependencyManager.Instance.Resolve<IImplementerLogic>(), _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
MessageBoxButtons.OK, MessageBoxIcon.Information);
} }
private void письмаToolStripMenuItem_Click(object sender, EventArgs e)
{
var form = DependencyManager.Instance.Resolve<FormMails>();
form.ShowDialog();
}
private void создатьБекапToolStripMenuItem_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

@@ -8,6 +8,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
using System.Drawing; using System.Drawing;
using AbstractFoodOrdersBusinessLogic.MailWorker;
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.DI;
namespace FoodOrders namespace FoodOrders
{ {
@@ -24,45 +27,71 @@ namespace FoodOrders
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
var services = new ServiceCollection(); InitDependency();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider(); try
Application.Run(_serviceProvider.GetRequiredService<FormMain>()); {
} var mailSender = DependencyManager.Instance.Resolve<AbstractMailWorker>();
private static void ConfigureServices(ServiceCollection services) mailSender?.MailConfig(new MailConfigBindingModel
{ {
services.AddLogging(option => MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
{ MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
option.SetMinimumLevel(LogLevel.Information); SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
option.AddNLog("nlog.config"); SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
}); PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
services.AddTransient<IComponentStorage, ComponentStorage>(); PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
services.AddTransient<IOrderStorage, OrderStorage>(); });
services.AddTransient<IDishStorage, DishStorage>();
services.AddTransient<IClientStorage, ClientStorage>(); var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 100000);
services.AddTransient<IImplementerStorage, ImplementerStorage>(); }
services.AddTransient<IComponentLogic, ComponentLogic>(); catch (Exception ex)
services.AddTransient<IOrderLogic, OrderLogic>(); {
services.AddTransient<IDishLogic, DishLogic>(); var logger = DependencyManager.Instance.Resolve<ILogger>();
services.AddTransient<IReportLogic, ReportLogic>(); logger?.LogError(ex, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
services.AddTransient<IClientLogic, ClientLogic>(); }
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IWorkProcess, WorkModeling>(); Application.Run(DependencyManager.Instance.Resolve<FormMain>());
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddTransient<FormMain>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
services.AddTransient<FormCreateOrder>();
services.AddTransient<FormDish>();
services.AddTransient<FormDishComponent>();
services.AddTransient<FormDishes>();
services.AddTransient<FormReportDishComponents>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormClients>();
services.AddTransient<FormCreateImplementer>();
services.AddTransient<FormImplementers>();
} }
} private static void InitDependency()
{
DependencyManager.InitDependency();
DependencyManager.Instance.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
DependencyManager.Instance.RegisterType<IComponentLogic, ComponentLogic>();
DependencyManager.Instance.RegisterType<IOrderLogic, OrderLogic>();
DependencyManager.Instance.RegisterType<IDishLogic, DishLogic>();
DependencyManager.Instance.RegisterType<IReportLogic, ReportLogic>();
DependencyManager.Instance.RegisterType<IClientLogic, ClientLogic>();
DependencyManager.Instance.RegisterType<IImplementerLogic, ImplementerLogic>();
DependencyManager.Instance.RegisterType<IMessageInfoLogic, MessageInfoLogic>();
DependencyManager.Instance.RegisterType<AbstractSaveToExcel, SaveToExcel>();
DependencyManager.Instance.RegisterType<AbstractSaveToWord, SaveToWord>();
DependencyManager.Instance.RegisterType<AbstractSaveToPdf, SaveToPdf>();
DependencyManager.Instance.RegisterType<IWorkProcess, WorkModeling>();
DependencyManager.Instance.RegisterType<AbstractMailWorker, MailKitWorker>(true);
DependencyManager.Instance.RegisterType<IBackUpLogic, BackUpLogic>();
DependencyManager.Instance.RegisterType<FormMain>();
DependencyManager.Instance.RegisterType<FormComponent>();
DependencyManager.Instance.RegisterType<FormComponents>();
DependencyManager.Instance.RegisterType<FormCreateOrder>();
DependencyManager.Instance.RegisterType<FormDish>();
DependencyManager.Instance.RegisterType<FormDishes>();
DependencyManager.Instance.RegisterType<FormDishComponent>();
DependencyManager.Instance.RegisterType<FormClients>();
DependencyManager.Instance.RegisterType<FormCreateImplementer>();
DependencyManager.Instance.RegisterType<FormImplementers>();
DependencyManager.Instance.RegisterType<FormReportDishComponents>();
DependencyManager.Instance.RegisterType<FormReportOrders>();
DependencyManager.Instance.RegisterType<FormMails>();
}
private static void MailCheck(object obj) => DependencyManager.Instance.Resolve<AbstractMailWorker>()?.MailCheck();
}
} }