Слой бизнес-логики

This commit is contained in:
Вячеслав Иванов 2024-02-25 14:44:58 +04:00
parent a0251dbb00
commit 7e6d2bd728
14 changed files with 610 additions and 2 deletions

View File

@ -0,0 +1,115 @@
using Microsoft.Extensions.Logging;
using TransportCompanyContracts.BindingModels;
using TransportCompanyContracts.BusinessLogicsContracts;
using TransportCompanyContracts.SearchModels;
using TransportCompanyContracts.StoragesContracts;
using TransportCompanyContracts.ViewModels;
namespace TransportCompanyBusinessLogic.BusinessLogics
{
public class CargoLogic : ICargoLogic
{
private readonly ILogger _logger;
private readonly ICargoStorage _cargoStorage;
public CargoLogic(ILogger <CargoLogic> logger, ICargoStorage cargoStorage)
{
_logger = logger;
_cargoStorage = cargoStorage;
}
public List<CargoViewModel>? ReadList(CargoSearchModel? model)
{
_logger.LogInformation("ReadList. CargoName:{CargoName}. Id:{Id}", model?.CargoName, model?.Id);
var list = model == null ? _cargoStorage.GetFullList() : _cargoStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public CargoViewModel? ReadElement(CargoSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. CargoName:{CargoName}. Id:{Id}", model.CargoName, model.Id);
var element = _cargoStorage.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(CargoBindingModel model)
{
CheckModel(model);
if (_cargoStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(CargoBindingModel model)
{
CheckModel(model);
if (_cargoStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(CargoBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_cargoStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(CargoBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.CargoName))
{
throw new ArgumentNullException("Нет названия груза", nameof(model.CargoName));
}
if (model.Weight <= 0)
{
throw new ArgumentNullException("Вес груза должен быть больше 0", nameof(model.Weight));
}
_logger.LogInformation("Cargo. CargoName:{CargoName}. Weight:{Weight}. Id:{Id}", model.CargoName, model.Weight, model.Id);
var element = _cargoStorage.GetElement(new CargoSearchModel
{
CargoName = model.CargoName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Груз с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,114 @@
using Microsoft.Extensions.Logging;
using TransportCompanyContracts.BindingModels;
using TransportCompanyContracts.BusinessLogicsContracts;
using TransportCompanyContracts.SearchModels;
using TransportCompanyContracts.StoragesContracts;
using TransportCompanyContracts.ViewModels;
namespace TransportCompanyBusinessLogic.BusinessLogics
{
public class DriverLogic : IDriverLogic
{
private readonly ILogger _logger;
private readonly IDriverStorage _driverStorage;
public DriverLogic(ILogger<DriverLogic> logger, IDriverStorage driverStorage)
{
_logger = logger;
_driverStorage = driverStorage;
}
public List<DriverViewModel>? ReadList(DriverSearchModel? model)
{
_logger.LogInformation("ReadList. DriverFio:{DriverFio}.Id:{ Id}", model?.DriverFio, model?.Id);
var list = model == null ? _driverStorage.GetFullList() : _driverStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public DriverViewModel? ReadElement(DriverSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. DriverFio:{DriverFio}.Id:{ Id}", model.DriverFio, model.Id);
var element = _driverStorage.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(DriverBindingModel model)
{
CheckModel(model);
if (_driverStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(DriverBindingModel model)
{
CheckModel(model);
if (_driverStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(DriverBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_driverStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(DriverBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.DriverFio))
{
throw new ArgumentNullException("Нет ФИО водителя", nameof(model.DriverFio));
}
if (string.IsNullOrEmpty(model.PhoneNumber))
{
throw new ArgumentNullException("Нет номера телефона водителя", nameof(model.PhoneNumber));
}
_logger.LogInformation("Driver. DriverFio:{DriverFio}.PhoneNumber:{ PhoneNumber}.Id: { Id}", model.DriverFio, model.PhoneNumber, model.Id);
var element = _driverStorage.GetElement(new DriverSearchModel
{
PhoneNumber = model.PhoneNumber
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Водитель с таким номером телефона уже есть");
}
}
}
}

View File

@ -0,0 +1,114 @@
using Microsoft.Extensions.Logging;
using TransportCompanyContracts.BindingModels;
using TransportCompanyContracts.BusinessLogicsContracts;
using TransportCompanyContracts.SearchModels;
using TransportCompanyContracts.StoragesContracts;
using TransportCompanyContracts.ViewModels;
namespace TransportCompanyBusinessLogic.BusinessLogics
{
public class PointLogic : IPointLogic
{
private readonly ILogger _logger;
private readonly IPointStorage _pointStorage;
public PointLogic(ILogger<PointLogic> logger, IPointStorage pointStorage)
{
_logger = logger;
_pointStorage = pointStorage;
}
public List<PointViewModel>? ReadList(PointSearchModel? model)
{
_logger.LogInformation("ReadList. PointName:{PointName}.Id:{ Id}", model?.PointName, model?.Id);
var list = model == null ? _pointStorage.GetFullList() : _pointStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public PointViewModel? ReadElement(PointSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. PointName:{PointName}.Id:{ Id}", model.PointName, model.Id);
var element = _pointStorage.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(PointBindingModel model)
{
CheckModel(model);
if (_pointStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(PointBindingModel model)
{
CheckModel(model);
if (_pointStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(PointBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_pointStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(PointBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.PointName))
{
throw new ArgumentNullException("Нет наименования пункта", nameof(model.PointName));
}
if (string.IsNullOrEmpty(model.Address))
{
throw new ArgumentNullException("Нет адреса пункта", nameof(model.Address));
}
_logger.LogInformation("Point. PointName:{PointName}.Address:{ Address}.Id: { Id}", model.PointName, model.Address, model.Id);
var element = _pointStorage.GetElement(new PointSearchModel
{
Address = model.Address
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Пункт с таким адресом уже есть");
}
}
}
}

View File

@ -0,0 +1,119 @@
using Microsoft.Extensions.Logging;
using TransportCompanyContracts.BindingModels;
using TransportCompanyContracts.BusinessLogicsContracts;
using TransportCompanyContracts.SearchModels;
using TransportCompanyContracts.StoragesContracts;
using TransportCompanyContracts.ViewModels;
namespace TransportCompanyBusinessLogic.BusinessLogics
{
public class TransportLogic : ITransportLogic
{
private readonly ILogger _logger;
private readonly ITransportStorage _transportStorage;
public TransportLogic(ILogger<CargoLogic> logger, ITransportStorage transportStorage)
{
_logger = logger;
_transportStorage = transportStorage;
}
public List<TransportViewModel>? ReadList(TransportSearchModel? model)
{
_logger.LogInformation("ReadList. Model:{Model}. Id:{Id}", model?.Model, model?.Id);
var list = model == null ? _transportStorage.GetFullList() : _transportStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public TransportViewModel? ReadElement(TransportSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Model:{Model}. Id:{Id}", model.Model, model.Id);
var element = _transportStorage.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(TransportBindingModel model)
{
CheckModel(model);
if (_transportStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(TransportBindingModel model)
{
CheckModel(model);
if (_transportStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(TransportBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_transportStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(TransportBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Model))
{
throw new ArgumentNullException("Нет модели авто", nameof(model.Model));
}
if (model.LoadCapacity <= 0)
{
throw new ArgumentNullException("Вместимость авто должна быть больше 0", nameof(model.LoadCapacity));
}
if (string.IsNullOrEmpty(model.StateNumber))
{
throw new ArgumentNullException("Нет автомобильного номера", nameof(model.StateNumber));
}
_logger.LogInformation("Cargo. Model:{Model}. LoadCapacity:{LoadCapacity}. StateNumber:{StateNumber}. Id:{Id}", model.Model, model.LoadCapacity, model.StateNumber, model.Id);
var element = _transportStorage.GetElement(new TransportSearchModel
{
StateNumber = model.StateNumber
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Авто с таким автомобильным номером уже есть");
}
}
}
}

View File

@ -0,0 +1,119 @@
using Microsoft.Extensions.Logging;
using TransportCompanyContracts.BindingModels;
using TransportCompanyContracts.BusinessLogicsContracts;
using TransportCompanyContracts.SearchModels;
using TransportCompanyContracts.StoragesContracts;
using TransportCompanyContracts.ViewModels;
using TransportCompanyDataModels.Enums;
namespace TransportCompanyBusinessLogic.BusinessLogics
{
public class TransportationLogic : ITransportationLogic
{
private readonly ILogger _logger;
private readonly ITransportationStorage _transportationStorage;
public TransportationLogic(ILogger<TransportationLogic> logger, ITransportationStorage transportationStorage)
{
_logger = logger;
_transportationStorage = transportationStorage;
}
public List<TransportationViewModel>? ReadList(TransportationSearchModel? model)
{
_logger.LogInformation("ReadList. TransportationId:{Id}", model?.Id);
var list = model == null ? _transportationStorage.GetFullList() : _transportationStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateTransportation(TransportationBindingModel model)
{
CheckModel(model);
if (model.Status != TransportationStatus.Неизвестен)
return false;
model.Status = TransportationStatus.Принят;
if (_transportationStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool DeliveredTransportation(TransportationBindingModel model)
{
return ChangeStatus(model, TransportationStatus.Доставляется);
}
public bool ArrivedTransportation(TransportationBindingModel model)
{
return ChangeStatus(model, TransportationStatus.Прибыл);
}
public bool ShippedTransportation(TransportationBindingModel model)
{
return ChangeStatus(model, TransportationStatus.Отгружен);
}
private void CheckModel(TransportationBindingModel 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.ArrivalDate.HasValue && model.ArrivalDate < model.DepartureDate)
{
throw new ArithmeticException($"Дата отгрузки {model.ArrivalDate} не может быть раньше даты отправки {model.DepartureDate}");
}
_logger.LogInformation("Transportation. CargoId:{CargoId}.Count:{Count.}Id:{Id}",
model.CargoId, model.Count, model.Id);
}
private bool ChangeStatus(TransportationBindingModel model, TransportationStatus requiredStatus)
{
CheckModel(model, false);
var element = _transportationStorage.GetElement(new TransportationSearchModel()
{
Id = model.Id
});
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
model.DepartureDate = element.DepartureDate;
model.CargoId = element.CargoId;
model.ArrivalDate = element.ArrivalDate;
model.Status = element.Status;
model.Count = element.Count;
if (requiredStatus - model.Status == 1)
{
model.Status = requiredStatus;
if (model.Status == TransportationStatus.Отгружен)
model.ArrivalDate = DateTime.Now;
if (_transportationStorage.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}");
}
}
}

View File

@ -6,4 +6,16 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TransportCompanyContracts\TransportCompanyContracts.csproj" />
<ProjectReference Include="..\TransportCompanyDataModels\TransportCompanyDataModels.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -10,6 +10,8 @@ namespace TransportCompanyContracts.BindingModels
public int TransportId { get; set; } public int TransportId { get; set; }
public int PointToId { get; set; } public int PointToId { get; set; }
public int PointFromId { get; set; } public int PointFromId { get; set; }
public int CargoId { get; set; }
public int Count { get; set; }
public TransportationStatus Status { get; set; } = TransportationStatus.Неизвестен; public TransportationStatus Status { get; set; } = TransportationStatus.Неизвестен;
public DateTime DepartureDate { get; set; } = DateTime.Now; public DateTime DepartureDate { get; set; } = DateTime.Now;
public DateTime? ArrivalDate { get; set; } public DateTime? ArrivalDate { get; set; }

View File

@ -10,7 +10,7 @@ namespace TransportCompanyContracts.BusinessLogicsContracts
bool CreateTransportation(TransportationBindingModel bindingModel); bool CreateTransportation(TransportationBindingModel bindingModel);
bool DeliveredTransportation(TransportationBindingModel bindingModel); bool DeliveredTransportation(TransportationBindingModel bindingModel);
bool ArrivedTransportation(TransportationBindingModel bindingModel); bool ArrivedTransportation(TransportationBindingModel bindingModel);
bool IssueTransportation(TransportationBindingModel bindingModel); bool ShippedTransportation(TransportationBindingModel bindingModel);
} }
} }

View File

@ -4,5 +4,6 @@
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? DriverFio { get; set; } public string? DriverFio { get; set; }
public string? PhoneNumber { get; set; }
} }
} }

View File

@ -4,5 +4,6 @@
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? PointName { get; set; } public string? PointName { get; set; }
public string? Address { get; set; }
} }
} }

View File

@ -4,5 +4,6 @@
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? Model { get; set; } public string? Model { get; set; }
public string? StateNumber { get; set; }
} }
} }

View File

@ -19,6 +19,14 @@ namespace TransportCompanyContracts.ViewModels
[DisplayName("Машина")] [DisplayName("Машина")]
public string Model { get; set; } = string.Empty; public string Model { get; set; } = string.Empty;
public int CargoId { get; set; }
[DisplayName("Груз")]
public string CargoName { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
public int PointToId { get; set; } public int PointToId { get; set; }
[DisplayName("Откуда")] [DisplayName("Откуда")]

View File

@ -10,6 +10,6 @@
Прибыл = 2, Прибыл = 2,
Выдан = 3 Отгружен = 3
} }
} }

View File

@ -6,6 +6,8 @@ namespace TransportCompanyDataModels.Models
{ {
int DriverId { get; } int DriverId { get; }
int TransportId { get; } int TransportId { get; }
int CargoId { get; }
int Count { get; }
int PointToId { get; } int PointToId { get; }
int PointFromId { get; } int PointFromId { get; }
TransportationStatus Status { get; } TransportationStatus Status { get; }