Implementer contracts, data models, business logic

This commit is contained in:
ShabOl 2024-04-16 00:06:12 +04:00
parent 1d6b9b85f6
commit 75911262ea
16 changed files with 438 additions and 6 deletions

View File

@ -0,0 +1,135 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
private readonly ILogger _logger;
private readonly IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<IImplementerLogic> Logger, IImplementerStorage ImplementerStorage)
{
_logger = Logger;
_implementerStorage = ImplementerStorage;
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? Model)
{
_logger.LogInformation("ReadList. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}",
Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id);
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 is null)
{
throw new ArgumentNullException(nameof(Model));
}
_logger.LogInformation("ReadElement. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}",
Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id);
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("Стаж должен быть неотрицательным целым числом", nameof(Model.WorkExperience));
if (Model.Qualification < 0)
throw new ArgumentNullException("Квалификация должна быть неотрицательным целым числом", nameof(Model.Qualification));
_logger.LogInformation("Implementer. ImplementerFIO: {ImplementerFIO}. Password: {Password}. WorkExperience: {WorkExperience}. Qualification: {Qualification}. Id: {Id}",
Model.ImplementerFIO, Model.Password, Model.WorkExperience, Model.Qualification, Model.Id);
var Implementer = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = Model.ImplementerFIO
});
if (Implementer != null && Implementer.Id != Model.Id)
{
throw new InvalidOperationException("Исполнитель с таким ФИО уже есть");
}
}
}
}

View File

@ -14,6 +14,8 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
private readonly IOrderStorage _orderStorage;
static readonly object _locker = new object();
public OrderLogic(ILogger<RepairLogic> Logger, IOrderStorage OrderStorage)
{
_logger = Logger;
@ -22,19 +24,18 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public List<OrderViewModel>? ReadList(OrderSearchModel? Model)
{
_logger.LogInformation("ReadList. Id:{Id}", Model?.Id);
_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 is null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(Model);
if (List is 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);
@ -76,6 +77,8 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
}
Model.RepairId = Order.RepairId;
Model.ClientId = Order.ClientId;
Model.ImplementerId = Order.ImplementerId;
Model.Count = Order.Count;
Model.Sum = Order.Sum;
Model.DateCreate = Order.DateCreate;
@ -97,7 +100,10 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
public bool TakeOrderInWork(OrderBindingModel Model)
{
return ChangeOrderStatus(Model, OrderStatus.BeingProcessed);
lock (_locker)
{
return ChangeOrderStatus(Model, OrderStatus.BeingProcessed);
}
}
public bool FinishOrder(OrderBindingModel Model)
@ -129,5 +135,27 @@ namespace AutoWorkshopBusinessLogic.BusinessLogics
Model.RepairId, Model.Count, Model.Sum, Model.Status, Model.DateCreate,
Model.DateImplement, Model.Id);
}
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 Order = _orderStorage.GetElement(Model);
if (Order == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", Order.Id);
return Order;
}
}
}

View File

@ -0,0 +1,143 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.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 { 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<OrderViewModel> Orders)
{
if (_orderLogic == null || Implementer == 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 || Implementer == null)
return;
try
{
var RunOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = Implementer.Id,
Status = OrderStatus.BeingProcessed
}));
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;
}
}
}
}

View File

@ -0,0 +1,17 @@
using AutoWorkshopDataModels.Models;
namespace AutoWorkshopContracts.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

@ -8,6 +8,7 @@ namespace AutoWorkshopContracts.BindingModels
public int Id { get; set; }
public int RepairId { get; set; }
public int ClientId { get; set; }
public int? ImplementerId { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
public OrderStatus Status { get; set; } = OrderStatus.Undefined;

View File

@ -0,0 +1,19 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.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

@ -11,5 +11,6 @@ namespace AutoWorkshopContracts.BusinessLogicContracts
bool TakeOrderInWork(OrderBindingModel Model);
bool FinishOrder(OrderBindingModel Model);
bool DeliveryOrder(OrderBindingModel Model);
OrderViewModel? ReadElement(OrderSearchModel Model);
}
}

View File

@ -0,0 +1,9 @@
using AutoWorkshopContracts.BusinessLogicsContracts;
namespace AutoWorkshopContracts.BusinessLogicContracts
{
public interface IWorkProcess
{
void DoWork(IImplementerLogic ImplementerLogic, IOrderLogic OrderLogic);
}
}

View File

@ -0,0 +1,11 @@
namespace AutoWorkshopContracts.SearchModels
{
public class ImplementerSearchModel
{
public int? Id { get; set; }
public string? ImplementerFIO { get; set; }
public string? Password { get; set; }
}
}

View File

@ -1,4 +1,6 @@
namespace AutoWorkshopContracts.SearchModels
using AutoWorkshopDataModels.Enums;
namespace AutoWorkshopContracts.SearchModels
{
public class OrderSearchModel
{
@ -6,6 +8,10 @@
public int? ClientId { get; set; }
public OrderStatus? Status { get; set; }
public int? ImplementerId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }

View File

@ -0,0 +1,21 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopContracts.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,22 @@
using AutoWorkshopDataModels.Models;
using System.ComponentModel;
namespace AutoWorkshopContracts.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

@ -19,6 +19,11 @@ namespace AutoWorkshopContracts.ViewModels
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; }
[DisplayName("Количество")]
public int Count { get; set; }

View File

@ -0,0 +1,13 @@
namespace AutoWorkshopDataModels.Models
{
public interface IImplementerModel : IId
{
string ImplementerFIO { get; }
string Password { get; }
int WorkExperience { get; }
int Qualification { get; }
}
}

View File

@ -6,6 +6,7 @@ namespace AutoWorkshopDataModels.Models
{
int RepairId { get; }
int ClientId { get; }
int? ImplementerId { get; }
int Count { get; }
double Sum { get; }
OrderStatus Status { get; }

Binary file not shown.