10 Commits

74 changed files with 4479 additions and 726 deletions

View File

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

View File

@@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
@@ -17,7 +18,7 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
@@ -108,11 +109,20 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
{
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
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким логином уже зарегистрирован");

View File

@@ -0,0 +1,126 @@
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 ImplementerLogic:IImplementerLogic
{
private readonly ILogger _logger;
private readonly IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<ImplementerLogic> logger, IImplementerStorage implementerStorage)
{
_logger = logger;
_implementerStorage = implementerStorage;
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}. ImplementerFIO:{ImplementerFIO}. Password:{Password}", model?.Id, model?.ImplementerFIO, model?.Password);
var list = model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ImplementerViewModel? ReadElement(ImplementerSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Id:{Id}. ImplementerFIO:{ImplementerFIO}. Password:{Password}", model.Id, model.ImplementerFIO, model.Password);
var element = _implementerStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ImplementerBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_implementerStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ImplementerBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.ImplementerFIO));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.Password));
}
if (model.WorkExperience < 0)
{
throw new ArgumentNullException("Опыт работы не может быть меньше 0!", nameof(model.WorkExperience));
}
if (model.Qualification < 0)
{
throw new ArgumentNullException("Квалификация не может быть меньше 0!", nameof(model.Qualification));
}
_logger.LogInformation("Implementer. ImplementerFIO:{ImplementerFIO}. Password:{Password}. Id:{Id}", model.ImplementerFIO, model.Password, model.Id);
var element = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = model.ImplementerFIO
});
if (element != null && element.Id != model.Id)
{
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.SearchModels;
using AbstractFoodOrdersContracts.StoragesContracts;
@@ -15,106 +16,150 @@ namespace AbstractFoodOrdersBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. OrderId:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.Count <= 0)
{
throw new ArgumentException("Колличество изделий в заказе не может быть меньше 1", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentException("Стоимость заказа на может быть меньше 1", nameof(model.Sum));
}
if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate)
{
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)
{
CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel()
{
Id = model.Id
});
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
model.DateCreate = element.DateCreate;
model.DishId = element.DishId;
model.DateImplement = element.DateImplement;
model.Status = element.Status;
model.Count = element.Count;
model.Sum = element.Sum;
if (requiredStatus - model.Status == 1)
{
model.Status = requiredStatus;
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 ArgumentException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}");
}
}
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly AbstractMailWorker _mailWorker;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker)
{
_logger = logger;
_orderStorage = orderStorage;
_mailWorker = mailWorker;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ClientId: {ClientId}. ImplementerId: {ImplementerId}. Status: {Status}. DateFrom: {DateFrom}. DateTo: {DateTo}. Id: {Id}",
model.ClientId, model.ImplementerId, model.OrderStatus, model.DateFrom, model.DateTo, model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Order status change failed");
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;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (_locker)
{
return ChangeOrderStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeOrderStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeOrderStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Кол-во изделий в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. Count: {Count}. Sum: {Sum} Id: {Id}", model.Count, model.Sum, model.Id);
}
private bool ChangeOrderStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var orderView = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (orderView == null || newStatus - orderView.Status != 1)
{
_logger.LogWarning("Order status change failed");
return false;
}
model.Status = newStatus;
if (!model.ImplementerId.HasValue)
model.ImplementerId = orderView.ImplementerId;
model.DateImplement = orderView.DateImplement;
if (newStatus == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
}
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,151 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.Enums;
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 WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel { OrderStatus = OrderStatus.Принят });
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
}
_logger.LogDebug("DoWork for {Count} orders", orders?.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
/// <summary>
/// Иммитация работы исполнителя
/// </summary>
/// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel>? orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
if (orders == null || orders.Count == 0)
return;
await Task.Run(async () =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
await Task.Delay(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id
});
// отдыхаем
await Task.Delay(implementer.Qualification * _rnd.Next(10, 100));
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
OrderStatus = OrderStatus.Выполняется
}));
if (runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
await Task.Delay(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@@ -0,0 +1,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.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace AbstractFoodOrdersClientApp.Controllers
@@ -142,5 +143,16 @@ namespace AbstractFoodOrdersClientApp.Controllers
);
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">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

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

View File

@@ -0,0 +1,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,19 @@
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;
}
}

View File

@@ -18,6 +18,7 @@ namespace AbstractFoodOrdersContracts.BindingModels
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; set; } = DateTime.Now;
public DateTime? DateImplement { get; set; }
public int? ImplementerId { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
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 IImplementerLogic
{
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
ImplementerViewModel? ReadElement(ImplementerSearchModel model);
bool Create(ImplementerBindingModel model);
bool Update(ImplementerBindingModel model);
bool Delete(ImplementerBindingModel model);
}
}

View File

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

@@ -12,7 +12,8 @@ namespace AbstractFoodOrdersContracts.BusinessLogicsContracts
public interface IOrderLogic
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
OrderViewModel? ReadElement(OrderSearchModel? model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model);

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
using System;
using AbstractFoodOrdersDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -12,5 +13,7 @@ namespace AbstractFoodOrdersContracts.SearchModels
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public int? ClientId { get; set; }
}
public int? ImplementerId { get; set; }
public OrderStatus? OrderStatus { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
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 IImplementerStorage
{
List<ImplementerViewModel> GetFullList();
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
ImplementerViewModel? GetElement(ImplementerSearchModel model);
ImplementerViewModel? Insert(ImplementerBindingModel model);
ImplementerViewModel? Update(ImplementerBindingModel model);
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

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

@@ -0,0 +1,23 @@
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 ImplementerViewModel:IImplementerModel
{
public int Id { get; set; }
[DisplayName("ФИО")]
public string ImplementerFIO { get; set; } = String.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = String.Empty;
[DisplayName("Опыт работы")]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
public int Qualification { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
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
{
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
[DisplayName("Отправитель")]
public string SenderName { get; set; } = string.Empty;
[DisplayName("Доставлено")]
public DateTime DateDelivery { get; set; }
[DisplayName("Заголовок")]
public string Subject { get; set; } = string.Empty;
[DisplayName("Текст")]
public string Body { get; set; } = string.Empty;
}
}

View File

@@ -16,10 +16,14 @@ namespace AbstractFoodOrdersContracts.ViewModels
public int DishId { get; set; }
[DisplayName("Изделие")]
public string DishName { get; set; } = string.Empty;
public int ClientId { get; set; }
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; }
public int ClientId { get; set; }
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Количество")]
public string ClientEmail { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }

View File

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

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
{
string MessageId { get; }
int? ClientId { get; }
string SenderName { get; }
DateTime DateDelivery { get; }
string Subject { get; }
string Body { get; }
}
}

View File

@@ -16,6 +16,7 @@ namespace AbstractFoodOrdersDataModels.Models
OrderStatus Status { get; }
DateTime DateCreate { get; }
DateTime? DateImplement { get; }
int? ImplementerId { get; }
}
}

View File

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

View File

@@ -0,0 +1,97 @@
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 ImplementerStorage:IImplementerStorage
{
public List<ImplementerViewModel> GetFullList()
{
using var context = new AbstractFoodOrdersDatabase();
return context.Implementers
.Select(x => x.GetViewModel)
.ToList();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.Id.HasValue)
{
return new();
}
if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
{
using var context = new AbstractFoodOrdersDatabase();
return context.Implementers
.Where(x => x.ImplementerFIO.Equals(model.ImplementerFIO))
.Select(x => x.GetViewModel)
.ToList();
}
else
{
using var context = new AbstractFoodOrdersDatabase();
return context.Implementers
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
using var context = new AbstractFoodOrdersDatabase();
if (model.Id.HasValue)
return context.Implementers.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
if (model.ImplementerFIO != null && model.Password != null)
return context.Implementers
.FirstOrDefault(x => x.ImplementerFIO.Equals(model.ImplementerFIO)
&& x.Password.Equals(model.Password))
?.GetViewModel;
if (model.ImplementerFIO != null)
return context.Implementers.FirstOrDefault(x => x.ImplementerFIO.Equals(model.ImplementerFIO))?.GetViewModel;
return null;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
using var context = new AbstractFoodOrdersDatabase();
context.Implementers.Add(newImplementer);
context.SaveChanges();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
using var context = new AbstractFoodOrdersDatabase();
var component = context.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (component == null)
{
return null;
}
component.Update(model);
context.SaveChanges();
return component.GetViewModel;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
using var context = new AbstractFoodOrdersDatabase();
var element = context.Implementers.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Implementers.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
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

@@ -17,20 +17,28 @@ namespace AbstractFoodOrdersDatabaseImplement.Implements
public List<OrderViewModel> GetFullList()
{
using var context = new AbstractFoodOrdersDatabase();
return context.Orders.Include(x => x.Client)
return context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.Select(x => AccessDishStorage(x.GetViewModel, context))
.ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue)
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue && !model.OrderStatus.HasValue)
{
return new();
}
if (model.OrderStatus.HasValue)
{
using var context = new AbstractFoodOrdersDatabase();
return context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.Status == model.OrderStatus)
.Select(x => AccessDishStorage(x.GetViewModel, context))
.ToList();
}
if (model.ClientId.HasValue)
{
using var context = new AbstractFoodOrdersDatabase();
return context.Orders.Include(x => x.Client)
return context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.ClientId == model.ClientId)
.Select(x => AccessDishStorage(x.GetViewModel, context))
.ToList();
@@ -38,7 +46,7 @@ namespace AbstractFoodOrdersDatabaseImplement.Implements
else if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
{
using var context = new AbstractFoodOrdersDatabase();
return context.Orders.Include(x => x.Client)
return context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.Id == model.Id)
.Select(x => AccessDishStorage(x.GetViewModel, context))
.ToList();
@@ -46,7 +54,7 @@ namespace AbstractFoodOrdersDatabaseImplement.Implements
else
{
using var context = new AbstractFoodOrdersDatabase();
return context.Orders.Include(x => x.Client)
return context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => AccessDishStorage(x.GetViewModel, context))
.ToList();
@@ -54,15 +62,25 @@ namespace AbstractFoodOrdersDatabaseImplement.Implements
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
using var context = new AbstractFoodOrdersDatabase();
return AccessDishStorage(context.Orders.Include(x => x.Client)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel, context);
}
if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue)
{
return new();
}
using var context = new AbstractFoodOrdersDatabase();
if (!model.Id.HasValue)
{
return AccessDishStorage(context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue
&& x.Status == model.OrderStatus && x.ImplementerId == model.ImplementerId)
?.GetViewModel, context);
}
else
{
return AccessDishStorage(context.Orders.Include(x => x.Client).Include(x => x.Implementer)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel, context);
}
}
public OrderViewModel? Insert(OrderBindingModel model)
{
using var context = new AbstractFoodOrdersDatabase();
@@ -84,7 +102,7 @@ namespace AbstractFoodOrdersDatabaseImplement.Implements
{
return null;
}
order.Update(model);
order.Update(context, model);
context.SaveChanges();
return AccessDishStorage(order.GetViewModel, context);
}

View File

@@ -0,0 +1,257 @@
// <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("20230514143654_ImplementerUpdate")]
partial class ImplementerUpdate
{
/// <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.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,67 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AbstractFoodOrdersDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class ImplementerUpdate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ImplementerId",
table: "Orders",
type: "int",
nullable: true);
migrationBuilder.CreateTable(
name: "Implementers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
WorkExperience = table.Column<int>(type: "int", nullable: false),
Qualification = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Implementers", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_ImplementerId",
table: "Orders",
column: "ImplementerId");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders",
column: "ImplementerId",
principalTable: "Implementers",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
table: "Orders");
migrationBuilder.DropTable(
name: "Implementers");
migrationBuilder.DropIndex(
name: "IX_Orders_ImplementerId",
table: "Orders");
migrationBuilder.DropColumn(
name: "ImplementerId",
table: "Orders");
}
}
}

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

@@ -113,6 +113,61 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
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")
@@ -136,6 +191,9 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
b.Property<int>("DishId")
.HasColumnType("int");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
@@ -148,6 +206,8 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
b.HasIndex("DishId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
@@ -184,9 +244,15 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
.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 =>
@@ -205,6 +271,11 @@ namespace AbstractFoodOrdersDatabaseImplement.Migrations
b.Navigation("Orders");
});
modelBuilder.Entity("AbstractFoodOrdersDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}

View File

@@ -0,0 +1,63 @@
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;
namespace AbstractFoodOrdersDatabaseImplement.Models
{
public class Implementer:IImplementerModel
{
public int Id { get; private set; }
[Required]
public string ImplementerFIO { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
[Required]
public int WorkExperience { get; set; }
[Required]
public int Qualification { get; set; }
[ForeignKey("ImplementerId")]
public virtual List<Order> Orders { get; set; } = new List<Order>();
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification,
};
}
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification,
};
}
}

View File

@@ -0,0 +1,56 @@
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;
namespace AbstractFoodOrdersDatabaseImplement.Models
{
public class MessageInfo:IMessageInfoModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string MessageId { get; set; } = string.Empty;
public int? ClientId { get; set; }
[Required]
public string SenderName { get; set; } = string.Empty;
[Required]
public DateTime DateDelivery { get; set; }
[Required]
public string Subject { get; set; } = string.Empty;
[Required]
public string Body { get; set; } = string.Empty;
public static MessageInfo? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new MessageInfo()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
Body = model.Body,
Subject = model.Subject,
DateDelivery = model.DateDelivery
};
}
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
Body = Body,
Subject = Subject,
DateDelivery = DateDelivery
};
}
}

View File

@@ -20,7 +20,9 @@ namespace AbstractFoodOrdersDatabaseImplement.Models
[Required]
public int ClientId { get; set; }
public virtual Client Client { get; set; } = new();
[Required]
public int? ImplementerId { get; set; }
public virtual Implementer? Implementer { get; set; } = new();
[Required]
public int Count { get; private set; }
[Required]
public double Sum { get; private set; }
@@ -46,29 +48,36 @@ namespace AbstractFoodOrdersDatabaseImplement.Models
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement
};
DateImplement = model.DateImplement,
ImplementerId = model.ImplementerId,
Implementer = model.ImplementerId.HasValue ? data.Implementers.First(x => x.Id == model.ImplementerId) : null,
};
}
public void Update(OrderBindingModel? model)
public void Update(AbstractFoodOrdersDatabase context, OrderBindingModel? model)
{
if (model == null)
{
return;
}
Status = model.Status;
if (model.DateImplement.HasValue) DateImplement = model.DateImplement;
}
if (model.ImplementerId.HasValue) ImplementerId = model.ImplementerId;
if (model.ImplementerId.HasValue) Implementer = context.Implementers.First(x => x.Id == model.ImplementerId);
if (model.DateImplement.HasValue) DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
DishId = DishId,
ClientId = ClientId,
ClientFIO = Client.ClientFIO,
ClientEmail = Client.Email,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement
};
DateImplement = DateImplement,
ImplementerId = ImplementerId,
ImplementerFIO = Implementer?.ImplementerFIO
};
}
}

View File

@@ -14,13 +14,17 @@ namespace AbstractFoodOrdersListImplement
public List<Order> Orders { get; set; }
public List<Dish> Dishes { get; set; }
public List<Client> Clients { get; set; }
private DataListSingleton()
public List<Implementer> Implementers { get; set; }
public List<MessageInfo> MessageInfos { get; set; }
private DataListSingleton()
{
Components = new List<Component>();
Orders = new List<Order>();
Dishes = new List<Dish>();
Clients = new List<Client>();
}
Implementers = new List<Implementer>();
MessageInfos = new List<MessageInfo>();
}
public static DataListSingleton GetInstance()
{
if (_instance == null)

View File

@@ -0,0 +1,114 @@
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 ImplementerStorage : IImplementerStorage
{
private readonly DataListSingleton _source;
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
var result = new List<ImplementerViewModel>();
foreach (var implementer in _source.Implementers)
{
result.Add(implementer.GetViewModel);
}
return result;
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
var result = new List<ImplementerViewModel>();
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return result;
}
foreach (var implementer in _source.Implementers)
{
if (implementer.ImplementerFIO.Contains(model.ImplementerFIO))
{
result.Add(implementer.GetViewModel);
}
}
return result;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && string.IsNullOrEmpty(model.Password) && !model.Id.HasValue)
{
return null;
}
foreach (var implementer in _source.Implementers)
{
if ((!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password)
&& implementer.ImplementerFIO == model.ImplementerFIO && implementer.Password == model.Password) ||
(model.Id.HasValue && implementer.Id == model.Id))
{
return implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = 1;
foreach (var implementer in _source.Implementers)
{
if (model.Id <= implementer.Id)
{
model.Id = implementer.Id + 1;
}
}
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
_source.Implementers.Add(newImplementer);
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
implementer.Update(model);
return implementer.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
for (int i = 0; i < _source.Implementers.Count; ++i)
{
if (_source.Implementers[i].Id == model.Id)
{
var element = _source.Implementers[i];
_source.Implementers.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

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

@@ -13,118 +13,148 @@ namespace AbstractFoodOrdersListImplement.Implements
{
public class OrderStorage : IOrderStorage
{
private readonly DataListSingleton _source;
public OrderStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
var result = new List<OrderViewModel>();
foreach (var order in _source.Orders)
{
result.Add(AttachReinforcedName(order.GetViewModel));
}
return result;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
var result = new List<OrderViewModel>();
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue)
{
return result;
}
foreach (var order in _source.Orders)
{
if ((order.DateCreate >= model.DateFrom && order.DateCreate <= model.DateTo) || order.ClientId == model.ClientId)
{
result.Add(AttachReinforcedName(order.GetViewModel));
}
}
return result;
private readonly DataListSingleton _source;
public OrderStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
var result = new List<OrderViewModel>();
foreach (var order in _source.Orders)
{
result.Add(AccessDishStorage(order.GetViewModel));
}
return result;
}
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
foreach (var order in _source.Orders)
{
if (model.Id.HasValue && order.Id == model.Id)
{
return AttachReinforcedName(order.GetViewModel);
}
}
return null;
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
var result = new List<OrderViewModel>();
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.OrderStatus.HasValue)
{
return result;
}
if (model.ImplementerId.HasValue && model.OrderStatus.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.Status == model.OrderStatus)
{
result.Add(AccessDishStorage(order.GetViewModel));
}
}
}
else if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.Id == model.Id)
{
result.Add(AccessDishStorage(order.GetViewModel));
}
}
}
else
{
foreach (var order in _source.Orders)
{
if (order.DateCreate >= model.DateFrom && order.DateCreate <= model.DateTo)
{
result.Add(AccessDishStorage(order.GetViewModel));
}
}
}
return result;
}
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.Id = 1;
foreach (var order in _source.Orders)
{
if (model.Id <= order.Id)
{
model.Id = order.Id + 1;
}
}
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
_source.Orders.Add(newOrder);
return AttachReinforcedName(newOrder.GetViewModel);
}
public OrderViewModel? Update(OrderBindingModel model)
{
foreach (var order in _source.Orders)
{
if (order.Id == model.Id)
{
order.Update(model);
return AttachReinforcedName(order.GetViewModel);
}
}
return null;
}
public OrderViewModel? Delete(OrderBindingModel model)
{
for (int i = 0; i < _source.Orders.Count; ++i)
{
if (_source.Orders[i].Id == model.Id)
{
var element = _source.Orders[i];
_source.Orders.RemoveAt(i);
return AttachReinforcedName(element.GetViewModel);
}
}
return null;
}
private OrderViewModel AttachReinforcedName(OrderViewModel model)
{
//Из всех мест, это выглядит наиболее подходящим, для данной манипуляции.
//При расположении ниже нарушится целостность данных
//При расположении выше будет нарушен принцип разделения уровней
foreach (var reinforced in _source.Dishes)
{
if (reinforced.Id == model.DishId)
{
model.DishName = reinforced.DishName;
break;
}
}
foreach (var client in _source.Clients)
{
if (client.Id == model.ClientId)
{
model.ClientFIO = client.ClientFIO;
break;
}
}
return model;
}
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue)
{
return null;
}
if (!model.Id.HasValue)
{
foreach (var order in _source.Orders)
{
if (model.ImplementerId.HasValue && model.OrderStatus.HasValue
&& order.ImplementerId == model.ImplementerId && order.Status == model.OrderStatus)
{
return AccessDishStorage(order.GetViewModel);
}
}
}
else
{
foreach (var order in _source.Orders)
{
if (model.Id.HasValue && order.Id == model.Id)
{
return AccessDishStorage(order.GetViewModel);
}
}
}
return null;
}
public OrderViewModel? Insert(OrderBindingModel model)
{
model.Id = 1;
foreach (var order in _source.Orders)
{
if (model.Id <= order.Id)
{
model.Id = order.Id + 1;
}
}
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
_source.Orders.Add(newOrder);
return AccessDishStorage(newOrder.GetViewModel);
}
public OrderViewModel? Update(OrderBindingModel model)
{
foreach (var order in _source.Orders)
{
if (order.Id == model.Id)
{
order.Update(model);
return AccessDishStorage(order.GetViewModel);
}
}
return null;
}
public OrderViewModel? Delete(OrderBindingModel model)
{
for (int i = 0; i < _source.Orders.Count; ++i)
{
if (_source.Orders[i].Id == model.Id)
{
var element = _source.Orders[i];
_source.Orders.RemoveAt(i);
return AccessDishStorage(element.GetViewModel);
}
}
return null;
}
public OrderViewModel AccessDishStorage(OrderViewModel model)
{
foreach (var pastry in _source.Dishes)
{
if (pastry.Id == model.DishId)
{
model.DishName = pastry.DishName;
break;
}
}
return model;
}
}
}

View File

@@ -0,0 +1,55 @@
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 Implementer:IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification,
};
}
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
}
}

View File

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

@@ -15,7 +15,8 @@ namespace AbstractFoodOrdersListImplement.Models
public int Id { get; private set; }
public int DishId { get; private set; }
public int ClientId { get; private set; }
public int Count { get; private set; }
public int? ImplementerId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; private set; } = DateTime.Now;
@@ -31,6 +32,7 @@ namespace AbstractFoodOrdersListImplement.Models
Id = model.Id,
DishId = model.DishId,
ClientId = model.ClientId,
ImplementerId = model.ImplementerId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@@ -46,6 +48,7 @@ namespace AbstractFoodOrdersListImplement.Models
}
DishId = model.DishId;
ClientId = model.ClientId;
ImplementerId = model.ImplementerId;
Count = model.Count;
Sum = model.Sum;
Status = model.Status;
@@ -57,6 +60,7 @@ namespace AbstractFoodOrdersListImplement.Models
Id = Id,
DishId = DishId,
ClientId = ClientId,
ImplementerId = ImplementerId,
Count = Count,
Sum = Sum,
Status = Status,

View File

@@ -12,11 +12,13 @@ namespace AbstractFoodOrdersRestApi.Controllers
{
private readonly ILogger _logger;
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;
_logic = logic;
_mailLogic = mailLogic;
}
[HttpGet]
public ClientViewModel? Login(string login, string password)
@@ -61,5 +63,22 @@ namespace AbstractFoodOrdersRestApi.Controllers
throw;
}
}
}
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
}
}

View File

@@ -0,0 +1,104 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.SearchModels;
using AbstractFoodOrdersContracts.ViewModels;
using AbstractFoodOrdersDataModels.Enums;
using DocumentFormat.OpenXml.Office2010.Excel;
using Microsoft.AspNetCore.Mvc;
namespace AbstractFoodOrdersRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ImplementerController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IImplementerLogic _logic;
public ImplementerController(IOrderLogic order, IImplementerLogic logic,
ILogger<ImplementerController> logger)
{
_logger = logger;
_order = order;
_logic = logic;
}
[HttpGet]
public ImplementerViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ImplementerSearchModel
{
ImplementerFIO = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка авторизации сотрудника");
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetNewOrders()
{
try
{
return _order.ReadList(new OrderSearchModel
{
OrderStatus = OrderStatus.Принят
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения новых заказов");
throw;
}
}
[HttpGet]
public OrderViewModel? GetImplementerOrder(int implementerId)
{
try
{
return _order.ReadElement(new OrderSearchModel
{
ImplementerId = implementerId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения текущего заказа исполнителя");
throw;
}
}
[HttpPost]
public void TakeOrderInWork(OrderBindingModel model)
{
try
{
_order.TakeOrderInWork(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка перевода заказа с №{Id} в работу",
model.Id);
throw;
}
}
[HttpPost]
public void FinishOrder(OrderBindingModel model)
{
try
{
_order.FinishOrder(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа с №{ Id}", model.Id);
throw;
}
}
}
}

View File

@@ -1,4 +1,6 @@
using AbstractFoodOrdersBusinessLogic.BusinessLogics;
using AbstractFoodOrdersBusinessLogic.MailWorker;
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.StoragesContracts;
using AbstractFoodOrdersDatabaseImplement.Implements;
@@ -13,9 +15,16 @@ builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IDishStorage, DishStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IDishLogic, DishLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddTransient<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers();
// 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 mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty,
MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty,
SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty,
SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()),
PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty,
PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString())
});
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{

View File

@@ -5,5 +5,12 @@
"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

@@ -15,11 +15,15 @@ namespace AbstractFoodOrdersFileImplement
private readonly string OrderFileName = "Order.xml";
private readonly string DishFileName = "Dish.xml";
private readonly string ClientFileName = "Client.xml";
public List<Component> Components { get; private set; }
private readonly string ImplementerFileName = "Implementer.xml";
private readonly string MessageInfoFileName = "MessageInfo.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Dish> Dishes { get; private set; }
public List<Client> Clients { get; private set; }
public static DataFileSingleton GetInstance()
public List<Implementer> Implementers { get; private set; }
public List<MessageInfo> MessageInfos { get; private set; }
public static DataFileSingleton GetInstance()
{
if (instance == null)
{
@@ -31,7 +35,9 @@ namespace AbstractFoodOrdersFileImplement
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);
private DataFileSingleton()
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
public void SaveMessageInfos() => SaveData(MessageInfos, MessageInfoFileName, "MessageInfos", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x =>
Component.Create(x)!)!;
@@ -41,7 +47,9 @@ namespace AbstractFoodOrdersFileImplement
Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x =>
Client.Create(x)!)!;
}
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
MessageInfos = LoadData(MessageInfoFileName, "MessageInfo", x => MessageInfo.Create(x)!)!;
}
private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction)
{

View File

@@ -0,0 +1,86 @@
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 ImplementerStorage:IImplementerStorage
{
private readonly DataFileSingleton source;
public ImplementerStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
return source.Implementers
.Select(x => x.GetViewModel)
.ToList();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return new();
}
return source.Implementers
.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO))
.Select(x => x.GetViewModel)
.ToList();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && string.IsNullOrEmpty(model.Password) && !model.Id.HasValue)
{
return null;
}
return source.Implementers
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password)
&& x.ImplementerFIO == model.ImplementerFIO && x.Password == model.Password) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = source.Implementers.Count > 0 ? source.Implementers.Max(x => x.Id) + 1 : 1;
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
source.Implementers.Add(newImplementer);
source.SaveImplementers();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
var ingredient = source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (ingredient == null)
{
return null;
}
ingredient.Update(model);
source.SaveImplementers();
return ingredient.GetViewModel;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
var element = source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Implementers.Remove(element);
source.SaveImplementers();
return element.GetViewModel;
}
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

@@ -6,6 +6,7 @@ using AbstractFoodOrdersFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -22,90 +23,100 @@ namespace AbstractFoodOrdersFileImplement.Implements
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => GetViewModel(x)).ToList();
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.DateFrom.HasValue || !model.DateTo.HasValue) && !model.ClientId.HasValue)
if (!model.Id.HasValue || !model.DateFrom.HasValue || !model.DateTo.HasValue || !model.OrderStatus.HasValue)
{
return new();
}
if (model.OrderStatus.HasValue)
{
return new();
}
return source.Orders.Where(x => (model.DateFrom.HasValue && model.DateTo.HasValue && x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) ||( x.ClientId == model.ClientId))
.Select(x => GetViewModel(x))
return source.Orders.Where(x => x.ImplementerId == model.ImplementerId)
.Select(x => x.GetViewModel)
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList();
}
}
if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
{
return source.Orders.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList();
}
else
{
return source.Orders.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.Select(y => { y.DishName = source.Dishes.FirstOrDefault(x => x.Id == y?.DishId)?.DishName; return y; }).ToList();
}
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.ClientId.HasValue)
if (!model.Id.HasValue && !model.ImplementerId.HasValue && !model.OrderStatus.HasValue)
{
return null;
}
if (!model.Id.HasValue)
{
return null;
}
return source.Orders.FirstOrDefault(x => x.ClientId == model.ClientId && x.Id == model.Id)?.GetViewModel;
}
return AccessDishStorage(source.Orders
.FirstOrDefault(x => model.ImplementerId.HasValue && model.OrderStatus.HasValue
&& x.ImplementerId == model.ImplementerId && x.Status == model.OrderStatus)
?.GetViewModel);
}
else
{
return AccessDishStorage(source.Orders
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel);
}
}
//для загрузки названий изделия в заказе
private OrderViewModel GetViewModel(Order order)
private OrderViewModel AccessDishStorage(OrderViewModel model)
{
var viewModel = order.GetViewModel;
var manufacture = source.Dishes.FirstOrDefault(x => x.Id == order.DishId);
if (manufacture != null)
{
viewModel.DishName = manufacture.DishName;
}
return viewModel;
}
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;
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
source.Orders.Add(newOrder);
source.SaveOrders();
return GetViewModel(newOrder);
}
model.Id = source.Orders.Count > 0 ? source.Orders.Max(x => x.Id) + 1 : 1;
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
source.Orders.Add(newOrder);
source.SaveOrders();
return AccessDishStorage(newOrder.GetViewModel);
}
public OrderViewModel? Update(OrderBindingModel model)
{
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
source.SaveOrders();
return GetViewModel(order);
}
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
source.SaveOrders();
return AccessDishStorage(order.GetViewModel);
}
public OrderViewModel? Delete(OrderBindingModel model)
{
var element = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Orders.Remove(element);
source.SaveOrders();
return GetViewModel(element);
}
return null;
}
var element = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
source.Orders.Remove(element);
source.SaveOrders();
return AccessDishStorage(element.GetViewModel);
}
return null;
}
}
}

View File

@@ -0,0 +1,80 @@
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;
using System.Xml.Linq;
namespace AbstractFoodOrdersFileImplement.Models
{
public class Implementer:IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification,
};
}
public static Implementer? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Implementer()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ImplementerFIO = element.Attribute("ImplementerFIO")!.Value,
Password = element.Attribute("Password")!.Value,
WorkExperience = Convert.ToInt32(element.Attribute("WorkExperience")!.Value),
Qualification = Convert.ToInt32(element.Attribute("Qualification")!.Value),
};
}
public void Update(ImplementerBindingModel? model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
public XElement GetXElement => new("Implementer",
new XAttribute("Id", Id),
new XElement("ImplementerFIO", ImplementerFIO),
new XElement("Password", Password),
new XElement("WorkExperience", WorkExperience),
new XElement("Qualification", Qualification));
}
}

View File

@@ -0,0 +1,74 @@
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;
using System.Xml.Linq;
namespace AbstractFoodOrdersFileImplement.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 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

@@ -17,7 +17,8 @@ namespace AbstractFoodOrdersFileImplement.Models
public int Id { get; private set; }
public int DishId { get; private set; }
public int ClientId { get; private set; }
public int Count { get; private set; }
public int? ImplementerId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
public DateTime DateCreate { get; private set; } = DateTime.Now;
@@ -38,7 +39,8 @@ namespace AbstractFoodOrdersFileImplement.Models
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement
DateImplement = model.DateImplement,
ImplementerId = model.ImplementerId
};
}
public static Order? Create(XElement element)
@@ -57,8 +59,10 @@ namespace AbstractFoodOrdersFileImplement.Models
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)
};
Convert.ToDateTime(element.Element("DateImplement")!.Value),
ImplementerId = Convert.ToInt32(element.Element("ImplementerId")!.Value),
};
}
public void Update(OrderBindingModel? model)
{
@@ -73,7 +77,8 @@ namespace AbstractFoodOrdersFileImplement.Models
Status = model.Status;
DateCreate = model.DateCreate;
DateImplement = model.DateImplement;
}
ImplementerId = model.ImplementerId;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
@@ -84,12 +89,14 @@ namespace AbstractFoodOrdersFileImplement.Models
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement,
};
ImplementerId = ImplementerId
};
public XElement GetXElement => new("Order",
new XAttribute("Id", Id),
new XElement("DishId", DishId),
new XElement("ClientId", ClientId),
new XElement("Count", Count.ToString()),
new XElement("ImplementerId", ImplementerId.ToString()),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),
new XElement("DateCreate", DateCreate.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,163 @@
namespace FoodOrders
{
partial class FormCreateImplementer
{
/// <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.textBoxWorkExperience = new System.Windows.Forms.TextBox();
this.textBoxFIO = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.labelName = new System.Windows.Forms.Label();
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonSave = new System.Windows.Forms.Button();
this.textBoxPassword = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.textBoxQualification = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// textBoxWorkExperience
//
this.textBoxWorkExperience.Location = new System.Drawing.Point(118, 76);
this.textBoxWorkExperience.Name = "textBoxWorkExperience";
this.textBoxWorkExperience.Size = new System.Drawing.Size(191, 27);
this.textBoxWorkExperience.TabIndex = 11;
//
// textBoxFIO
//
this.textBoxFIO.Location = new System.Drawing.Point(118, 6);
this.textBoxFIO.Name = "textBoxFIO";
this.textBoxFIO.Size = new System.Drawing.Size(330, 27);
this.textBoxFIO.TabIndex = 10;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 79);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(105, 20);
this.label1.TabIndex = 9;
this.label1.Text = "Опыт работы:";
//
// labelName
//
this.labelName.AutoSize = true;
this.labelName.Location = new System.Drawing.Point(64, 6);
this.labelName.Name = "labelName";
this.labelName.Size = new System.Drawing.Size(45, 20);
this.labelName.TabIndex = 8;
this.labelName.Text = "ФИО:";
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(354, 163);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(94, 29);
this.buttonCancel.TabIndex = 7;
this.buttonCancel.Text = "Отмена";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(254, 163);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(94, 29);
this.buttonSave.TabIndex = 6;
this.buttonSave.Text = "Сохранить";
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
//
// textBoxPassword
//
this.textBoxPassword.Location = new System.Drawing.Point(118, 39);
this.textBoxPassword.Name = "textBoxPassword";
this.textBoxPassword.Size = new System.Drawing.Size(330, 27);
this.textBoxPassword.TabIndex = 13;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(44, 42);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(65, 20);
this.label2.TabIndex = 12;
this.label2.Text = "Пароль:";
//
// textBoxQualification
//
this.textBoxQualification.Location = new System.Drawing.Point(118, 109);
this.textBoxQualification.Name = "textBoxQualification";
this.textBoxQualification.Size = new System.Drawing.Size(191, 27);
this.textBoxQualification.TabIndex = 15;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(-2, 112);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(111, 20);
this.label3.TabIndex = 14;
this.label3.Text = "Квалификация";
//
// FormImplementer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(454, 202);
this.Controls.Add(this.textBoxQualification);
this.Controls.Add(this.label3);
this.Controls.Add(this.textBoxPassword);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBoxWorkExperience);
this.Controls.Add(this.textBoxFIO);
this.Controls.Add(this.label1);
this.Controls.Add(this.labelName);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonSave);
this.Name = "FormImplementer";
this.Text = "Исполнитель";
this.Load += new System.EventHandler(this.FormImplementer_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private TextBox textBoxWorkExperience;
private TextBox textBoxFIO;
private Label label1;
private Label labelName;
private Button buttonCancel;
private Button buttonSave;
private TextBox textBoxPassword;
private Label label2;
private TextBox textBoxQualification;
private Label label3;
}
}

View File

@@ -0,0 +1,109 @@
using AbstractFoodOrdersContracts.BindingModels;
using AbstractFoodOrdersContracts.BusinessLogicsContracts;
using AbstractFoodOrdersContracts.SearchModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FoodOrders
{
public partial class FormCreateImplementer : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
private int? _id;
public int Id { set { _id = value; } }
public FormCreateImplementer(ILogger<FormCreateImplementer> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormImplementer_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение исполнителя");
var view = _logic.ReadElement(new ImplementerSearchModel { Id = _id.Value });
if (view != null)
{
textBoxFIO.Text = view.ImplementerFIO;
textBoxPassword.Text = view.Password;
textBoxWorkExperience.Text = view.WorkExperience.ToString();
textBoxQualification.Text = view.Qualification.ToString();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFIO.Text))
{
MessageBox.Show("Заполните ФИО", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxPassword.Text))
{
MessageBox.Show("Заполните пароль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxWorkExperience.Text))
{
MessageBox.Show("Заполните опыт работы", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxQualification.Text))
{
MessageBox.Show("Заполните квалификацию", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение исполнителя");
try
{
var model = new ImplementerBindingModel
{
Id = _id ?? 0,
ImplementerFIO = textBoxFIO.Text,
Password = textBoxPassword.Text,
WorkExperience = Convert.ToInt32(textBoxWorkExperience.Text),
Qualification = Convert.ToInt32(textBoxQualification.Text)
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

View File

@@ -0,0 +1,119 @@
namespace FoodOrders
{
partial class FormImplementers
{
/// <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.buttonRef = new System.Windows.Forms.Button();
this.buttonDel = new System.Windows.Forms.Button();
this.buttonUpd = new System.Windows.Forms.Button();
this.buttonAdd = new System.Windows.Forms.Button();
this.dataGridView = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
this.SuspendLayout();
//
// buttonRef
//
this.buttonRef.Location = new System.Drawing.Point(523, 185);
this.buttonRef.Name = "buttonRef";
this.buttonRef.Size = new System.Drawing.Size(94, 29);
this.buttonRef.TabIndex = 9;
this.buttonRef.Text = "Обновить";
this.buttonRef.UseVisualStyleBackColor = true;
this.buttonRef.Click += new System.EventHandler(this.buttonRef_Click);
//
// buttonDel
//
this.buttonDel.Location = new System.Drawing.Point(523, 127);
this.buttonDel.Name = "buttonDel";
this.buttonDel.Size = new System.Drawing.Size(94, 29);
this.buttonDel.TabIndex = 8;
this.buttonDel.Text = "Удалить";
this.buttonDel.UseVisualStyleBackColor = true;
this.buttonDel.Click += new System.EventHandler(this.buttonDel_Click);
//
// buttonUpd
//
this.buttonUpd.Location = new System.Drawing.Point(523, 70);
this.buttonUpd.Name = "buttonUpd";
this.buttonUpd.Size = new System.Drawing.Size(94, 29);
this.buttonUpd.TabIndex = 7;
this.buttonUpd.Text = "Изменить";
this.buttonUpd.UseVisualStyleBackColor = true;
this.buttonUpd.Click += new System.EventHandler(this.buttonUpd_Click);
//
// buttonAdd
//
this.buttonAdd.Location = new System.Drawing.Point(523, 13);
this.buttonAdd.Name = "buttonAdd";
this.buttonAdd.Size = new System.Drawing.Size(94, 29);
this.buttonAdd.TabIndex = 6;
this.buttonAdd.Text = "Добавить";
this.buttonAdd.UseVisualStyleBackColor = true;
this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
//
// dataGridView
//
this.dataGridView.BackgroundColor = System.Drawing.Color.White;
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView.Location = new System.Drawing.Point(1, 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(489, 449);
this.dataGridView.TabIndex = 5;
//
// FormImplementers
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(628, 450);
this.Controls.Add(this.buttonRef);
this.Controls.Add(this.buttonDel);
this.Controls.Add(this.buttonUpd);
this.Controls.Add(this.buttonAdd);
this.Controls.Add(this.dataGridView);
this.Name = "FormImplementers";
this.Text = "Исполнители";
this.Load += new System.EventHandler(this.FormImplementers_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
this.ResumeLayout(false);
}
#endregion
private Button buttonRef;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@@ -0,0 +1,110 @@
using AbstractFoodOrdersContracts.BindingModels;
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 FormImplementers : Form
{
private readonly ILogger _logger;
private readonly IImplementerLogic _logic;
public FormImplementers(ILogger<FormImplementers> logger, IImplementerLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormImplementers_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка исполнителей");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки исполнителей");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer));
if (service is FormCreateImplementer form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void buttonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateImplementer));
if (service is FormCreateImplementer form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление исполнителя");
try
{
if (!_logic.Delete(new ImplementerBindingModel { Id = id }))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления исполнителя");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@@ -0,0 +1,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,47 @@
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
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["MessageId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_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

@@ -1,218 +1,219 @@
namespace FoodOrders
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <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
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
КомпонентыToolStripMenuItem = new ToolStripMenuItem();
БлюдаToolStripMenuItem = new ToolStripMenuItem();
отчётыToolStripMenuItem = new ToolStripMenuItem();
ComponentToolStripMenuItem = new ToolStripMenuItem();
ComponentProductsToolStripMenuItem = new ToolStripMenuItem();
OrdersToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
ButtonCreateOrder = new Button();
ButtonTakeOrderInWork = new Button();
ButtonOrderReady = new Button();
ButtonIssuedOrder = new Button();
ButtonRef = new Button();
ClientToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1104, 28);
menuStrip.TabIndex = 0;
menuStrip.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, БлюдаToolStripMenuItem, ClientToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(117, 24);
справочникиToolStripMenuItem.Text = "Справочники";
//
// КомпонентыToolStripMenuItem
//
КомпонентыToolStripMenuItem.Name = "КомпонентыToolStripMenuItem";
КомпонентыToolStripMenuItem.Size = new Size(224, 26);
КомпонентыToolStripMenuItem.Text = "Компоненты";
КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click;
//
// БлюдаToolStripMenuItem
//
БлюдаToolStripMenuItem.Name = "БлюдаToolStripMenuItem";
БлюдаToolStripMenuItem.Size = new Size(224, 26);
БлюдаToolStripMenuItem.Text = "Блюда";
БлюдаToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click;
//
// отчётыToolStripMenuItem
//
отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ComponentToolStripMenuItem, ComponentProductsToolStripMenuItem, OrdersToolStripMenuItem });
отчётыToolStripMenuItem.Name = "отчётыToolStripMenuItem";
отчётыToolStripMenuItem.Size = new Size(73, 24);
отчётыToolStripMenuItem.Text = "Отчёты";
//
// ComponentToolStripMenuItem
//
ComponentToolStripMenuItem.Name = "ComponentToolStripMenuItem";
ComponentToolStripMenuItem.Size = new Size(264, 26);
ComponentToolStripMenuItem.Text = "Список блюд";
ComponentToolStripMenuItem.Click += ComponentToolStripMenuItem_Click;
//
// ComponentProductsToolStripMenuItem
//
ComponentProductsToolStripMenuItem.Name = "ComponentProductsToolStripMenuItem";
ComponentProductsToolStripMenuItem.Size = new Size(264, 26);
ComponentProductsToolStripMenuItem.Text = "Компоненты по блюдам";
ComponentProductsToolStripMenuItem.Click += ComponentProductsToolStripMenuItem_Click;
//
// OrdersToolStripMenuItem
//
OrdersToolStripMenuItem.Name = "OrdersToolStripMenuItem";
OrdersToolStripMenuItem.Size = new Size(264, 26);
OrdersToolStripMenuItem.Text = "Список заказов";
OrdersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = SystemColors.ControlLightLight;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 40);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(798, 408);
dataGridView.TabIndex = 1;
//
// ButtonCreateOrder
//
ButtonCreateOrder.Location = new Point(831, 82);
ButtonCreateOrder.Name = "ButtonCreateOrder";
ButtonCreateOrder.Size = new Size(241, 29);
ButtonCreateOrder.TabIndex = 2;
ButtonCreateOrder.Text = "Создать заказ";
ButtonCreateOrder.UseVisualStyleBackColor = true;
ButtonCreateOrder.Click += ButtonCreateOrder_Click;
//
// ButtonTakeOrderInWork
//
ButtonTakeOrderInWork.Location = new Point(831, 141);
ButtonTakeOrderInWork.Name = "ButtonTakeOrderInWork";
ButtonTakeOrderInWork.Size = new Size(241, 29);
ButtonTakeOrderInWork.TabIndex = 3;
ButtonTakeOrderInWork.Text = "Отдать заказ на выполнение";
ButtonTakeOrderInWork.UseVisualStyleBackColor = true;
ButtonTakeOrderInWork.Click += ButtonTakeOrderInWork_Click;
//
// ButtonOrderReady
//
ButtonOrderReady.Location = new Point(831, 202);
ButtonOrderReady.Name = "ButtonOrderReady";
ButtonOrderReady.Size = new Size(241, 29);
ButtonOrderReady.TabIndex = 4;
ButtonOrderReady.Text = "Заказ готов";
ButtonOrderReady.UseVisualStyleBackColor = true;
ButtonOrderReady.Click += ButtonOrderReady_Click;
//
// ButtonIssuedOrder
//
ButtonIssuedOrder.Location = new Point(831, 264);
ButtonIssuedOrder.Name = "ButtonIssuedOrder";
ButtonIssuedOrder.Size = new Size(241, 29);
ButtonIssuedOrder.TabIndex = 5;
ButtonIssuedOrder.Text = "Заказ выдан";
ButtonIssuedOrder.UseVisualStyleBackColor = true;
ButtonIssuedOrder.Click += ButtonIssuedOrder_Click;
//
// ButtonRef
//
ButtonRef.Location = new Point(831, 331);
ButtonRef.Name = "ButtonRef";
ButtonRef.Size = new Size(241, 29);
ButtonRef.TabIndex = 6;
ButtonRef.Text = "Обновить список";
ButtonRef.UseVisualStyleBackColor = true;
ButtonRef.Click += ButtonRef_Click;
//
// ClientToolStripMenuItem
//
ClientToolStripMenuItem.Name = "ClientToolStripMenuItem";
ClientToolStripMenuItem.Size = new Size(224, 26);
ClientToolStripMenuItem.Text = "Клиенты";
ClientToolStripMenuItem.Click += ClientToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1104, 470);
Controls.Add(ButtonRef);
Controls.Add(ButtonIssuedOrder);
Controls.Add(ButtonOrderReady);
Controls.Add(ButtonTakeOrderInWork);
Controls.Add(ButtonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Доставка еды";
Load += FormMain_Load;
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
КомпонентыToolStripMenuItem = new ToolStripMenuItem();
БлюдаToolStripMenuItem = new ToolStripMenuItem();
ClientToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
отчётыToolStripMenuItem = new ToolStripMenuItem();
ComponentToolStripMenuItem = new ToolStripMenuItem();
ComponentProductsToolStripMenuItem = new ToolStripMenuItem();
OrdersToolStripMenuItem = new ToolStripMenuItem();
запускРаботыToolStripMenuItem = new ToolStripMenuItem();
dataGridView = new DataGridView();
ButtonCreateOrder = new Button();
ButtonIssuedOrder = new Button();
ButtonRef = new Button();
письмаToolStripMenuItem = new ToolStripMenuItem();
menuStrip.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчётыToolStripMenuItem, запускРаботыToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1104, 28);
menuStrip.TabIndex = 0;
menuStrip.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, БлюдаToolStripMenuItem, ClientToolStripMenuItem, исполнителиToolStripMenuItem, письмаToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(117, 24);
справочникиToolStripMenuItem.Text = "Справочники";
//
// КомпонентыToolStripMenuItem
//
КомпонентыToolStripMenuItem.Name = "КомпонентыToolStripMenuItem";
КомпонентыToolStripMenuItem.Size = new Size(224, 26);
КомпонентыToolStripMenuItem.Text = "Компоненты";
КомпонентыToolStripMenuItem.Click += КомпонентыToolStripMenuItem_Click;
//
// БлюдаToolStripMenuItem
//
БлюдаToolStripMenuItem.Name = "БлюдаToolStripMenuItem";
БлюдаToolStripMenuItem.Size = new Size(224, 26);
БлюдаToolStripMenuItem.Text = "Блюда";
БлюдаToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click;
//
// ClientToolStripMenuItem
//
ClientToolStripMenuItem.Name = "ClientToolStripMenuItem";
ClientToolStripMenuItem.Size = new Size(224, 26);
ClientToolStripMenuItem.Text = "Клиенты";
ClientToolStripMenuItem.Click += ClientToolStripMenuItem_Click;
//
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(224, 26);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += ИсполнителиToolStripMenuItem_Click;
//
// отчётыToolStripMenuItem
//
отчётыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ComponentToolStripMenuItem, ComponentProductsToolStripMenuItem, OrdersToolStripMenuItem });
отчётыToolStripMenuItem.Name = "отчётыToolStripMenuItem";
отчётыToolStripMenuItem.Size = new Size(73, 24);
отчётыToolStripMenuItem.Text = "Отчёты";
//
// ComponentToolStripMenuItem
//
ComponentToolStripMenuItem.Name = "ComponentToolStripMenuItem";
ComponentToolStripMenuItem.Size = new Size(264, 26);
ComponentToolStripMenuItem.Text = "Список блюд";
ComponentToolStripMenuItem.Click += ComponentToolStripMenuItem_Click;
//
// ComponentProductsToolStripMenuItem
//
ComponentProductsToolStripMenuItem.Name = "ComponentProductsToolStripMenuItem";
ComponentProductsToolStripMenuItem.Size = new Size(264, 26);
ComponentProductsToolStripMenuItem.Text = "Компоненты по блюдам";
ComponentProductsToolStripMenuItem.Click += ComponentProductsToolStripMenuItem_Click;
//
// OrdersToolStripMenuItem
//
OrdersToolStripMenuItem.Name = "OrdersToolStripMenuItem";
OrdersToolStripMenuItem.Size = new Size(264, 26);
OrdersToolStripMenuItem.Text = "Список заказов";
OrdersToolStripMenuItem.Click += OrdersToolStripMenuItem_Click;
//
// запускРаботыToolStripMenuItem
//
запускРаботыToolStripMenuItem.Name = "запускРаботыToolStripMenuItem";
запускРаботыToolStripMenuItem.Size = new Size(125, 24);
запускРаботыToolStripMenuItem.Text = "Запуск работы";
запускРаботыToolStripMenuItem.Click += ЗапускРаботыToolStripMenuItem_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = SystemColors.ControlLightLight;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(0, 40);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(798, 408);
dataGridView.TabIndex = 1;
//
// ButtonCreateOrder
//
ButtonCreateOrder.Location = new Point(831, 82);
ButtonCreateOrder.Name = "ButtonCreateOrder";
ButtonCreateOrder.Size = new Size(241, 29);
ButtonCreateOrder.TabIndex = 2;
ButtonCreateOrder.Text = "Создать заказ";
ButtonCreateOrder.UseVisualStyleBackColor = true;
ButtonCreateOrder.Click += ButtonCreateOrder_Click;
//
// ButtonIssuedOrder
//
ButtonIssuedOrder.Location = new Point(831, 148);
ButtonIssuedOrder.Name = "ButtonIssuedOrder";
ButtonIssuedOrder.Size = new Size(241, 29);
ButtonIssuedOrder.TabIndex = 5;
ButtonIssuedOrder.Text = "Заказ выдан";
ButtonIssuedOrder.UseVisualStyleBackColor = true;
ButtonIssuedOrder.Click += ButtonIssuedOrder_Click;
//
// ButtonRef
//
ButtonRef.Location = new Point(831, 223);
ButtonRef.Name = "ButtonRef";
ButtonRef.Size = new Size(241, 29);
ButtonRef.TabIndex = 6;
ButtonRef.Text = "Обновить список";
ButtonRef.UseVisualStyleBackColor = true;
ButtonRef.Click += ButtonRef_Click;
//
// письмаToolStripMenuItem
//
письмаToolStripMenuItem.Name = "письмаToolStripMenuItem";
письмаToolStripMenuItem.Size = new Size(224, 26);
письмаToolStripMenuItem.Text = "Письма";
письмаToolStripMenuItem.Click += письмаToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1104, 470);
Controls.Add(ButtonRef);
Controls.Add(ButtonIssuedOrder);
Controls.Add(ButtonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Доставка еды";
Load += FormMain_Load;
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem КомпонентыToolStripMenuItem;
private ToolStripMenuItem БлюдаToolStripMenuItem;
private DataGridView dataGridView;
private Button ButtonCreateOrder;
private Button ButtonTakeOrderInWork;
private Button ButtonOrderReady;
private Button ButtonIssuedOrder;
private Button ButtonRef;
private ToolStripMenuItem отчётыToolStripMenuItem;
private ToolStripMenuItem ComponentToolStripMenuItem;
private ToolStripMenuItem ComponentProductsToolStripMenuItem;
private ToolStripMenuItem OrdersToolStripMenuItem;
private ToolStripMenuItem ClientToolStripMenuItem;
}
private MenuStrip menuStrip;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem КомпонентыToolStripMenuItem;
private ToolStripMenuItem БлюдаToolStripMenuItem;
private DataGridView dataGridView;
private Button ButtonCreateOrder;
private Button ButtonIssuedOrder;
private Button ButtonRef;
private ToolStripMenuItem отчётыToolStripMenuItem;
private ToolStripMenuItem ComponentToolStripMenuItem;
private ToolStripMenuItem ComponentProductsToolStripMenuItem;
private ToolStripMenuItem OrdersToolStripMenuItem;
private ToolStripMenuItem ClientToolStripMenuItem;
private ToolStripMenuItem запускРаботыToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripMenuItem письмаToolStripMenuItem;
}
}

View File

@@ -14,194 +14,213 @@ using System.Windows.Forms;
namespace FoodOrders
{
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["DishId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormDishes));
if (service is FormDishes form)
{
form.ShowDialog();
}
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void 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)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'",
id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new
OrderBindingModel
{ Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
public partial class FormMain : Form
{
private readonly ILogger _logger;
private readonly IOrderLogic _orderLogic;
private readonly IReportLogic _reportLogic;
private readonly IWorkProcess _workProcess;
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["DishId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
dataGridView.Columns["ClientEmail"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormDishes));
if (service is FormDishes form)
{
form.ShowDialog();
}
}
private void ButtonCreateOrder_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
private void 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)
{
if (dataGridView.SelectedRows.Count == 1)
{
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'",
id);
try
{
var operationResult = _orderLogic.DeliveryOrder(new
OrderBindingModel
{ Id = id });
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдачи заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void ComponentToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveComponentsToWordFile(new ReportBindingModel
{
FileName = dialog.FileName
});
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
private void ComponentToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveComponentsToWordFile(new ReportBindingModel
{
FileName = dialog.FileName
});
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
private void ComponentProductsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportDishComponents));
if (service is FormReportDishComponents form)
{
form.ShowDialog();
}
}
private void ComponentProductsToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportDishComponents));
if (service is FormReportDishComponents form)
{
form.ShowDialog();
}
}
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
private void OrdersToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
}
private void ClientToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
}
private void ClientToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
private void ИсполнителиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
private void ЗапускРаботыToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void письмаToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMails));
if (service is FormMails form)
{
form.ShowDialog();
}
}
}
}

View File

@@ -8,6 +8,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System.Drawing;
using AbstractFoodOrdersBusinessLogic.MailWorker;
using AbstractFoodOrdersContracts.BindingModels;
namespace FoodOrders
{
@@ -27,7 +29,36 @@ namespace FoodOrders
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
try
{
var mailSender =
_serviceProvider.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin =
System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword =
System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost =
System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort =
Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost =
System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort =
Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
var timer = new System.Threading.Timer(new
TimerCallback(MailCheck!), null, 0, 10000);
}
catch (Exception ex)
{
var logger = _serviceProvider.GetService<ILogger>();
logger?.LogError(ex, "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
@@ -40,14 +71,24 @@ namespace FoodOrders
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IDishStorage, DishStorage>();
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IMessageInfoStorage,MessageInfoStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IDishLogic, DishLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
services.AddTransient<FormMain>();
services.AddTransient<FormComponent>();
services.AddTransient<FormComponents>();
@@ -58,6 +99,10 @@ namespace FoodOrders
services.AddTransient<FormReportDishComponents>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormClients>();
}
}
services.AddTransient<FormCreateImplementer>();
services.AddTransient<FormImplementers>();
services.AddTransient<FormMails>();
}
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
}
}