PIbd-23-Yunusov-N.N.-CarRep.../CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/OrderLogic.cs
2024-04-08 01:56:52 +04:00

186 lines
6.8 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 CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts;
using CarRepairShopContracts.ViewModels;
using CarRepairShopDataModels.Enums;
using CarRepairShopDataModels.Models;
using Microsoft.Extensions.Logging;
namespace CarRepairShopBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly IRepairStorage _repairStorage;
public OrderLogic(IOrderStorage orderStorage, IShopStorage shopStorage, IShopLogic shopLogic, IRepairStorage repairStorage, ILogger<OrderLogic> logger)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
_logger = logger;
_shopLogic = shopLogic;
_repairStorage = repairStorage;
}
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 repair = _repairStorage.GetElement(new RepairSearchModel() { Id = model.RepairId });
if (repair == null)
{
_logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found.");
return false;
}
if (CheckSupply(repair, 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(IRepairModel Repair, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check then supply operation error. Repair count < 0.");
return false;
}
int sumCapacity = 0;
int sumCount = 0;
sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCapacity).Sum();
sumCount = _shopStorage.GetFullList().Select(x => x.ShopRepairs.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 Repair in shops.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCapacity;
foreach (var doc in shop.ShopRepairs)
{
freeSpace -= doc.Value.Item2;
}
if (freeSpace == 0)
{
continue;
}
if (freeSpace - count >= 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id }, Repair, count))
count = 0;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (freeSpace - count < 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id }, Repair, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
}
}