diff --git a/Shipyard/ShipyardBusinessLogic/BusinessLogics/ShopLogic.cs b/Shipyard/ShipyardBusinessLogic/BusinessLogics/ShopLogic.cs new file mode 100644 index 0000000..9c226d1 --- /dev/null +++ b/Shipyard/ShipyardBusinessLogic/BusinessLogics/ShopLogic.cs @@ -0,0 +1,147 @@ +using Microsoft.Extensions.Logging; +using ShipyardContracts.BindingModels; +using ShipyardContracts.BusinessLogicsContracts; +using ShipyardContracts.SearchModels; +using ShipyardContracts.ViewModels; +using ShipyardContracts.StoragesContracts; +using ShipyardDataModels.Models; + +namespace ShipyardBusinessLogic.BusinessLogics +{ + public class ShopLogic : IShopLogic + { + private readonly ILogger _logger; + private readonly IShopStorage _shopStorage; + public ShopLogic(ILogger logger, IShopStorage shopStorage) + { + _logger = logger; + _shopStorage = shopStorage; + } + public List? ReadList(ShopSearchModel? model) + { + _logger.LogInformation("ReadList. ShopName: {ShopName}. Id: {Id}", model?.ShopName, 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 ShopViewModel? ReadElement(ShopSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ShopName: {ShopName}. Id: {Id}", model.ShopName, model.Id); + var element = _shopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); + return element; + } + 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); + _logger.LogInformation("Delete. Id: {Id}", model.Id); + 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.ShopName)) + { + throw new ArgumentNullException("Нет названия магазина", nameof(model.ShopName)); + } + _logger.LogInformation("Shop. ShopName:{0}. Address:{1}. Id:{2}", + model.ShopName, model.Address, model.Id); + var element = _shopStorage.GetElement(new ShopSearchModel + { + ShopName = model.ShopName + }); + if (element != null && element.Id != model.Id && element.ShopName == model.ShopName) + { + throw new InvalidOperationException("Магазин с таким названием уже есть"); + } + } + + public bool AddShip(ShopSearchModel model, IShipModel ship, int count) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (count <= 0) + { + throw new ArgumentException("Количество кораблей должно быть больше 0", nameof(count)); + } + _logger.LogInformation("AddShip. ShopName:{ShopName}. Id:{Id}", model.ShopName, model.Id); + var element = _shopStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("AddShip element not found"); + return false; + } + _logger.LogInformation("AddShip find. Id:{Id}", element.Id); + + if (element.ShopShips.TryGetValue(ship.Id, out var pair)) + { + element.ShopShips[ship.Id] = (ship, count + pair.Item2); + _logger.LogInformation("AddShip. Added {count} {ship} to '{ShopName}' shop", + count, ship.ShipName, element.ShopName); + } + else + { + element.ShopShips[ship.Id] = (ship, count); + _logger.LogInformation("AddShip. Added {count} new ship {ship} to '{ShopName}' shop", + count, ship.ShipName, element.ShopName); + } + _shopStorage.Update(new() + { + Id = element.Id, + Address = element.Address, + ShopName = element.ShopName, + DateOpen = element.DateOpen, + ShopShips = element.ShopShips + }); + return true; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/BindingModels/ShopBindingModel.cs b/Shipyard/ShipyardContracts/BindingModels/ShopBindingModel.cs new file mode 100644 index 0000000..a4b2391 --- /dev/null +++ b/Shipyard/ShipyardContracts/BindingModels/ShopBindingModel.cs @@ -0,0 +1,13 @@ +using ShipyardDataModels.Models; + +namespace ShipyardContracts.BindingModels +{ + public class ShopBindingModel : IShopModel + { + public string ShopName { get; set; } = string.Empty; + public string Address { get; set; } = string.Empty; + public DateTime DateOpen { get; set; } = DateTime.Now; + public Dictionary ShopShips { get; set; } = new(); + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/BusinessLogicsContracts/IShopLogic.cs b/Shipyard/ShipyardContracts/BusinessLogicsContracts/IShopLogic.cs new file mode 100644 index 0000000..a5b3dac --- /dev/null +++ b/Shipyard/ShipyardContracts/BusinessLogicsContracts/IShopLogic.cs @@ -0,0 +1,17 @@ +using ShipyardContracts.BindingModels; +using ShipyardContracts.SearchModels; +using ShipyardContracts.ViewModels; +using ShipyardDataModels.Models; + +namespace ShipyardContracts.BusinessLogicsContracts +{ + public interface IShopLogic + { + List? ReadList(ShopSearchModel? model); + ShopViewModel? ReadElement(ShopSearchModel model); + bool Create(ShopBindingModel model); + bool Update(ShopBindingModel model); + bool Delete(ShopBindingModel model); + bool AddShip(ShopSearchModel model, IShipModel ship, int count); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/SearchModels/ShopSearchModel.cs b/Shipyard/ShipyardContracts/SearchModels/ShopSearchModel.cs new file mode 100644 index 0000000..14c5b79 --- /dev/null +++ b/Shipyard/ShipyardContracts/SearchModels/ShopSearchModel.cs @@ -0,0 +1,8 @@ +namespace ShipyardContracts.SearchModels +{ + public class ShopSearchModel + { + public int? Id { get; set; } + public string? ShopName { get; set; } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/StoragesContracts/IShopStorage.cs b/Shipyard/ShipyardContracts/StoragesContracts/IShopStorage.cs new file mode 100644 index 0000000..37c809f --- /dev/null +++ b/Shipyard/ShipyardContracts/StoragesContracts/IShopStorage.cs @@ -0,0 +1,16 @@ +using ShipyardContracts.BindingModels; +using ShipyardContracts.SearchModels; +using ShipyardContracts.ViewModels; + +namespace ShipyardContracts.StoragesContracts +{ + public interface IShopStorage + { + List GetFullList(); + List GetFilteredList(ShopSearchModel model); + ShopViewModel? GetElement(ShopSearchModel model); + ShopViewModel? Insert(ShopBindingModel model); + ShopViewModel? Update(ShopBindingModel model); + ShopViewModel? Delete(ShopBindingModel model); + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardContracts/ViewModels/ShopViewModel.cs b/Shipyard/ShipyardContracts/ViewModels/ShopViewModel.cs new file mode 100644 index 0000000..ffb1e46 --- /dev/null +++ b/Shipyard/ShipyardContracts/ViewModels/ShopViewModel.cs @@ -0,0 +1,19 @@ +using ShipyardDataModels.Models; +using System.ComponentModel; + +namespace ShipyardContracts.ViewModels +{ + public class ShopViewModel : IShopModel + { + [DisplayName("Название магазина")] + public string ShopName { get; set; } = string.Empty; + + [DisplayName("Адрес магазина")] + public string Address { get; set; } = string.Empty; + + [DisplayName("Дата открытия")] + public DateTime DateOpen { get; set; } = DateTime.Now; + public Dictionary ShopShips { get; set; } = new(); + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardDataModels/Models/IShopModel.cs b/Shipyard/ShipyardDataModels/Models/IShopModel.cs new file mode 100644 index 0000000..8ae0c90 --- /dev/null +++ b/Shipyard/ShipyardDataModels/Models/IShopModel.cs @@ -0,0 +1,10 @@ +namespace ShipyardDataModels.Models +{ + public interface IShopModel : IId + { + string ShopName { get; } + string Address { get; } + DateTime DateOpen { get; } + Dictionary ShopShips { get; } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardListImplement/DataListSingleton.cs b/Shipyard/ShipyardListImplement/DataListSingleton.cs index fd368be..5d32fb0 100644 --- a/Shipyard/ShipyardListImplement/DataListSingleton.cs +++ b/Shipyard/ShipyardListImplement/DataListSingleton.cs @@ -8,13 +8,15 @@ namespace ShipyardListImplement public List Details { get; set; } public List Orders { get; set; } public List Ships { get; set; } - private DataListSingleton() - { - Details = new List(); - Orders = new List(); - Ships = new List(); - } - public static DataListSingleton GetInstance() + public List Shops { get; set; } + private DataListSingleton() + { + Details = new List(); + Orders = new List(); + Ships = new List(); + Shops = new List(); + } + public static DataListSingleton GetInstance() { if (_instance == null) { diff --git a/Shipyard/ShipyardListImplement/Implements/ShopStorage.cs b/Shipyard/ShipyardListImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..b54f40b --- /dev/null +++ b/Shipyard/ShipyardListImplement/Implements/ShopStorage.cs @@ -0,0 +1,107 @@ +using ShipyardContracts.BindingModels; +using ShipyardContracts.SearchModels; +using ShipyardContracts.StoragesContracts; +using ShipyardContracts.ViewModels; +using ShipyardListImplement.Models; + +namespace ShipyardListImplement.Implements +{ + public class ShopStorage : IShopStorage + { + private readonly DataListSingleton _source; + + public ShopStorage() + { + _source = DataListSingleton.GetInstance(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + foreach (var shop in _source.Shops) + { + if ((!string.IsNullOrEmpty(model.ShopName) && shop.ShopName == model.ShopName) || (model.Id.HasValue && shop.Id == model.Id)) + { + return shop.GetViewModel; + } + } + return null; + } + + public List GetFilteredList(ShopSearchModel model) + { + var result = new List(); + if (string.IsNullOrEmpty(model.ShopName)) + { + return result; + } + foreach (var shop in _source.Shops) + { + if (shop.ShopName.Contains(model.ShopName)) + { + result.Add(shop.GetViewModel); + } + } + return result; + } + + public List GetFullList() + { + var result = new List(); + foreach (var shop in _source.Shops) + { + result.Add(shop.GetViewModel); + } + return result; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + model.Id = 1; + foreach (var shop in _source.Shops) + { + if (model.Id <= shop.Id) + { + model.Id = shop.Id + 1; + } + } + var newShop = Shop.Create(model); + if (newShop == null) + { + return null; + } + _source.Shops.Add(newShop); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + foreach (var shop in _source.Shops) + { + if (shop.Id == model.Id) + { + shop.Update(model); + return shop.GetViewModel; + } + } + return null; + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + for (int i = 0; i < _source.Shops.Count; ++i) + { + if (_source.Shops[i].Id == model.Id) + { + var element = _source.Shops[i]; + _source.Shops.RemoveAt(i); + return element.GetViewModel; + } + } + return null; + } + } +} \ No newline at end of file diff --git a/Shipyard/ShipyardListImplement/Models/Shop.cs b/Shipyard/ShipyardListImplement/Models/Shop.cs new file mode 100644 index 0000000..72c1590 --- /dev/null +++ b/Shipyard/ShipyardListImplement/Models/Shop.cs @@ -0,0 +1,54 @@ +using ShipyardContracts.BindingModels; +using ShipyardContracts.ViewModels; +using ShipyardDataModels.Models; + +namespace ShipyardListImplement.Models +{ + public class Shop : IShopModel + { + public string ShopName { get; set; } = string.Empty; + + public string Address { get; set; } = string.Empty; + + public DateTime DateOpen { get; set; } + public int Id { get; set; } + public Dictionary ShopShips { get; private set; } = new Dictionary(); + + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpen = model.DateOpen, + ShopShips = model.ShopShips + }; + } + + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + ShopName = model.ShopName; + Address = model.Address; + DateOpen = model.DateOpen; + ShopShips = model.ShopShips; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpen = DateOpen, + ShopShips = ShopShips + }; + } +} \ No newline at end of file