214 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FoodOrdersContracts.BindingModels;
using FoodOrdersContracts.BusinessLogicsContracts;
using FoodOrdersContracts.SearchModels;
using FoodOrdersContracts.StoragesContracts;
using FoodOrdersContracts.ViewModels;
using FoodOrdersDataModels.Enums;
using FoodOrdersDataModels.Models;
using Microsoft.Extensions.Logging;
namespace FoodOrdersBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly IDishStorage _dishStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopLogic shopLogic, IDishStorage dishStorage, IShopStorage shopStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopLogic = shopLogic;
_dishStorage = dishStorage;
_shopStorage = shopStorage;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Invalid order status");
return false;
}
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public List<OrderViewModel>? 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 bool TakeOrderInWork(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.DishId <= 0)
{
throw new ArgumentNullException("Некорректный идентификатор блюда", nameof(model.DishId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("В заказе должно быть хотя бы одна блюдо", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Стоимость заказа должна быть больше 0", nameof(model.Sum));
}
_logger.LogInformation("Order. Id: {Id}. Sum: {Sum}. DishId: {DishId}. DishCount: {Count}", model.Id, model.Sum,
model.DishId, model.Count);
}
public bool CheckThenMakeShipment(IDishModel dish, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check then make shipment operation error. Dish count < 0.");
return false;
}
int freeSpace = 0;
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace += shop.MaxCountDishs;
foreach (var c in shop.ShopDishs)
{
freeSpace -= c.Value.Item2;
}
}
if (freeSpace < count)
{
_logger.LogWarning("Check then supply operation error. There's no place for new dishs in shops.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCountDishs;
foreach (var c in shop.ShopDishs)
freeSpace -= c.Value.Item2;
if (freeSpace <= 0)
continue;
if (freeSpace >= count)
{
if (_shopLogic.MakeShipment(new ShopSearchModel() { Id = shop.Id }, dish, count))
count = 0;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (freeSpace < count)
{
if (_shopLogic.MakeShipment(new ShopSearchModel() { Id = shop.Id }, dish, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
private bool ChangeStatus(OrderBindingModel model, OrderStatus newStatus)
{
CheckModel(model, false);
var order = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id } );
if (order == null)
{
_logger.LogWarning("Change status operation failed. Order not found");
return false;
}
if (order.Status + 1 != newStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {newStatus}. Current status: {currStatus}",
newStatus, order.Status);
return false;
}
if (newStatus == OrderStatus.Выдан)
{
var dish = _dishStorage.GetElement(new DishSearchModel() { Id = order.DishId });
if (dish == null)
{
_logger.LogWarning("Change status operation failed. Dish not found");
return false;
}
if (!CheckThenMakeShipment(dish, order.Count))
{
_logger.LogWarning("Change status operation failed. Dishs delivery operation failed");
return false;
}
}
model.DishId = order.DishId;
model.Count = order.Count;
model.Sum = order.Sum;
model.DateCreate = order.DateCreate;
model.Status = newStatus;
if (model.Status == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
} else
{
model.DateImplement = order.DateImplement;
}
if (_orderStorage.Update(model) == null)
{
_logger.LogWarning("Change status operation failed");
return false;
}
return true;
}
}
}