Алексей Крюков af3573a8d8 done
2024-04-22 11:48:48 +04:00

185 lines
6.6 KiB
C#
Raw Permalink 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 TypographyContracts.BusinessLogicsContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypographyContracts.BindingModels;
using TypographyContracts.SearchModels;
using TypographyContracts.StoragesContracts;
using TypographyContracts.ViewModels;
using TypographyDataModels.Enums;
using Microsoft.Extensions.Logging;
using TypographyDataModels.Models;
namespace TypographyBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly IPrintedStorage _printedStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopStorage shopStorage, IShopLogic shopLogic, IPrintedStorage printedStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
_shopLogic = shopLogic;
_printedStorage = printedStorage;
}
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)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private void CheckModel(OrderBindingModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество заказов должно быть больше нуля");
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Цена заказа должна быть больше нуля");
}
_logger.LogInformation("Order. OrderId:{Id}. Sum:{Sum}", model.Id, model.Sum);
}
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.Выдан);
}
public bool CheckSupply(IPrintedModel printed, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check supply operation error. Printed count < 0");
return false;
}
int Capacity = _shopStorage.GetFullList().Select(x => x.MaxCountPrinteds).Sum();
int currentCount = _shopStorage.GetFullList().Select(x => x.ShopPrinteds.Select(y => y.Value.Item2).Sum()).Sum();
int freeSpace = Capacity - currentCount;
if (freeSpace < count)
{
_logger.LogWarning("Check supply error. No place for new Printeds");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCountPrinteds;
foreach (var doc in shop.ShopPrinteds)
{
freeSpace -= doc.Value.Item2;
}
if (freeSpace == 0)
{
continue;
}
if (freeSpace >= count)
{
if (_shopLogic.MakeShipment(new()
{
Id = shop.Id
}, printed, count))
{
count = 0;
}
else
{
_logger.LogWarning("Supply error");
return false;
}
}
else
{
if (_shopLogic.MakeShipment(new() { Id = shop.Id }, printed, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
private bool ChangeStatus(OrderBindingModel model, OrderStatus status)
{
var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (element == null)
{
_logger.LogWarning("Find order failed");
return false;
}
if (element.Status != status - 1)
{
_logger.LogWarning("Status change failed");
throw new InvalidOperationException("Невозможно перевести состояние заказа");
}
if (status == OrderStatus.Готов)
{
var printed = _printedStorage.GetElement(new PrintedSearchModel() { Id = model.PrintedId });
if (printed == null)
{
_logger.LogWarning("Status change error. Printed not found");
return false;
}
if (!CheckSupply(printed, model.Count))
{
_logger.LogWarning("Status change error. Shop doesnt have printedes");
return false;
}
}
model.Status = status;
if (model.Status == OrderStatus.Выдан) model.DateImplement = DateTime.Now;
_orderStorage.Update(model);
return true;
}
}
}