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 logger, ITransportationStorage transportationStorage) { _logger = logger; _transportationStorage = transportationStorage; } public List? 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}"); } } }