225 lines
7.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 Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDataModels.Models;
using System.Reflection;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
{
_logger = logger;
_shopStorage = shopStorage;
}
public ShopViewModel? ReadElement(ShopSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Shop Name:{0}, ID:{1}", model.Name, model.Id);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement. element not found");
return null;
}
_logger.LogInformation("ReadElement found. Id:{Id}", element.Id);
return element;
}
public List<ShopViewModel>? ReadList(ShopSearchModel? model)
{
_logger.LogInformation("ReadList. Shop Name:{0}, ID:{1} ", model?.Name, model?.Id);
var list = (model == null) ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Create(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ShopBindingModel model)
{
CheckModel(model, false);
if (_shopStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ShopBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Name))
{
throw new ArgumentNullException("Нет названия магазина!", nameof(model.Name));
}
_logger.LogInformation("Shop. Name: {0}, Address: {1}, ID: {2}", model.Name, model.Address, model.Id);
var element = _shopStorage.GetElement(new ShopSearchModel
{
Name = model.Name
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
public bool SupplySecures(ShopSearchModel model, ISecureModel secure, int count)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (secure == null)
{
throw new ArgumentNullException(nameof(secure));
}
if (count <= 0)
{
throw new ArgumentNullException("Количество продукта для пополнения должно быть больше 0", nameof(count));
}
var shopElement = _shopStorage.GetElement(model);
if (shopElement == null)
{
_logger.LogWarning("Required shop element not found in storage");
return false;
}
_logger.LogInformation("Shop element found. ID: {0}, Name: {1}", shopElement.Id, shopElement.Name);
if (GetFreeSpace(shopElement.Id) < count)
{
throw new InvalidOperationException("В магазине не хватает места");
}
if (shopElement.ShopSecures.TryGetValue(secure.Id, out var sameSecure))
{
shopElement.ShopSecures[secure.Id] = (secure, sameSecure.Item2 + count);
_logger.LogInformation("Same secure found by supply. Added {0} of {1} in {2} shop", count, secure.SecureName, shopElement.Name);
}
else
{
shopElement.ShopSecures[secure.Id] = (secure, count);
_logger.LogInformation("New secure added by supply. Added {0} of {1} in {2} shop", count, secure.SecureName, shopElement.Name);
}
_shopStorage.Update(new()
{
Id = shopElement.Id,
Name = shopElement.Name,
Address = shopElement.Address,
OpeningDate = shopElement.OpeningDate,
ShopSecures = shopElement.ShopSecures,
MaxSecuresCount = shopElement.MaxSecuresCount
});
return true;
}
public bool SupplySecures(ISecureModel secure, int count)
{
if (!CheckSupplySecures(count))
{
throw new InvalidOperationException("Невозможно пополнить: в магазинах не хватает места");
}
var shops = _shopStorage.GetFullList();
foreach (var shop in shops)
{
int shopFreeSpace = GetFreeSpace(shop.Id);
if (shopFreeSpace > 0 && count > 0)
{
int min = Math.Min(count, shopFreeSpace);
count -= min;
SupplySecures(new ShopSearchModel { Id = shop.Id }, secure, min);
}
}
return true;
}
public bool SellSecures(ISecureModel model, int count)
{
return _shopStorage.SellSecures(model, count);
}
public bool CheckSupplySecures(int count)
{
return GetFreeSpace() >= count;
}
private int GetFreeSpace()
{
var shops = _shopStorage.GetFullList();
return shops.Select(shop => shop.MaxSecuresCount - shop.ShopSecures.Select(shopSecure => shopSecure.Value.Item2).Sum()).Sum();
}
private int GetFreeSpace(int shopId)
{
var shop = _shopStorage.GetElement(new ShopSearchModel { Id = shopId });
return shop.MaxSecuresCount - shop.ShopSecures.Select(shopSecure => shopSecure.Value.Item2).Sum();
}
}
}