From 53c43da5a91ec6a67bd7577428ee07b30b0d37b7 Mon Sep 17 00:00:00 2001 From: ValAn Date: Thu, 20 Jun 2024 13:33:14 +0400 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/OrderLogic.cs | 194 --------- .../MailWorker/AbstractMailWorker.cs | 174 +++++--- .../MailWorker/MailKitWorker.cs | 145 ++++--- .../MessageInfoLogic.cs | 54 ++- SushiBar/SushiBarBusinessLogic_/OrderLogic.cs | 157 ++++--- SushiBar/SushiBarClientApp/APIClient.cs | 4 +- .../Controllers/HomeController.cs | 202 ++------- .../SushiBarClientApp/Views/Home/Index.cshtml | 117 +++--- .../SushiBarClientApp/Views/Home/Mails.cshtml | 73 ++-- .../Views/Shared/_Layout.cshtml | 6 +- .../MailReplySendInfoBindingModel.cs | 13 + .../BindingModels/MessageInfoBindingModel.cs | 3 + .../IMessageInfoLogic.cs | 2 + .../SearchModels/MessageInfoSearchModel.cs | 2 + .../StoragesContracts/IMessageInfoStorage.cs | 1 + .../ViewModels/MessageInfoViewModel.cs | 9 + .../Models/IMessageInfoModel.cs | 17 +- .../Implements/MessageInfoStorage.cs | 108 +++-- .../20240620075442_InitCreate.Designer.cs | 392 ++++++++++++++++++ .../Migrations/20240620075442_InitCreate.cs | 286 +++++++++++++ .../SushiBarDatabaseModelSnapshot.cs | 17 + .../Models/MessageInfo.cs | 115 +++-- .../Implements/MessageInfoStorage.cs | 95 +++-- .../Models/MessageInfo.cs | 139 ++++--- .../Implements/MessageInfoStorage.cs | 127 +++--- .../Models/MessageInfo.cs | 85 ++-- .../Controllers/ClientController.cs | 154 +++---- SushiBar/SushiBarView/FormLetter.Designer.cs | 182 ++++++++ SushiBar/SushiBarView/FormLetter.cs | 152 +++++++ SushiBar/SushiBarView/FormLetter.resx | 120 ++++++ SushiBar/SushiBarView/FormMail.Designer.cs | 74 +++- SushiBar/SushiBarView/FormMail.cs | 65 ++- SushiBar/SushiBarView/FormMain.cs | 7 +- SushiBar/SushiBarView/Program.cs | 3 +- 34 files changed, 2293 insertions(+), 1001 deletions(-) delete mode 100644 SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs create mode 100644 SushiBar/SushiBarContracts/BindingModels/MailReplySendInfoBindingModel.cs create mode 100644 SushiBar/SushiBarDatabaseImplement/Migrations/20240620075442_InitCreate.Designer.cs create mode 100644 SushiBar/SushiBarDatabaseImplement/Migrations/20240620075442_InitCreate.cs create mode 100644 SushiBar/SushiBarView/FormLetter.Designer.cs create mode 100644 SushiBar/SushiBarView/FormLetter.cs create mode 100644 SushiBar/SushiBarView/FormLetter.resx diff --git a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs b/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs deleted file mode 100644 index e99a7c9..0000000 --- a/SushiBar/SushiBarBusinessLogic_/BusinessLogics/OrderLogic.cs +++ /dev/null @@ -1,194 +0,0 @@ -using Microsoft.Extensions.Logging; -using SushiBarContracts.BindingModels; -using SushiBarContracts.BusinessLogicsContracts; -using SushiBarContracts.SearchModels; -using SushiBarContracts.StoragesContracts; -using SushiBarContracts.ViewModels; -using SushiBarDataModels.Enums; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SushiBarBusinessLogic.BusinessLogics -{ - public class OrderLogic : IOrderLogic - { - - private readonly ILogger _logger; - private readonly IOrderStorage _orderStorage; - static readonly object _locker = new object(); - private readonly IShopStorage _shopStorage; - - public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage) - { - _logger = logger; - _orderStorage = orderStorage; - _shopStorage = shopStorage; - } - - public OrderViewModel? ReadElement(OrderSearchModel model) - { - if (model == null) - { - throw new ArgumentNullException(nameof(model)); - } - _logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", - model.ClientId, model.Status, model.ImplementerId, 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 List? ReadList(OrderSearchModel? model) - { - _logger.LogInformation("ReadList. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", - model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, 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) - { - lock (_locker) - { - return ChangeStatus(model, OrderStatus.Выполняется); - } - } - - public bool FinishOrder(OrderBindingModel model) - { - return ChangeStatus(model, OrderStatus.Готов); - } - - public bool DeliveryOrder(OrderBindingModel model) - { - lock (_locker) - { - model = FillOrderBindingModel(model); - if (model.Status != OrderStatus.Готов && model.Status != OrderStatus.Ожидает) - { - _logger.LogWarning("Changing status operation faled: Current-{Status}:required-Выдан.", model.Status); - throw new InvalidOperationException($"Невозможно приствоить статус выдан заказу с текущим статусом {model.Status}"); - } - if (!_shopStorage.RestockingShops(new SupplyBindingModel - { - SushiId = model.SushiId, - Count = model.Count - })) - { - if (model.Status == OrderStatus.Готов || model.Status == OrderStatus.Ожидает) - { - model.Status = OrderStatus.Ожидает; - return UpdateOrder(model); - } - } - model.Status = OrderStatus.Выдан; - return UpdateOrder(model); - } - } - - 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("Sushi. SushiId:{SushiId}.Count:{Count}.Sum:{Sum}Id:{Id}", - model.SushiId, model.Count, model.Sum, model.Id); - } - private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus) - { - model = FillOrderBindingModel(model); - - if (requiredStatus - model.Status == 1) - { - model.Status = requiredStatus; - if (model.Status == OrderStatus.Готов) - model.DateImplement = DateTime.Now; - return UpdateOrder(model); - } - _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); - throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); - } - - private OrderBindingModel FillOrderBindingModel(OrderBindingModel model) - { - CheckModel(model, false); - var element = _orderStorage.GetElement(new OrderSearchModel() - { - Id = model.Id - }); - if (element == null) - { - throw new InvalidOperationException(nameof(element)); - } - model.Id = element.Id; - model.DateCreate = element.DateCreate; - model.SushiId = element.SushiId; - model.DateImplement = element.DateImplement; - model.ClientId = element.ClientId; - model.Status = element.Status; - model.Count = element.Count; - model.Sum = element.Sum; - if (!model.ImplementerId.HasValue) - { - model.ImplementerId = element.ImplementerId; - } - return model; - } - - private bool UpdateOrder(OrderBindingModel model) - { - if (_orderStorage.Update(model) == null) - { - _logger.LogWarning("Update operation failed"); - return false; - } - _logger.LogWarning("Update operation sucsess"); - return true; - } - } - } diff --git a/SushiBar/SushiBarBusinessLogic_/MailWorker/AbstractMailWorker.cs b/SushiBar/SushiBarBusinessLogic_/MailWorker/AbstractMailWorker.cs index b0d6a54..33d0a68 100644 --- a/SushiBar/SushiBarBusinessLogic_/MailWorker/AbstractMailWorker.cs +++ b/SushiBar/SushiBarBusinessLogic_/MailWorker/AbstractMailWorker.cs @@ -15,75 +15,119 @@ namespace SushiBarBusinessLogic.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; + 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 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.Length, _smtpClientHost, _smtpClientPort, _popHost, _popPort); - } - public async void MailSendAsync(MailSendInfoBindingModel info) - { - if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) - { - return; - } + public AbstractMailWorker(ILogger 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.Length, _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(_smtpClientHost) || _smtpClientPort == 0) + { + return; + } - if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text)) - { - 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; - } + _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 (string.IsNullOrEmpty(_popHost) || _popPort == 0) + { + return; + } - if (_messageInfoLogic == null) - { - 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> ReceiveMailAsync(); - } -} + var list = await ReceiveMailAsync(); + _logger.LogDebug("Check Mail: {Count} new mails", list.Count); + foreach (var mail in list) + { + _messageInfoLogic.Create(mail); + } + } + + public async void MailSendReplyAsync(MailReplySendInfoBindingModel 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) || string.IsNullOrEmpty(info.ParentMessageId)) + { + return; + } + + _logger.LogDebug("Send Mail as reply: {To}, {Subject}, {parentId}", info.MailAddress, info.Subject, info.ParentMessageId); + + string? messageId = await SendMailAsync(info); + if (string.IsNullOrEmpty(messageId)) + { + throw new InvalidOperationException("Непредвиденная ошибка при отправке сообщения в ответ"); + } + if (_messageInfoLogic.Create(new MessageInfoBindingModel + { + MessageId = messageId, + DateDelivery = DateTime.Now, + SenderName = _mailLogin, + IsReply = true, + Subject = info.Subject, + Body = info.Text, + })) + { + _messageInfoLogic.Update(new MessageInfoBindingModel() + { + MessageId = info.ParentMessageId, + ReplyMessageId = messageId, + IsReaded = true + }); + } + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + protected abstract Task> ReceiveMailAsync(); + } +} \ No newline at end of file diff --git a/SushiBar/SushiBarBusinessLogic_/MailWorker/MailKitWorker.cs b/SushiBar/SushiBarBusinessLogic_/MailWorker/MailKitWorker.cs index b86598b..bcf30e4 100644 --- a/SushiBar/SushiBarBusinessLogic_/MailWorker/MailKitWorker.cs +++ b/SushiBar/SushiBarBusinessLogic_/MailWorker/MailKitWorker.cs @@ -15,69 +15,90 @@ namespace SushiBarBusinessLogic.MailWorker { public class MailKitWorker : AbstractMailWorker { - public MailKitWorker(ILogger logger, IMessageInfoLogic messageInfoLogic) : base(logger, messageInfoLogic) { } + public MailKitWorker(ILogger 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; - + protected override async Task SendMailAsync(MailSendInfoBindingModel info) + { + string? resount = null; + using var objMailMessage = new MailMessage(); + using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort); + try + { + ConfigurateSmtpClient(objSmtpClient); + CreateMessage(objMailMessage, info); - objSmtpClient.UseDefaultCredentials = false; - objSmtpClient.EnableSsl = true; - objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; - objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword); + if (info is MailReplySendInfoBindingModel replyInfo) + { + objMailMessage.Headers.Add("In-Reply-To", replyInfo.ParentMessageId); + objMailMessage.Headers.Add("References", replyInfo.ParentMessageId); - await Task.Run(() => objSmtpClient.Send(objMailMessage)); - } - catch (Exception) - { - throw; - } - } + string messageGuid = Guid.NewGuid().ToString(); + objMailMessage.Headers.Add("Message-Id", messageGuid); + resount = messageGuid; + } - protected override async Task> ReceiveMailAsync() - { - var list = new List(); - 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 (MailKit.Security.AuthenticationException) - { } - finally - { - client.Disconnect(true); - } - }); - return list; - } - } -} + await Task.Run(() => objSmtpClient.Send(objMailMessage)); + } + catch (Exception) + { + throw; + } + return resount; + } + + protected override async Task> ReceiveMailAsync() + { + var list = new List(); + 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 (MailKit.Security.AuthenticationException) + { } + finally + { + client.Disconnect(true); + } + }); + return list; + } + + private void CreateMessage(MailMessage objMailMessage, MailSendInfoBindingModel info) + { + 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; + } + + private void ConfigurateSmtpClient(SmtpClient objSmtpClient) + { + + objSmtpClient.UseDefaultCredentials = false; + objSmtpClient.EnableSsl = true; + objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; + objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword); + } + } +} \ No newline at end of file diff --git a/SushiBar/SushiBarBusinessLogic_/MessageInfoLogic.cs b/SushiBar/SushiBarBusinessLogic_/MessageInfoLogic.cs index 5a3a4d0..749cc4a 100644 --- a/SushiBar/SushiBarBusinessLogic_/MessageInfoLogic.cs +++ b/SushiBar/SushiBarBusinessLogic_/MessageInfoLogic.cs @@ -28,8 +28,12 @@ namespace SushiBarBusinessLogic } public List? ReadList(MessageInfoSearchModel? model) { - _logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId}", model?.MessageId, model?.ClientId); - var list = model == null ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(model); + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId}.PageLength:{PageLength}.PageCount:{PageIndex}", model?.MessageId, model?.ClientId, model?.PageLength, model?.PageIndex); + var list = _messageInfoStorage.GetFilteredList(model); if (list == null) { _logger.LogWarning("ReadList return null list"); @@ -41,7 +45,8 @@ namespace SushiBarBusinessLogic public bool Create(MessageInfoBindingModel model) { CheckModel(model); - if (_messageInfoStorage.Insert(model) == null) + var message = _messageInfoStorage.Insert(model); + if (message == null) { _logger.LogWarning("Insert operation failed"); return false; @@ -54,27 +59,26 @@ namespace SushiBarBusinessLogic { throw new ArgumentNullException(nameof(model)); } - if (!withParams) - { - return; - } if (string.IsNullOrEmpty(model.MessageId)) { throw new ArgumentNullException("Не указан id сообщения", nameof(model.MessageId)); } + if (!withParams) + { + return; + } if (string.IsNullOrEmpty(model.SenderName)) { - throw new ArgumentNullException("Не указао почта", nameof(model.SenderName)); + throw new ArgumentNullException("Не указао имя отправителя(электронная почта)", nameof(model.SenderName)); } if (string.IsNullOrEmpty(model.Subject)) { - throw new ArgumentNullException("Не указана тема", nameof(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); var element = _clientStorage.GetElement(new ClientSearchModel { @@ -89,5 +93,33 @@ namespace SushiBarBusinessLogic model.ClientId = element.Id; } } + + public MessageInfoViewModel? ReadElement(MessageInfoSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. MessageId:{MessageId}", model?.MessageId); + var element = _messageInfoStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.MessageId); + return element; + } + + public bool Update(MessageInfoBindingModel model) + { + CheckModel(model, withParams: false); + if (_messageInfoStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } } -} +} \ No newline at end of file diff --git a/SushiBar/SushiBarBusinessLogic_/OrderLogic.cs b/SushiBar/SushiBarBusinessLogic_/OrderLogic.cs index b1ea738..d101c25 100644 --- a/SushiBar/SushiBarBusinessLogic_/OrderLogic.cs +++ b/SushiBar/SushiBarBusinessLogic_/OrderLogic.cs @@ -19,18 +19,39 @@ namespace SushiBarBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; - private readonly AbstractMailWorker _mailWorker; - static readonly object _locker = new object(); - public OrderLogic(ILogger logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker) - { + private readonly AbstractMailWorker _mailWorker; + static readonly object _locker = new object(); + private readonly IShopStorage _shopStorage; + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IShopStorage shopStorage, AbstractMailWorker mailWorker) + { _logger = logger; _orderStorage = orderStorage; - _mailWorker = mailWorker; - } + _shopStorage = shopStorage; + _mailWorker = mailWorker; + } + + public OrderViewModel? ReadElement(OrderSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", + model.ClientId, model.Status, model.ImplementerId, 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 List? ReadList(OrderSearchModel? model) { _logger.LogInformation("ReadList. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", - model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, model?.Id); + model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, model?.Id); var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); if (list == null) { @@ -40,25 +61,26 @@ namespace SushiBarBusinessLogic.BusinessLogics _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.Принят; - var element = _orderStorage.Insert(model); - if (element == null) - { + var element = _orderStorage.Insert(model); + if (element == null) + { _logger.LogWarning("Insert operation failed"); return false; } - Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel - { - MailAddress = element.ClientEmail, - Subject = $"Изменение статуса заказа номер {element.Id}", - Text = $"Ваш заказ номер {element.Id} на суши {element.SushiName} от {element.DateCreate} на сумму {element.Sum} принят." - })); - return true; + Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel + { + MailAddress = element.ClientEmail, + Subject = $"Изменение статуса заказа номер {element.Id}", + Text = $"Ваш заказ номер {element.Id} на пиццу {element.SushiName} от {element.DateCreate} на сумму {element.Sum} принят." + })); + return true; } public bool TakeOrderInWork(OrderBindingModel model) @@ -76,7 +98,31 @@ namespace SushiBarBusinessLogic.BusinessLogics public bool DeliveryOrder(OrderBindingModel model) { - return ChangeStatus(model, OrderStatus.Выдан); + lock (_locker) + { + (model, var element) = FillOrderBindingModel(model); + if (model.Status != OrderStatus.Готов && model.Status != OrderStatus.Ожидает) + { + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-Выдан.", model.Status); + throw new InvalidOperationException($"Невозможно приствоить статус выдан заказу с текущим статусом {model.Status}"); + } + if (!_shopStorage.RestockingShops(new SupplyBindingModel + { + SushiId = model.SushiId, + Count = model.Count + })) + { + if (model.Status == OrderStatus.Готов) + { + model.Status = OrderStatus.Ожидает; + + UpdateOrder(model, element); + } + throw new ArgumentException("Недостаточно места в магазинах для поставки"); + } + model.Status = OrderStatus.Выдан; + return UpdateOrder(model, element); + } } private void CheckModel(OrderBindingModel model, bool withParams = true) @@ -104,8 +150,22 @@ namespace SushiBarBusinessLogic.BusinessLogics _logger.LogInformation("Sushi. SushiId:{SushiId}.Count:{Count}.Sum:{Sum}Id:{Id}", model.SushiId, model.Count, model.Sum, model.Id); } - private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus) + { + (model, var element) = FillOrderBindingModel(model); + + if (requiredStatus - model.Status == 1) + { + model.Status = requiredStatus; + if (model.Status == OrderStatus.Готов) + model.DateImplement = DateTime.Now; + return UpdateOrder(model, element); + } + _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); + throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); + } + + private (OrderBindingModel, OrderViewModel) FillOrderBindingModel(OrderBindingModel model) { CheckModel(model, false); var element = _orderStorage.GetElement(new OrderSearchModel() @@ -116,59 +176,38 @@ namespace SushiBarBusinessLogic.BusinessLogics { throw new InvalidOperationException(nameof(element)); } + model.Id = element.Id; model.DateCreate = element.DateCreate; model.SushiId = element.SushiId; model.DateImplement = element.DateImplement; model.ClientId = element.ClientId; + model.Status = element.Status; + model.Count = element.Count; + model.Sum = element.Sum; if (!model.ImplementerId.HasValue) { model.ImplementerId = element.ImplementerId; } - 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; - } - string DateInfo = model.DateImplement.HasValue ? $"Дата выполнения {model.DateImplement}" : ""; - Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel - { - MailAddress = element.ClientEmail, - Subject = $"Изменение статуса заказа номер {element.Id}", - Text = $"Ваш заказ номер {element.Id} на суши {element.SushiName} от {element.DateCreate} на сумму {element.Sum} {model.Status}. {DateInfo}" - })); - return true; - } - _logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus); - throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}"); - + return (model, element); } - public OrderViewModel? ReadElement(OrderSearchModel model) + private bool UpdateOrder(OrderBindingModel model, OrderViewModel MailNotificationModel) { - if (model == null) + if (_orderStorage.Update(model) == null) { - throw new ArgumentNullException(nameof(model)); + _logger.LogWarning("Update operation failed"); + return false; } - _logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}", - model.ClientId, model.Status, model.ImplementerId, model.DateFrom, model.DateTo, model.Id); - var element = _orderStorage.GetElement(model); - if (element == null) + _logger.LogWarning("Update operation sucsess"); + string DateInfo = model.DateImplement.HasValue ? $"Дата выполнения {model.DateImplement}" : ""; + Task.Run(() => _mailWorker.MailSendAsync(new MailSendInfoBindingModel { - _logger.LogWarning("ReadElement element not found"); - return null; - } - _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); - return element; + MailAddress = MailNotificationModel.ClientEmail, + Subject = $"Изменение статуса заказа номер {MailNotificationModel.Id}", + Text = $"Ваш заказ номер {MailNotificationModel.Id} на изделие {MailNotificationModel.SushiName} от" + + $" {MailNotificationModel.DateCreate} на сумму {MailNotificationModel.Sum} {model.Status}. {DateInfo}" + })); + return true; } } -} +} \ No newline at end of file diff --git a/SushiBar/SushiBarClientApp/APIClient.cs b/SushiBar/SushiBarClientApp/APIClient.cs index dbebe39..05ad940 100644 --- a/SushiBar/SushiBarClientApp/APIClient.cs +++ b/SushiBar/SushiBarClientApp/APIClient.cs @@ -12,7 +12,9 @@ namespace SushiBarClientApp private static readonly HttpClient _client = new(); public static string? Password { get; set; } - + public static ClientViewModel? Client { get; set; } = null; + public static int MailPage { get; set; } = 1; + public static void Connect(IConfiguration configuration) { _client.BaseAddress = new Uri(configuration["IPAddress"]); diff --git a/SushiBar/SushiBarClientApp/Controllers/HomeController.cs b/SushiBar/SushiBarClientApp/Controllers/HomeController.cs index ab3ec11..f2831e8 100644 --- a/SushiBar/SushiBarClientApp/Controllers/HomeController.cs +++ b/SushiBar/SushiBarClientApp/Controllers/HomeController.cs @@ -17,152 +17,15 @@ namespace SushiBarClientApp.Controllers _logger = logger; } - public IActionResult Index() - { - if (APIClient.Password == null) - { - return Redirect("~/Home/Enter"); - } - return View(APIClient.GetRequest>($"api/shop/getshoplist?password={APIClient.Password}")); - } - - [HttpGet] - public IActionResult Enter() - { - return View(); - } - - [HttpPost] - public void Enter(string password) - { - bool resout = APIClient.GetRequest($"/api/shop/authentication?password={password}"); - if (!resout) - { - Response.Redirect("../Home/Enter"); - return; - } - APIClient.Password = password; - Response.Redirect("Index"); - } - - [HttpGet] - public IActionResult Create() - { - if (APIClient.Password == null) - { - return Redirect("~/Home/Enter"); - } - return View("Shop"); - } - - [HttpPost] - public void Create(int id, string shopname, string adress, DateTime openingdate, int maxcount) - { - if (string.IsNullOrEmpty(shopname) || string.IsNullOrEmpty(adress)) - { - throw new Exception("Название или адрес не может быть пустым"); - } - if (openingdate == default(DateTime)) - { - throw new Exception("Дата открытия не может быть пустой"); - } - - APIClient.PostRequest($"api/shop/createshop?password={APIClient.Password}", new ShopBindingModel - { - Id = id, - ShopName = shopname, - Adress = adress, - OpeningDate = openingdate, - SushiMaxCount = maxcount - }); - Response.Redirect("Index"); - } - - [HttpGet] - public IActionResult Update(int Id) - { - if (APIClient.Password == null) - { - return Redirect("~/Home/Enter"); - } - return View("Shop", APIClient.GetRequest($"api/shop/getshop?shopId={Id}&password={APIClient.Password}")); - } - - [HttpPost] - public void Update(int id, string shopname, string adress, DateTime openingdate, int maxcount) - { - if (string.IsNullOrEmpty(shopname) || string.IsNullOrEmpty(adress)) - { - throw new Exception("Название или адрес не может быть пустым"); - } - if (openingdate == default(DateTime)) - { - throw new Exception("Дата открытия не может быть пустой"); - } - APIClient.PostRequest($"api/shop/updateshop?password={APIClient.Password}", new ShopBindingModel - { - Id = id, - ShopName = shopname, - Adress = adress, - OpeningDate = openingdate, - SushiMaxCount = maxcount - }); - Response.Redirect("../Index"); - } - - [HttpPost] - public void Delete(int Id) - { - APIClient.DeleteRequest($"api/shop/deleteshop?shopId={Id}&password={APIClient.Password}"); - Response.Redirect("../Index"); - } - - [HttpGet] - public IActionResult Supply() - { - if (APIClient.Password == null) - { - return Redirect("~/Home/Enter"); - } - - ViewBag.Shops = APIClient.GetRequest>($"api/shop/getshoplist?password={APIClient.Password}"); - ViewBag.Sushis = APIClient.GetRequest>($"api/main/getsushilist"); - return View(); - } - - [HttpPost] - public void Supply(int shop, int sushi, int count) - { - APIClient.PostRequest($"api/shop/makesypply?password={APIClient.Password}", new SupplyBindingModel - { - ShopId = shop, - SushiId = sushi, - Count = count - }); - Response.Redirect("Index"); - } - - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public IActionResult Error() - { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - } - } -} - private readonly ILogger _logger; - public HomeController(ILogger logger) - { - _logger = logger; - } public IActionResult Index() { if (APIClient.Client == null) { return Redirect("~/Home/Enter"); } - return - View(APIClient.GetRequest>($"api/main/getorders?clientId={APIClient.Client.Id}")); + return View(APIClient.GetRequest>($"api/main/getorders?clientId={APIClient.Client.Id}")); } + [HttpGet] public IActionResult Privacy() { @@ -172,6 +35,7 @@ namespace SushiBarClientApp.Controllers } return View(APIClient.Client); } + [HttpPost] public void Privacy(string login, string password, string fio) { @@ -179,70 +43,65 @@ namespace SushiBarClientApp.Controllers { throw new Exception("Вы как суда попали? Суда вход только авторизованным"); } - if (string.IsNullOrEmpty(login) || - string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) { throw new Exception("Введите логин, пароль и ФИО"); } - APIClient.PostRequest("api/client/updatedata", new - ClientBindingModel + APIClient.PostRequest("api/client/updatedata", new ClientBindingModel { Id = APIClient.Client.Id, ClientFIO = fio, Email = login, Password = password }); + APIClient.Client.ClientFIO = fio; APIClient.Client.Email = login; APIClient.Client.Password = password; Response.Redirect("Index"); } - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, - NoStore = true)] + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { - return View(new ErrorViewModel - { - RequestId = - Activity.Current?.Id ?? HttpContext.TraceIdentifier - }); + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } + [HttpGet] public IActionResult Enter() { return View(); } + [HttpPost] public void Enter(string login, string password) { - if (string.IsNullOrEmpty(login) || - string.IsNullOrEmpty(password)) + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)) { throw new Exception("Введите логин и пароль"); } - APIClient.Client = - APIClient.GetRequest($"api/client/login?login={login}&password={password}"); + APIClient.Client = APIClient.GetRequest($"api/client/login?login={login}&password={password}"); if (APIClient.Client == null) { throw new Exception("Неверный логин/пароль"); } Response.Redirect("Index"); } + [HttpGet] public IActionResult Register() { return View(); } + [HttpPost] public void Register(string login, string password, string fio) { - if (string.IsNullOrEmpty(login) || - string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) { throw new Exception("Введите логин, пароль и ФИО"); } - APIClient.PostRequest("api/client/register", new - ClientBindingModel + APIClient.PostRequest("api/client/register", new ClientBindingModel { ClientFIO = fio, Email = login, @@ -251,15 +110,16 @@ namespace SushiBarClientApp.Controllers Response.Redirect("Enter"); return; } + [HttpGet] public IActionResult Create() { - ViewBag.Sushis = - APIClient.GetRequest>("api/main/getsushilist"); + ViewBag.Sushis = APIClient.GetRequest>("api/main/getSushilist"); return View(); } + [HttpPost] - public void Create(int sushi, int count) + public void Create(int Sushi, int count) { if (APIClient.Client == null) { @@ -272,31 +132,31 @@ namespace SushiBarClientApp.Controllers APIClient.PostRequest("api/main/createorder", new OrderBindingModel { ClientId = APIClient.Client.Id, - SushiId = sushi, + SushiId = Sushi, Count = count, - Sum = Calc(count, sushi) + Sum = Calc(count, Sushi) }); Response.Redirect("Index"); } + [HttpPost] - public double Calc(int count, int sushi) + public double Calc(int count, int Sushi) { - var prod = - APIClient.GetRequest($"api/main/getsushi?sushiId={sushi}" - ); - return count * (prod?.Price ?? 1); + var sus = APIClient.GetRequest($"api/main/getSushi?SushiId={Sushi}"); + return count * (sus?.Price ?? 1); } [HttpGet] - public IActionResult Mails() + public IActionResult Mails(int page = 1) { if (APIClient.Client == null) { return Redirect("~/Home/Enter"); } - return View(APIClient.GetRequest>($"api/client/getmessages?clientId={APIClient.Client.Id}")); - } + page = Math.Max(page, 1); + return View(APIClient.GetRequest>($"api/client/getmessages?clientId={APIClient.Client.Id}&page={page}")); + } } } diff --git a/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml b/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml index b669ca6..4cedcf6 100644 --- a/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml +++ b/SushiBar/SushiBarClientApp/Views/Home/Index.cshtml @@ -1,68 +1,75 @@ @using SushiBarContracts.ViewModels -@model List +@model List @{ ViewData["Title"] = "Home Page"; }
-

Магазины

+

Заказы

-
-

- Создать магазин -

+
+ @{ + if (Model == null) + { +

Авторизируйтесь

+ return; + } - - - - - - - - - - - - - @foreach (var item in Model) - { - - - - - - - - - } - -
- Номер - - Название - - Адрес - - Дата открытия - - Максимальная вместимость - - -
- @Html.DisplayFor(modelItem => item.Id) - - @Html.DisplayFor(modelItem => item.ShopName) - - @Html.DisplayFor(modelItem => item.Adress) - - @Html.DisplayFor(modelItem => item.OpeningDate) - - @Html.DisplayFor(modelItem => item.SushiMaxCount) - - Изменить -
+

+ Создать заказ +

+ + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + + } + +
+ Номер + + Пицца + + Дата создания + + Количество + + Сумма + + Статус +
+ @Html.DisplayFor(modelItem => item.Id) + + @Html.DisplayFor(modelItem => item.SushiName) + + @Html.DisplayFor(modelItem => item.DateCreate) + + @Html.DisplayFor(modelItem => item.Count) + + @Html.DisplayFor(modelItem => item.Sum) + + @Html.DisplayFor(modelItem => item.Status) +
+ }
\ No newline at end of file diff --git a/SushiBar/SushiBarClientApp/Views/Home/Mails.cshtml b/SushiBar/SushiBarClientApp/Views/Home/Mails.cshtml index b1fa224..fc65729 100644 --- a/SushiBar/SushiBarClientApp/Views/Home/Mails.cshtml +++ b/SushiBar/SushiBarClientApp/Views/Home/Mails.cshtml @@ -1,6 +1,7 @@ @using SushiBarContracts.ViewModels @model List +@Url.ActionContext.RouteData.Values["page"] @{ ViewData["Title"] = "Mails"; @@ -16,40 +17,58 @@ @{ if (Model == null) { -

Авторизируйтесь

+

Авторизируйтесь

return; } - - - - - - - - - +
- Дата письма - - Заголовок - - Текст -
+ + + + + + + + @foreach (var item in Model) { - - + - + - + - + + } - -
+ Дата письма + + Заголовок + + Текст +
+
@Html.DisplayFor(modelItem => item.DateDelivery) - + @Html.DisplayFor(modelItem => item.Subject) - + @Html.DisplayFor(modelItem => item.Body) -
+ + +
+ @{ + int page = int.Parse(Context.Request.Query["page"]); +
+ +
+ if (page > 1) + { + <- + } + else + { +

<-

+ } + + -> + } +
} -
+ \ No newline at end of file diff --git a/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml b/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml index 33fa0a2..2049c06 100644 --- a/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml +++ b/SushiBar/SushiBarClientApp/Views/Shared/_Layout.cshtml @@ -14,7 +14,7 @@