From 055e45b19132a9895b65e113f51082e7d425f2d1 Mon Sep 17 00:00:00 2001 From: Viltskaa Date: Mon, 10 Apr 2023 13:35:57 +0400 Subject: [PATCH] second part lab work --- .../BusinessLogics/OrderLogic.cs | 17 +++ .../BusinessLogics/WorkModeling.cs | 127 ++++++++++++++++++ .../BusinessLogicsContracts/IOrderLogic.cs | 1 + .../BusinessLogicsContracts/IWorkProcess.cs | 6 + .../SearchModels/OrderSearchModel.cs | 5 +- .../Controllers/ImplementerController.cs | 102 ++++++++++++++ 6 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 SushiBar/SushiBarBusinessLogic/BusinessLogics/WorkModeling.cs create mode 100644 SushiBar/SushiBarContracts/BusinessLogicsContracts/IWorkProcess.cs create mode 100644 SushiBar/SushiBarRestApi/Controllers/ImplementerController.cs diff --git a/SushiBar/SushiBarBusinessLogic/BusinessLogics/OrderLogic.cs b/SushiBar/SushiBarBusinessLogic/BusinessLogics/OrderLogic.cs index 0ba14c0..4f3b136 100644 --- a/SushiBar/SushiBarBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/SushiBar/SushiBarBusinessLogic/BusinessLogics/OrderLogic.cs @@ -18,6 +18,23 @@ namespace SushiBarBusinessLogic.BusinessLogics _logger = logger; _orderStorage = orderStorage; } + + public OrderViewModel? ReadElement(OrderSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. Id:{ Id}", model.Id); + var element = _orderStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } public bool CreateOrder(OrderBindingModel model) { diff --git a/SushiBar/SushiBarBusinessLogic/BusinessLogics/WorkModeling.cs b/SushiBar/SushiBarBusinessLogic/BusinessLogics/WorkModeling.cs new file mode 100644 index 0000000..f325e4d --- /dev/null +++ b/SushiBar/SushiBarBusinessLogic/BusinessLogics/WorkModeling.cs @@ -0,0 +1,127 @@ +using DocumentFormat.OpenXml.Drawing.Charts; +using Microsoft.Extensions.Logging; +using SushiBarContracts.BindingModels; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModels; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Enums; + +namespace SushiBarBusinessLogic.BusinessLogics; + +public class WorkModeling : IWorkProcess +{ + private readonly ILogger _logger; + private readonly Random _rnd; + private IOrderLogic? _orderLogic; + + public WorkModeling(ILogger 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 { Status = OrderStatus.Accepted }); + if (orders == null || orders.Count == 0) + { + _logger.LogWarning("DoWork. Orders is null or empty"); + return; + } + _logger.LogDebug("DoWork for {Count} orders", orders.Count); + foreach (var implementer in implementers) + { + Task.Run(() => WorkerWorkAsync(implementer, orders)); + } + } + + private async Task WorkerWorkAsync(ImplementerViewModel implementer, + List orders) + { + if (_orderLogic == null) + { + return; + } + await RunOrderInWork(implementer); + await Task.Run(() => + { + foreach (var order in orders) + { + try + { + _logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id); + _orderLogic.TakeOrderInWork(new OrderBindingModel + { + Id = order.Id, + ImplementerId = implementer.Id + }); + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, + 1000) * order.Count); + _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id); + _orderLogic.FinishOrder(new OrderBindingModel + { + Id = order.Id + }); + } + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try get work"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); + } + }); + } + + private async Task RunOrderInWork(ImplementerViewModel implementer) + { + if (_orderLogic == null) + { + return; + } + try + { + var runOrder = await Task.Run(() => _orderLogic.ReadElement(new + OrderSearchModel + { + ImplementerId = implementer.Id, + Status = OrderStatus.Performed + })); + if (runOrder == null) + { + return; + } + _logger.LogDebug("DoWork. Worker {Id} back to order {Order}", + implementer.Id, runOrder.Id); + Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * + runOrder.Count); + _logger.LogDebug("DoWork. Worker {Id} finish order {Order}", + implementer.Id, runOrder.Id); + _orderLogic.FinishOrder(new OrderBindingModel + { + Id = runOrder.Id + }); + Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); + } + catch (InvalidOperationException ex) + { + _logger.LogWarning(ex, "Error try get work"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while do work"); + throw; + } + } +} \ No newline at end of file diff --git a/SushiBar/SushiBarContracts/BusinessLogicsContracts/IOrderLogic.cs b/SushiBar/SushiBarContracts/BusinessLogicsContracts/IOrderLogic.cs index be0cb58..3898146 100644 --- a/SushiBar/SushiBarContracts/BusinessLogicsContracts/IOrderLogic.cs +++ b/SushiBar/SushiBarContracts/BusinessLogicsContracts/IOrderLogic.cs @@ -11,5 +11,6 @@ namespace SushiBarContracts.BusinessLogicsContracts bool TakeOrderInWork(OrderBindingModel model); bool FinishOrder(OrderBindingModel model); bool DeliveryOrder(OrderBindingModel model); + OrderViewModel? ReadElement(OrderSearchModel model); } } diff --git a/SushiBar/SushiBarContracts/BusinessLogicsContracts/IWorkProcess.cs b/SushiBar/SushiBarContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..b49e1ad --- /dev/null +++ b/SushiBar/SushiBarContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,6 @@ +namespace SushiBarContracts.BusinessLogicsContracts; + +public interface IWorkProcess +{ + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); +} \ No newline at end of file diff --git a/SushiBar/SushiBarContracts/SearchModels/OrderSearchModel.cs b/SushiBar/SushiBarContracts/SearchModels/OrderSearchModel.cs index b1a1f0c..dfa8020 100644 --- a/SushiBar/SushiBarContracts/SearchModels/OrderSearchModel.cs +++ b/SushiBar/SushiBarContracts/SearchModels/OrderSearchModel.cs @@ -1,4 +1,6 @@ -namespace SushiBarContracts.SearchModels +using SushiBarDataModels.Enums; + +namespace SushiBarContracts.SearchModels { public class OrderSearchModel { @@ -7,5 +9,6 @@ public DateTime? DateTo { get; set; } public int? ClientId { get; set; } public int? ImplementerId { get; set; } + public OrderStatus Status { get; set; } } } diff --git a/SushiBar/SushiBarRestApi/Controllers/ImplementerController.cs b/SushiBar/SushiBarRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..5841e24 --- /dev/null +++ b/SushiBar/SushiBarRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,102 @@ +using DocumentFormat.OpenXml.Office2010.Excel; +using Microsoft.AspNetCore.Mvc; +using SushiBarContracts.BindingModels; +using SushiBarContracts.BusinessLogicsContracts; +using SushiBarContracts.SearchModels; +using SushiBarContracts.ViewModels; +using SushiBarDataModels.Enums; + +namespace SushiBarRestApi.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 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, "Error on auth"); + throw; + } + } + [HttpGet] + public List? GetNewOrders() + { + try + { + return _order.ReadList(new OrderSearchModel + { + Status = OrderStatus.Accepted + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error on get new orders"); + throw; + } + } + [HttpGet] + public OrderViewModel? GetImplementerOrder(int implementerId) + { + try + { + return _order.ReadElement(new OrderSearchModel + { + ImplementerId = implementerId + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error on get current order"); + throw; + } + } + [HttpPost] + public void TakeOrderInWork(OrderBindingModel model) + { + try + { + _order.TakeOrderInWork(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error on take in work order with id {Id}", model.Id); + throw; + } + } + [HttpPost] + public void FinishOrder(OrderBindingModel model) + { + try + { + _order.FinishOrder(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error on ready order with id {Id}", model.Id); + throw; + } + } + +} \ No newline at end of file