diff --git a/PrecastConcretePlant/PrecastConcretePlantBusinessLogic/ShopLogic.cs b/PrecastConcretePlant/PrecastConcretePlantBusinessLogic/ShopLogic.cs index 6929890..de45dd1 100644 --- a/PrecastConcretePlant/PrecastConcretePlantBusinessLogic/ShopLogic.cs +++ b/PrecastConcretePlant/PrecastConcretePlantBusinessLogic/ShopLogic.cs @@ -100,6 +100,12 @@ namespace PrecastConcretePlantBusinessLogic throw new ArgumentNullException("Нет названия магазина", nameof(model.Name)); } + if (model.MaxCountReinforceds < 0) + { + throw new ArgumentException( + "Максимальное количество изделий в магазине не должно быть отрицательным", + nameof(model.MaxCountReinforceds)); + } _logger.LogInformation("Shop. ShopName:{0}.Address:{1}. Id: {2}", model.Name, model.Address, model.Id); var element = _shopStorage.GetElement(new ShopSearchModel @@ -149,5 +155,53 @@ namespace PrecastConcretePlantBusinessLogic }); return true; } + + public int GetFreePlacesWithReinforcedsInShops(int countReinforceds) + { + return _shopStorage.GetFullList() + .Select(x => x.MaxCountReinforceds - x.Reinforceds + .Select(p => p.Value.Item2).Sum()) + .Sum() - countReinforceds; + } + + public bool AddReinforcedsInShops(IReinforcedModel reinforced, int count) + { + if (count <= 0) + { + _logger.LogWarning("AddReinforcedsInShops. Количество добавляемых изделий должно быть больше 0. Количество - {count}", count); + return false; + } + var freePlaces = GetFreePlacesWithReinforcedsInShops(count); + if (freePlaces < 0) + { + _logger.LogInformation("AddReinforcedsInShops. Не удалось добавить изделия в магазины, поскольку они переполнены." + + "Освободите магазины на {places} изделий", -freePlaces); + return false; + } + foreach (var shop in _shopStorage.GetFullList()) + { + var cnt = Math.Min(count, shop.MaxCountReinforceds - shop.Reinforceds.Select(x => x.Value.Item2).Sum()); + if (cnt <= 0) + { + continue; + } + if (!AddReinforced(new() { Id = shop.Id }, reinforced, cnt)) + { + _logger.LogWarning("При добавления изделий во все магазины произошла ошибка"); + return false; + } + count -= cnt; + if (count == 0) + { + return true; + } + } + return true; + } + + public bool SellReinforceds(IReinforcedModel reinforced, int needCount) + { + return _shopStorage.SellReinforceds(reinforced, needCount); + } } } diff --git a/PrecastConcretePlant/PrecastConcretePlantFileImplement/DataFileSingleton.cs b/PrecastConcretePlant/PrecastConcretePlantFileImplement/DataFileSingleton.cs index 5ae7a7d..2a44e84 100644 --- a/PrecastConcretePlant/PrecastConcretePlantFileImplement/DataFileSingleton.cs +++ b/PrecastConcretePlant/PrecastConcretePlantFileImplement/DataFileSingleton.cs @@ -9,9 +9,11 @@ namespace PrecastConcretePlantFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string ReinforcedFileName = "Reinforced.xml"; + private readonly string ShopFileName = "Shop.xml"; public List Components { get; set; } public List Orders { get; set; } public List Reinforceds { get; set; } + public List Shops { get; private set; } public static DataFileSingleton GetInstance() { @@ -24,12 +26,14 @@ namespace PrecastConcretePlantFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); public void SaveReinforceds() => SaveData(Reinforceds, ReinforcedFileName, "Reinforceds", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement); private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Reinforceds = LoadData(ReinforcedFileName, "Reinforced", x => Reinforced.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!; } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) { diff --git a/PrecastConcretePlant/PrecastConcretePlantFileImplement/ShopStorage.cs b/PrecastConcretePlant/PrecastConcretePlantFileImplement/ShopStorage.cs index a10b774..eda8adb 100644 --- a/PrecastConcretePlant/PrecastConcretePlantFileImplement/ShopStorage.cs +++ b/PrecastConcretePlant/PrecastConcretePlantFileImplement/ShopStorage.cs @@ -8,44 +8,106 @@ namespace PrecastConcretePlantFileImplement { public class ShopStorage : IShopStorage { + private readonly DataFileSingleton _source; + public ShopStorage() + { + _source = DataFileSingleton.GetInstance(); + } + public ShopViewModel? Delete(ShopBindingModel model) { - throw new NotImplementedException(); + var element = _source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + _source.Shops.Remove(element); + _source.SaveShops(); + return element.GetViewModel; + } + return null; } public ShopViewModel? GetElement(ShopSearchModel model) { - throw new NotImplementedException(); + if (!model.Id.HasValue) + { + return null; + } + return _source.Shops.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; } public List GetFilteredList(ShopSearchModel model) { - throw new NotImplementedException(); + if (string.IsNullOrEmpty(model.Name)) + { + return new(); + } + return _source.Shops + .Select(x => x.GetViewModel) + .Where(x => x.Name.Contains(model.Name ?? string.Empty)) + .ToList(); } public List GetFullList() { - throw new NotImplementedException(); - } - - public bool HasNeedReinforceds(IReinforcedModel reinforced, int needCount) - { - throw new NotImplementedException(); + return _source.Shops + .Select(shop => shop.GetViewModel) + .ToList(); } public ShopViewModel? Insert(ShopBindingModel model) { - throw new NotImplementedException(); - } - - public bool SellReinforceds(IReinforcedModel reinforced, int needCount) - { - throw new NotImplementedException(); + model.Id = _source.Shops.Count > 0 ? _source.Shops.Max(x => x.Id) + 1 : 1; + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + _source.Shops.Add(newShop); + _source.SaveShops(); + return newShop.GetViewModel; } public ShopViewModel? Update(ShopBindingModel model) { - throw new NotImplementedException(); + var shop = _source.Shops.FirstOrDefault(x => x.Id == model.Id); + if (shop == null) + { + return null; + } + shop.Update(model); + _source.SaveShops(); + return shop.GetViewModel; + } + + public bool HasNeedReinforceds(IReinforcedModel reinforced, int needCount) + { + var resultCount = _source.Shops + .Select(shop => shop.Reinforceds + .FirstOrDefault(x => x.Key == reinforced.Id).Value.Item2) + .Sum(); + return resultCount >= needCount; + } + + public bool SellReinforceds(IReinforcedModel reinforced, int needCount) + { + if (!HasNeedReinforceds(reinforced, needCount)) + { + return false; + } + foreach (var shop in _source.Shops.Where(shop => shop.Reinforceds.ContainsKey(reinforced.Id))) + { + var tuple = shop.Reinforceds[reinforced.Id]; + var diff = Math.Min(tuple.Item2, needCount); + shop.Reinforceds[reinforced.Id] = (tuple.Item1, tuple.Item2 - diff); + + needCount -= diff; + if (needCount <= 0) + { + return true; + } + } + + return true; } } } diff --git a/PrecastConcretePlant/PrecastConcretePlantListImplement/Shop.cs b/PrecastConcretePlant/PrecastConcretePlantListImplement/Shop.cs index 1d07d25..fcbaa3c 100644 --- a/PrecastConcretePlant/PrecastConcretePlantListImplement/Shop.cs +++ b/PrecastConcretePlant/PrecastConcretePlantListImplement/Shop.cs @@ -11,6 +11,8 @@ namespace PrecastConcretePlantListImplement public string Address { get; private set; } = string.Empty; + public int MaxCountReinforceds { get; private set; } + public DateTime DateOpening { get; private set; } public Dictionary Reinforceds @@ -33,6 +35,7 @@ namespace PrecastConcretePlantListImplement Name = model.Name, Address = model.Address, DateOpening = model.DateOpening, + MaxCountReinforceds = model.MaxCountReinforceds, Reinforceds = new() }; } @@ -45,6 +48,7 @@ namespace PrecastConcretePlantListImplement Name = model.Name; Address = model.Address; DateOpening = model.DateOpening; + MaxCountReinforceds = model.MaxCountReinforceds; Reinforceds = model.Reinforceds; } public ShopViewModel GetViewModel => new() @@ -54,6 +58,7 @@ namespace PrecastConcretePlantListImplement Address = Address, Reinforceds = Reinforceds, DateOpening = DateOpening, + MaxCountReinforceds = MaxCountReinforceds, }; } } diff --git a/PrecastConcretePlant/PrecastConcretePlantListImplement/ShopStorage.cs b/PrecastConcretePlant/PrecastConcretePlantListImplement/ShopStorage.cs index fab9bd4..1a0e2bd 100644 --- a/PrecastConcretePlant/PrecastConcretePlantListImplement/ShopStorage.cs +++ b/PrecastConcretePlant/PrecastConcretePlantListImplement/ShopStorage.cs @@ -2,6 +2,7 @@ using PrecastConcretePlantContracts.SearchModels; using PrecastConcretePlantContracts.StoragesContract; using PrecastConcretePlantContracts.ViewModels; +using PrecastConcretePlantDataModels.Models; namespace PrecastConcretePlantListImplement { @@ -103,5 +104,15 @@ namespace PrecastConcretePlantListImplement } return null; } + + public bool HasNeedReinforceds(IReinforcedModel reinforced, int needCount) + { + throw new NotImplementedException(); + } + + public bool SellReinforceds(IReinforcedModel reinforced, int needCount) + { + throw new NotImplementedException(); + } } }