PIbd-23_Elatomtsev_L.K._Con.../Confectionery/ConfectioneryBusinessLogic/BusinessLogics/OrderLogic.cs
2024-06-20 06:10:16 +04:00

197 lines
6.3 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 ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.StoragesContracts;
using ConfectioneryContracts.ViewModels;
using ConfectioneryDataModels.Enums;
using ConfectioneryDataModels.Models;
using Microsoft.Extensions.Logging;
namespace ConfectioneryBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly IPastryStorage _pastryStorage;
public OrderLogic(ILogger<OrderLogic> logger,
IOrderStorage orderStorage, IShopStorage shopStorage,
IShopLogic shopLogic, IPastryStorage pastryStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
_shopLogic = shopLogic;
_pastryStorage = pastryStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ 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 CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private bool ChangeStatus(OrderBindingModel model, OrderStatus status)
{
CheckModel(model);
var element = _orderStorage.GetElement(
new OrderSearchModel { Id = model.Id });
if (element == null)
{
_logger.LogWarning("Read operation failed");
return false;
}
if (element.Status != status - 1)
{
_logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа" +
" не может быть переведен в выбранный");
}
if (element.Status == OrderStatus.Готов)
{
var pastry = _pastryStorage.GetElement(new PastrySearchModel()
{ Id = model.PastryId });
if (pastry == null)
{
_logger.LogWarning("Status update to " +
status.ToString() +
" operation failed. Document not found.");
return false;
}
if (CheckSupply(pastry, model.Count) == false)
{
_logger.LogWarning("Status update to " +
status.ToString() +
" operation failed. Shop supply error.");
return false;
}
}
model.Status = status;
if (model.Status == OrderStatus.Выдан)
model.DateImplement = DateTime.Now;
_orderStorage.Update(model);
return true;
}
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.Sum <= 0)
{
throw new ArgumentNullException(
"Цена заказа должна быть больше 0", nameof(model.Sum));
}
if (model.Count <= 0)
{
throw new ArgumentNullException(
"Количество элементов в заказе должно быть больше 0",
nameof(model.Count));
}
_logger.LogInformation("Order. Sum:{ Cost}. Id: { Id}",
model.Sum, model.Id);
}
private bool CheckSupply(IPastryModel Pastry, int count)
{
if (count <= 0)
{
_logger.LogWarning(
"Check then supply operation error. Pastry count < 0.");
return false;
}
int sumCapacity = 0;
int sumCount = 0;
sumCapacity = _shopStorage.GetFullList()
.Select(x => x.MaxCapacity).Sum();
sumCount = _shopStorage.GetFullList()
.Select(x => x.ShopPastries
.Select(y => y.Value.Item2).Sum()).Sum();
int freeSpace = sumCapacity - sumCount;
if (freeSpace - count < 0)
{
_logger.LogWarning("Check then supply operation error. " +
"There's no place for new Pastry in shops.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCapacity;
foreach (var doc in shop.ShopPastries)
{
freeSpace -= doc.Value.Item2;
}
if (freeSpace == 0)
{
continue;
}
if (freeSpace - count >= 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id },
Pastry, count))
count = 0;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (freeSpace - count < 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id },
Pastry, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
}
}