using DressAtelierContracts.BindingModels; using DressAtelierContracts.BusinessLogicContracts; using DressAtelierContracts.SearchModels; using DressAtelierContracts.StorageContracts; using DressAtelierContracts.ViewModels; using DressAtelierDataModels.Enums; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Transactions; namespace DressAtelierBusinessLogic.BusinessLogic { public class OrderLogic : IOrderLogic { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; private readonly IAtelierLogic _atelierLogic; public OrderLogic(ILogger logger, IOrderStorage orderStorage, IAtelierLogic atelierLogic) { _logger = logger; _orderStorage = orderStorage; _atelierLogic = atelierLogic; } public bool CreateOrder(OrderBindingModel model) { CheckModel(model); if (model.Status != OrderStatus.Unknown) { _logger.LogWarning("Insert operation failed"); return false; } model.Status = OrderStatus.Accepted; if (_orderStorage.Insert(model) == null) { _logger.LogWarning("Insert operation failed"); return false; } return true; } public bool GivenOrder(OrderBindingModel model) { CheckModel(model, false); _logger.LogInformation("Update to given status. ID:{ID}", model.ID); if (model.Status != OrderStatus.Ready) { _logger.LogWarning("Update operation failed"); return false; } var ateliers = _atelierLogic.ReadList(null); if (ateliers == null) { return false; } int quantity = model.Count; try { using (TransactionScope scope = new TransactionScope()) { if(ateliers.Sum(x => x.MaxTotalOfDresses - x.DressesList.Sum(y => y.Value.Item2)) < quantity) { throw new OverflowException("There is not enough space in ateliers"); } foreach (var atelier in ateliers) { quantity = _atelierLogic.AddDress(new AtelierBindingModel { ID = atelier.ID }, new DressBindingModel { ID = model.DressID }, quantity).quantity; } model.Status = OrderStatus.Given; model.DateImplement = DateTime.Now; _orderStorage.Update(model); } } catch (Exception ex) { throw new OverflowException("Shops' storages are full."); } return true; } public bool ReadyOrder(OrderBindingModel model) { CheckModel(model,false); _logger.LogInformation("Update to ready status. ID:{ID}", model.ID); if ( model.Status != OrderStatus.InProcess) { _logger.LogWarning("Update operation failed"); return false; } model.Status = OrderStatus.Ready; _orderStorage.Update(model); return true; } public bool TakeOrderInWork(OrderBindingModel model) { CheckModel(model,false); _logger.LogInformation("Update to in process status. ID:{ID}", model.ID); if (model.Status != OrderStatus.Accepted) { _logger.LogWarning("Update operation failed"); return false; } model.Status = OrderStatus.InProcess; _orderStorage.Update(model); return true; } public List? ReadList(OrderSearchModel? model) { _logger.LogInformation("ReadList. OrderID:{ID}",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 void CheckModel(OrderBindingModel model, bool withParams = true) { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (!withParams) { return; } _logger.LogInformation("Order. OrderID: { ID} ",model.ID); var element = _orderStorage.GetElement(new OrderSearchModel { ID = model.ID }); if (element != null && element.ID != model.ID) { throw new InvalidOperationException("Order with such name already exists."); } } } }