diff --git a/ConfectionaryBusinessLogic/OrderLogic.cs b/ConfectionaryBusinessLogic/OrderLogic.cs index 1471185..3a57520 100644 --- a/ConfectionaryBusinessLogic/OrderLogic.cs +++ b/ConfectionaryBusinessLogic/OrderLogic.cs @@ -12,10 +12,14 @@ namespace ConfectioneryBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + private readonly IPastryStorage _pastryStorage; + private readonly IShopLogic _shopLogic; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IPastryStorage pastryStorage, IShopLogic shopLogic) { _logger = logger; + _shopLogic = shopLogic; + _pastryStorage = pastryStorage; _orderStorage = orderStorage; } @@ -96,6 +100,15 @@ namespace ConfectioneryBusinessLogic.BusinessLogics $"Доступный статус: {(OrderStatus)((int)vmodel.Status + 1)}", nameof(vmodel)); } + if (orderStatus == OrderStatus.Готов) + { + var vpastry = _pastryStorage.GetElement(new() { Id = vmodel.PastryId }); + + if (vpastry == null || !_shopLogic.AddPastriesInShops(vpastry, vmodel.Count)) + { + throw new Exception($"Не удалось заполнить магазины изделием '{vpastry?.PastryName ?? string.Empty}' из заказа {vmodel.Id}"); + } + } model.Status = orderStatus; model.DateCreate = vmodel.DateCreate; if (model.DateImplement == null) diff --git a/ConfectionaryBusinessLogic/ShopLogic.cs b/ConfectionaryBusinessLogic/ShopLogic.cs index b6fb992..136e142 100644 --- a/ConfectionaryBusinessLogic/ShopLogic.cs +++ b/ConfectionaryBusinessLogic/ShopLogic.cs @@ -101,6 +101,13 @@ namespace ConfectioneryBusinessLogic throw new ArgumentNullException("Нет названия магазина", nameof(model.Name)); } + if (model.MaxCountPastries < 0) + { + throw new ArgumentException( + "Максимальное количество изделий в магазине не должно быть отрицательным", + nameof(model.MaxCountPastries)); + } + _logger.LogInformation("Shop. ShopName:{0}.Address:{1}. Id: {2}", model.Name, model.Address, model.Id); var element = _shopStorage.GetElement(new ShopSearchModel @@ -150,5 +157,55 @@ namespace ConfectioneryBusinessLogic }); return true; } + + + public int GetFreePlacesWithPastriesInShops(int countPastries) + { + // Сумма разностей между максимальный кол-вом изделий и суммой всех изделий в магазине + return _shopStorage.GetFullList() + .Select(x => x.MaxCountPastries - x.Pastries + .Select(p => p.Value.Item2).Sum()) + .Sum() - countPastries; + } + + public bool AddPastriesInShops(IPastryModel pastry, int count) + { + if (count <= 0) + { + _logger.LogWarning("AddPastriesInShops. Количество добавляемых изделий должно быть больше 0. Количество - {count}", count); + return false; + } + var freePlaces = GetFreePlacesWithPastriesInShops(count); + if (freePlaces < 0) + { + _logger.LogInformation("AddPastriesInShops. Не удалось добавить изделия в магазины, поскольку они переполнены." + + "Освободите магазины на {places} изделий", -freePlaces); + return false; + } + foreach (var shop in _shopStorage.GetFullList()) + { + var cnt = Math.Min(count, shop.MaxCountPastries - shop.Pastries.Select(x => x.Value.Item2).Sum()); + if (cnt <= 0) + { + continue; + } + if (!AddPastry(new() { Id = shop.Id }, pastry, cnt)) + { + _logger.LogWarning("При добавления изделий во все магазины произошла ошибка"); + return false; + } + count -= cnt; + if (count == 0) + { + return true; + } + } + return true; + } + + public bool SellPastries(IPastryModel pastry, int needCount) + { + return _shopStorage.SellPastries(pastry, needCount); + } } } diff --git a/ConfectionaryFileImplement/Component.cs b/ConfectionaryFileImplement/Component.cs new file mode 100644 index 0000000..91da900 --- /dev/null +++ b/ConfectionaryFileImplement/Component.cs @@ -0,0 +1,60 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using System.Xml.Linq; + + +namespace ConfectioneryFileImplement.Models +{ + public class Component : IComponentModel + { + public int Id { get; private set; } + public string ComponentName { get; private set; } = string.Empty; + public double Cost { get; set; } + public static Component? Create(ComponentBindingModel model) + { + if (model == null) + { + return null; + } + return new Component() + { + Id = model.Id, + ComponentName = model.ComponentName, + Cost = model.Cost + }; + } + public static Component? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Component() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + ComponentName = element.Element("ComponentName")!.Value, + Cost = Convert.ToDouble(element.Element("Cost")!.Value) + }; + } + public void Update(ComponentBindingModel model) + { + if (model == null) + { + return; + } + ComponentName = model.ComponentName; + Cost = model.Cost; + } + public ComponentViewModel GetViewModel => new() + { + Id = Id, + ComponentName = ComponentName, + Cost = Cost + }; + public XElement GetXElement => new("Component", + new XAttribute("Id", Id), + new XElement("ComponentName", ComponentName), + new XElement("Cost", Cost.ToString())); + } +} \ No newline at end of file diff --git a/ConfectionaryFileImplement/ComponentStorage.cs b/ConfectionaryFileImplement/ComponentStorage.cs new file mode 100644 index 0000000..2293b9a --- /dev/null +++ b/ConfectionaryFileImplement/ComponentStorage.cs @@ -0,0 +1,79 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContract; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; + +namespace ConfectioneryFileImplement.Implements +{ + public class ComponentStorage : IComponentStorage + { + private readonly DataFileSingleton _source; + public ComponentStorage() + { + _source = DataFileSingleton.GetInstance(); + } + public List GetFullList() + { + return _source.Components + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ComponentSearchModel model) + { + if (string.IsNullOrEmpty(model.ComponentName)) + { + return new(); + } + return _source.Components + .Where(x => x.ComponentName.Contains(model.ComponentName)) + .Select(x => x.GetViewModel) + .ToList(); + } + public ComponentViewModel? GetElement(ComponentSearchModel model) + { + if (string.IsNullOrEmpty(model.ComponentName) && !model.Id.HasValue) + { + return null; + } + return _source.Components.FirstOrDefault(x => + (!string.IsNullOrEmpty(model.ComponentName) && + x.ComponentName == model.ComponentName) || + (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + public ComponentViewModel? Insert(ComponentBindingModel model) + { + model.Id = _source.Components.Count > 0 ? _source.Components.Max(x => x.Id) + 1 : 1; + var newComponent = Component.Create(model); + if (newComponent == null) + { + return null; + } + _source.Components.Add(newComponent); + _source.SaveComponents(); + return newComponent.GetViewModel; + } + public ComponentViewModel? Update(ComponentBindingModel model) + { + var component = _source.Components.FirstOrDefault(x => x.Id == model.Id); + if (component == null) + { + return null; + } + component.Update(model); + _source.SaveComponents(); + return component.GetViewModel; + } + public ComponentViewModel? Delete(ComponentBindingModel model) + { + var element = _source.Components.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + _source.Components.Remove(element); + _source.SaveComponents(); + return element.GetViewModel; + } + return null; + } + } +} \ No newline at end of file diff --git a/ConfectionaryFileImplement/ConfectioneryFileImplement.csproj b/ConfectionaryFileImplement/ConfectioneryFileImplement.csproj new file mode 100644 index 0000000..41b6c3e --- /dev/null +++ b/ConfectionaryFileImplement/ConfectioneryFileImplement.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/ConfectionaryFileImplement/DataFileSingleton.cs b/ConfectionaryFileImplement/DataFileSingleton.cs new file mode 100644 index 0000000..ac19587 --- /dev/null +++ b/ConfectionaryFileImplement/DataFileSingleton.cs @@ -0,0 +1,54 @@ +using ConfectioneryFileImplement.Models; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement +{ + public class DataFileSingleton + { + private static DataFileSingleton? instance; + private readonly string ComponentFileName = "Component.xml"; + private readonly string OrderFileName = "Order.xml"; + private readonly string PastryFileName = "Pastry.xml"; + private readonly string ShopFileName = "Shop.xml"; + public List Components { get; private set; } + public List Orders { get; private set; } + public List Pastries { get; private set; } + public List Shops { get; private set; } + + public static DataFileSingleton GetInstance() + { + if (instance == null) + { + instance = new DataFileSingleton(); + } + return instance; + } + public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement); + public void SavePastries() => SaveData(Pastries, PastryFileName, "Pastries", 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)!)!; + Pastries = LoadData(PastryFileName, "Pastry", x => Pastry.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) + { + if (File.Exists(filename)) + { + return XDocument.Load(filename)?.Root?.Elements(xmlNodeName)?.Select(selectFunction)?.ToList(); + } + return new List(); + } + private static void SaveData(List data, string filename, string xmlNodeName, Func selectFunction) + { + if (data != null) + { + new XDocument(new XElement(xmlNodeName, data.Select(selectFunction).ToArray())).Save(filename); + } + } + } +} diff --git a/ConfectionaryFileImplement/Order.cs b/ConfectionaryFileImplement/Order.cs new file mode 100644 index 0000000..8a00130 --- /dev/null +++ b/ConfectionaryFileImplement/Order.cs @@ -0,0 +1,96 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Enums; +using ConfectioneryDataModels.Models; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Order : IOrderModel + { + public int Id { get; private set; } + + public int PastryId { get; private set; } + + public int Count { get; private set; } + + public double Sum { get; private set; } + + public OrderStatus Status { get; private set; } + + public DateTime DateCreate { get; private set; } + + public DateTime? DateImplement { get; private set; } + + public static Order? Create(OrderBindingModel? model) + { + if (model == null) + { + return null; + } + return new Order() + { + PastryId = model.PastryId, + Count = model.Count, + Sum = model.Sum, + Status = model.Status, + DateCreate = model.DateCreate, + DateImplement = model.DateImplement, + Id = model.Id, + }; + } + public static Order? Create(XElement element) + { + if (element == null) + { + return null; + } + var dateImplement = element.Element("DateImplement")!.Value; + return new() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + Sum = Convert.ToDouble(element.Element("Sum")!.Value), + Count = Convert.ToInt32(element.Element("Count")!.Value), + Status = (OrderStatus)Convert.ToInt32(element.Element("Status")!.Value), + PastryId = Convert.ToInt32(element.Element("PastryId")!.Value), + DateCreate = Convert.ToDateTime(element.Element("DateCreate")!.Value), + DateImplement = string.IsNullOrEmpty(dateImplement) ? null : Convert.ToDateTime(dateImplement), + }; + } + + public void Update(OrderBindingModel? model) + { + if (model == null) + { + return; + } + PastryId = model.PastryId; + Count = model.Count; + Sum = model.Sum; + Status = model.Status; + DateCreate = model.DateCreate; + DateImplement = model.DateImplement; + Id = model.Id; + } + public OrderViewModel GetViewModel => new() + { + PastryName = DataFileSingleton.GetInstance().Pastries.FirstOrDefault(x => x.Id == PastryId)?.PastryName ?? string.Empty, + PastryId = PastryId, + Count = Count, + Sum = Sum, + Status = Status, + DateCreate = DateCreate, + DateImplement = DateImplement, + Id = Id, + }; + public XElement GetXElement => new("Order", + new XAttribute("Id", Id), + new XElement("PastryId", PastryId), + new XElement("Count", Count), + new XElement("Sum", Sum.ToString()), + new XElement("Status", (int)Status), + new XElement("DateCreate", DateCreate), + new XElement("DateImplement", DateImplement) + ); + } +} diff --git a/ConfectionaryFileImplement/OrderStorage.cs b/ConfectionaryFileImplement/OrderStorage.cs new file mode 100644 index 0000000..c2dc788 --- /dev/null +++ b/ConfectionaryFileImplement/OrderStorage.cs @@ -0,0 +1,76 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContract; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; + +namespace ConfectioneryFileImplement +{ + public class OrderStorage : IOrderStorage + { + private readonly DataFileSingleton _source; + public OrderStorage() + { + _source = DataFileSingleton.GetInstance(); + } + + public OrderViewModel? Delete(OrderBindingModel model) + { + var element = _source.Orders.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + _source.Orders.Remove(element); + _source.SaveOrders(); + return element.GetViewModel; + } + return null; + } + + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + return _source.Orders.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(OrderSearchModel model) + { + var result = GetElement(model); + return result != null ? new() { result } : new(); + } + + public List GetFullList() + { + return _source.Orders + .Select(x => x.GetViewModel) + .ToList(); + } + + public OrderViewModel? Insert(OrderBindingModel model) + { + model.Id = _source.Orders.Count > 0 ? _source.Orders.Max(x => x.Id) + 1 : 1; + var newOrder = Order.Create(model); + if (newOrder == null) + { + return null; + } + _source.Orders.Add(newOrder); + _source.SaveOrders(); + return newOrder.GetViewModel; + } + + public OrderViewModel? Update(OrderBindingModel model) + { + var order = _source.Orders.FirstOrDefault(x => x.Id == model.Id); + if (order == null) + { + return null; + } + order.Update(model); + _source.SaveOrders(); + return order.GetViewModel; + } + } +} diff --git a/ConfectionaryFileImplement/Pastry.cs b/ConfectionaryFileImplement/Pastry.cs new file mode 100644 index 0000000..6138c0c --- /dev/null +++ b/ConfectionaryFileImplement/Pastry.cs @@ -0,0 +1,86 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement.Models +{ + public class Pastry : IPastryModel + { + public int Id { get; private set; } + public string PastryName { get; private set; } = string.Empty; + public double Price { get; private set; } + public Dictionary Components { get; private set; } = new(); + private Dictionary? _PastryComponents = null; + public Dictionary PastryComponents + { + get + { + if (_PastryComponents == null) + { + var source = DataFileSingleton.GetInstance(); + _PastryComponents = Components.ToDictionary(x => x.Key, y => + ((source.Components.FirstOrDefault(z => z.Id == y.Key) as IComponentModel)!, + y.Value)); + } + return _PastryComponents; + } + } + public static Pastry? Create(PastryBindingModel model) + { + if (model == null) + { + return null; + } + return new Pastry() + { + Id = model.Id, + PastryName = model.PastryName, + Price = model.Price, + Components = model.PastryComponents.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + public static Pastry? Create(XElement element) + { + if (element == null) + { + return null; + } + return new Pastry() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + PastryName = element.Element("PastryName")!.Value, + Price = Convert.ToDouble(element.Element("Price")!.Value), + Components = element.Element("PastryComponents")!.Elements("PastryComponent").ToDictionary(x => + Convert.ToInt32(x.Element("Key")?.Value), x => + Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + public void Update(PastryBindingModel model) + { + if (model == null) + { + return; + } + PastryName = model.PastryName; + Price = model.Price; + Components = model.PastryComponents.ToDictionary(x => x.Key, x => x.Value.Item2); + _PastryComponents = null; + } + public PastryViewModel GetViewModel => new() + { + Id = Id, + PastryName = PastryName, + Price = Price, + PastryComponents = PastryComponents + }; + public XElement GetXElement => new("Pastry", + new XAttribute("Id", Id), + new XElement("PastryName", PastryName), + new XElement("Price", Price.ToString()), + new XElement("PastryComponents", Components.Select(x => + new XElement("PastryComponent", + new XElement("Key", x.Key), + new XElement("Value", x.Value))).ToArray())); + } +} \ No newline at end of file diff --git a/ConfectionaryFileImplement/PastryStorage.cs b/ConfectionaryFileImplement/PastryStorage.cs new file mode 100644 index 0000000..4e03c2c --- /dev/null +++ b/ConfectionaryFileImplement/PastryStorage.cs @@ -0,0 +1,85 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContract; +using ConfectioneryContracts.ViewModels; +using ConfectioneryFileImplement.Models; + +namespace ConfectioneryFileImplement +{ + public class PastryStorage : IPastryStorage + { + private readonly DataFileSingleton _source; + public PastryStorage() + { + _source = DataFileSingleton.GetInstance(); + } + + public PastryViewModel? Delete(PastryBindingModel model) + { + var element = _source.Pastries.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + _source.Pastries.Remove(element); + _source.SavePastries(); + return element.GetViewModel; + } + return null; + } + + public PastryViewModel? GetElement(PastrySearchModel model) + { + if (string.IsNullOrEmpty(model.PastryName) && !model.Id.HasValue) + { + return null; + } + return _source.Pastries.FirstOrDefault + (x => (!string.IsNullOrEmpty(model.PastryName) && x.PastryName == model.PastryName) || + (model.Id.HasValue && x.Id == model.Id) + )?.GetViewModel; + } + + public List GetFilteredList(PastrySearchModel model) + { + if (string.IsNullOrEmpty(model.PastryName)) + { + return new(); + } + return _source.Pastries + .Select(x => x.GetViewModel) + .Where(x => x.PastryName.Contains(model.PastryName)) + .ToList(); + } + + public List GetFullList() + { + return _source.Pastries + .Select(x => x.GetViewModel) + .ToList(); + } + + public PastryViewModel? Insert(PastryBindingModel model) + { + model.Id = _source.Pastries.Count > 0 ? _source.Pastries.Max(x => x.Id) + 1 : 1; + var newPastry = Pastry.Create(model); + if (newPastry == null) + { + return null; + } + _source.Pastries.Add(newPastry); + _source.SavePastries(); + return newPastry.GetViewModel; + } + + public PastryViewModel? Update(PastryBindingModel model) + { + var pastry = _source.Pastries.FirstOrDefault(x => x.Id == model.Id); + if (pastry == null) + { + return null; + } + pastry.Update(model); + _source.SavePastries(); + return pastry.GetViewModel; + } + } +} diff --git a/ConfectionaryFileImplement/Shop.cs b/ConfectionaryFileImplement/Shop.cs new file mode 100644 index 0000000..928faf6 --- /dev/null +++ b/ConfectionaryFileImplement/Shop.cs @@ -0,0 +1,109 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels; +using ConfectioneryDataModels.Models; +using System.Xml.Linq; + +namespace ConfectioneryFileImplement +{ + public class Shop : IShopModel + { + public string Name { get; private set; } = string.Empty; + + public string Address { get; private set; } = string.Empty; + + public int MaxCountPastries { get; private set; } + + public DateTime DateOpening { get; private set; } + + public Dictionary CountPastries { get; private set; } = new(); + + private Dictionary? _cachedPastries = null; + public Dictionary Pastries + { + get + { + if (_cachedPastries == null) + { + var source = DataFileSingleton.GetInstance(); + _cachedPastries = CountPastries + .ToDictionary(x => x.Key, x => (source.Pastries + .FirstOrDefault(y => y.Id == x.Key)! as IPastryModel, x.Value)); + } + return _cachedPastries; + } + } + + public int Id { get; private set; } + + public static Shop? Create(ShopBindingModel? model) + { + if (model == null) + { + return null; + } + return new Shop() + { + Id = model.Id, + Name = model.Name, + Address = model.Address, + DateOpening = model.DateOpening, + MaxCountPastries = model.MaxCountPastries, + CountPastries = new() + }; + } + public static Shop? Create(XElement element) + { + if (element == null) + { + return null; + } + return new() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + Name = element.Element("Name")!.Value, + Address = element.Element("Address")!.Value, + DateOpening = Convert.ToDateTime(element.Element("DateOpening")!.Value), + MaxCountPastries = Convert.ToInt32(element.Element("MaxCountPastries")!.Value), + CountPastries = element.Element("CountPastries")!.Elements("CountPastry") + .ToDictionary( + x => Convert.ToInt32(x.Element("Key")?.Value), + x => Convert.ToInt32(x.Element("Value")?.Value) + ) + }; + } + public void Update(ShopBindingModel? model) + { + if (model == null) + { + return; + } + Name = model.Name; + Address = model.Address; + DateOpening = model.DateOpening; + CountPastries = model.Pastries.ToDictionary(x => x.Key, x => x.Value.Item2); + _cachedPastries = null; + } + public ShopViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + Address = Address, + Pastries = Pastries, + DateOpening = DateOpening, + MaxCountPastries = MaxCountPastries, + }; + public XElement GetXElement => new("Shop", + new XAttribute("Id", Id), + new XElement("Name", Name), + new XElement("Address", Address), + new XElement("DateOpening", DateOpening), + new XElement("MaxCountPastries", MaxCountPastries), + new XElement("CountPastries", CountPastries + .Select(x => new XElement("CountPastry", + new XElement("Key", x.Key), + new XElement("Value", x.Value)) + )) + ); + } +} diff --git a/ConfectionaryFileImplement/ShopStorage.cs b/ConfectionaryFileImplement/ShopStorage.cs new file mode 100644 index 0000000..e155218 --- /dev/null +++ b/ConfectionaryFileImplement/ShopStorage.cs @@ -0,0 +1,114 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContract; +using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels; +using ConfectioneryDataModels.Models; + +namespace ConfectioneryFileImplement +{ + public class ShopStorage : IShopStorage + { + private readonly DataFileSingleton _source; + public ShopStorage() + { + _source = DataFileSingleton.GetInstance(); + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + 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) + { + if (!model.Id.HasValue) + { + return null; + } + return _source.Shops.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + } + + public List GetFilteredList(ShopSearchModel model) + { + 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() + { + return _source.Shops + .Select(shop => shop.GetViewModel) + .ToList(); + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + 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) + { + 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 HasNeedPastries(IPastryModel pastry, int needCount) + { + var resultCount = _source.Shops + .Select(shop => shop.Pastries + .FirstOrDefault(x => x.Key == pastry.Id).Value.Item2) + .Sum(); + return resultCount >= needCount; + } + + public bool SellPastries(IPastryModel pastry, int needCount) + { + if (!HasNeedPastries(pastry, needCount)) + { + return false; + } + foreach (var shop in _source.Shops.Where(shop => shop.Pastries.ContainsKey(pastry.Id))) + { + var tuple = shop.Pastries[pastry.Id]; + var diff = Math.Min(tuple.Item2, needCount); + shop.Pastries[pastry.Id] = (tuple.Item1, tuple.Item2 - diff); + + needCount -= diff; + if (needCount <= 0) + { + return true; + } + } + + return true; + } + } +} diff --git a/ConfectionaryListImplement/Shop.cs b/ConfectionaryListImplement/Shop.cs index 93e754c..42b553d 100644 --- a/ConfectionaryListImplement/Shop.cs +++ b/ConfectionaryListImplement/Shop.cs @@ -11,6 +11,8 @@ namespace ConfectioneryListImplement public string Address { get; private set; } = string.Empty; + public int MaxCountPastries { get; private set; } + public DateTime DateOpening { get; private set; } public Dictionary Pastries @@ -33,6 +35,7 @@ namespace ConfectioneryListImplement Name = model.Name, Address = model.Address, DateOpening = model.DateOpening, + MaxCountPastries = model.MaxCountPastries, Pastries = new() }; } @@ -45,6 +48,7 @@ namespace ConfectioneryListImplement Name = model.Name; Address = model.Address; DateOpening = model.DateOpening; + MaxCountPastries = model.MaxCountPastries; Pastries = model.Pastries; } public ShopViewModel GetViewModel => new() @@ -54,6 +58,7 @@ namespace ConfectioneryListImplement Address = Address, Pastries = Pastries, DateOpening = DateOpening, + MaxCountPastries = MaxCountPastries, }; } } diff --git a/ConfectionaryListImplement/ShopStorage.cs b/ConfectionaryListImplement/ShopStorage.cs index 893b6ad..c9ff5c3 100644 --- a/ConfectionaryListImplement/ShopStorage.cs +++ b/ConfectionaryListImplement/ShopStorage.cs @@ -2,6 +2,7 @@ using ConfectioneryContracts.SearchModels; using ConfectioneryContracts.StoragesContract; using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; namespace ConfectioneryListImplement { @@ -72,6 +73,11 @@ namespace ConfectioneryListImplement return result; } + public bool HasNeedPastries(IPastryModel pastry, int needCount) + { + throw new NotImplementedException(); + } + public ShopViewModel? Insert(ShopBindingModel model) { model.Id = 1; @@ -91,6 +97,11 @@ namespace ConfectioneryListImplement return newShop.GetViewModel; } + public bool SellPastries(IPastryModel pastry, int needCount) + { + throw new NotImplementedException(); + } + public ShopViewModel? Update(ShopBindingModel model) { foreach (var shop in _source.Shops) diff --git a/Confectionery.sln b/Confectionery.sln index 91ace29..108d8a2 100644 --- a/Confectionery.sln +++ b/Confectionery.sln @@ -9,9 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDataModels", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryContracts", "ConfectioneryContracts\ConfectioneryContracts.csproj", "{28EC043D-88E8-48DA-B5E8-2DE5659EB1BD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryBusinessLogic", "ConfectionaryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{82EF78A8-98EC-490A-8D66-66909E5431E2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryBusinessLogic", "ConfectionaryBusinessLogic\ConfectioneryBusinessLogic.csproj", "{82EF78A8-98EC-490A-8D66-66909E5431E2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryListImplement", "ConfectionaryListImplement\ConfectioneryListImplement.csproj", "{0A7B118B-9B7C-4796-9846-66026159723E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryListImplement", "ConfectionaryListImplement\ConfectioneryListImplement.csproj", "{0A7B118B-9B7C-4796-9846-66026159723E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryFileImplement", "ConfectionaryFileImplement\ConfectioneryFileImplement.csproj", "{47A2EA59-4443-487E-85F4-AC49C04B7211}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,6 +41,10 @@ Global {0A7B118B-9B7C-4796-9846-66026159723E}.Debug|Any CPU.Build.0 = Debug|Any CPU {0A7B118B-9B7C-4796-9846-66026159723E}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A7B118B-9B7C-4796-9846-66026159723E}.Release|Any CPU.Build.0 = Release|Any CPU + {47A2EA59-4443-487E-85F4-AC49C04B7211}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47A2EA59-4443-487E-85F4-AC49C04B7211}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47A2EA59-4443-487E-85F4-AC49C04B7211}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47A2EA59-4443-487E-85F4-AC49C04B7211}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Confectionery/ConfectioneryView.csproj b/Confectionery/ConfectioneryView.csproj index 1635e6d..4947544 100644 --- a/Confectionery/ConfectioneryView.csproj +++ b/Confectionery/ConfectioneryView.csproj @@ -15,6 +15,7 @@ + diff --git a/Confectionery/FormMain.Designer.cs b/Confectionery/FormMain.Designer.cs index 0710300..35f58fe 100644 --- a/Confectionery/FormMain.Designer.cs +++ b/Confectionery/FormMain.Designer.cs @@ -40,6 +40,7 @@ this.button3 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button(); this.buttonAddPastryInShop = new System.Windows.Forms.Button(); + this.buttonSellPastry = new System.Windows.Forms.Button(); this.menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); @@ -94,7 +95,7 @@ this.dataGridView.Location = new System.Drawing.Point(12, 27); this.dataGridView.Name = "dataGridView"; this.dataGridView.RowTemplate.Height = 25; - this.dataGridView.Size = new System.Drawing.Size(606, 341); + this.dataGridView.Size = new System.Drawing.Size(606, 399); this.dataGridView.TabIndex = 1; // // buttonCreateOrder @@ -155,7 +156,7 @@ // buttonAddPastryInShop // this.buttonAddPastryInShop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonAddPastryInShop.Location = new System.Drawing.Point(624, 326); + this.buttonAddPastryInShop.Location = new System.Drawing.Point(624, 384); this.buttonAddPastryInShop.Name = "buttonAddPastryInShop"; this.buttonAddPastryInShop.Size = new System.Drawing.Size(147, 31); this.buttonAddPastryInShop.TabIndex = 7; @@ -163,11 +164,23 @@ this.buttonAddPastryInShop.UseVisualStyleBackColor = true; this.buttonAddPastryInShop.Click += new System.EventHandler(this.ButtonAddPastryInShop_Click); // + // buttonSellPastry + // + this.buttonSellPastry.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonSellPastry.Location = new System.Drawing.Point(624, 331); + this.buttonSellPastry.Name = "buttonSellPastry"; + this.buttonSellPastry.Size = new System.Drawing.Size(147, 31); + this.buttonSellPastry.TabIndex = 8; + this.buttonSellPastry.Text = "Продать изделие"; + this.buttonSellPastry.UseVisualStyleBackColor = true; + this.buttonSellPastry.Click += new System.EventHandler(this.ButtonSellPastry_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(783, 380); + this.ClientSize = new System.Drawing.Size(783, 438); + this.Controls.Add(this.buttonSellPastry); this.Controls.Add(this.buttonAddPastryInShop); this.Controls.Add(this.button4); this.Controls.Add(this.button3); @@ -202,5 +215,6 @@ private ToolStripMenuItem componentToolStripMenuItem; private ToolStripMenuItem ShopsToolStripMenuItem; private Button buttonAddPastryInShop; + private Button buttonSellPastry; } } \ No newline at end of file diff --git a/Confectionery/FormMain.cs b/Confectionery/FormMain.cs index 3c6c955..6dcaf07 100644 --- a/Confectionery/FormMain.cs +++ b/Confectionery/FormMain.cs @@ -170,5 +170,14 @@ namespace ConfectioneryView form.ShowDialog(); } } + + private void ButtonSellPastry_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSellPastry)); + if (service is FormSellPastry form) + { + form.ShowDialog(); + } + } } } \ No newline at end of file diff --git a/Confectionery/FormSellPastry.Designer.cs b/Confectionery/FormSellPastry.Designer.cs new file mode 100644 index 0000000..46f5949 --- /dev/null +++ b/Confectionery/FormSellPastry.Designer.cs @@ -0,0 +1,133 @@ +namespace ConfectioneryView +{ + partial class FormSellPastry + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.comboBoxPastry = new System.Windows.Forms.ComboBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.numericUpDownCount = new System.Windows.Forms.NumericUpDown(); + this.buttonSell = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).BeginInit(); + this.SuspendLayout(); + // + // comboBoxPastry + // + this.comboBoxPastry.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.comboBoxPastry.FormattingEnabled = true; + this.comboBoxPastry.Location = new System.Drawing.Point(141, 12); + this.comboBoxPastry.Name = "comboBoxPastry"; + this.comboBoxPastry.Size = new System.Drawing.Size(121, 23); + this.comboBoxPastry.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 15); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(123, 15); + this.label1.TabIndex = 1; + this.label1.Text = "Изделие на продажу:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(60, 46); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(75, 15); + this.label2.TabIndex = 2; + this.label2.Text = "Количество:"; + // + // numericUpDownCount + // + this.numericUpDownCount.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.numericUpDownCount.Location = new System.Drawing.Point(142, 46); + this.numericUpDownCount.Maximum = new decimal(new int[] { + 10000000, + 0, + 0, + 0}); + this.numericUpDownCount.Name = "numericUpDownCount"; + this.numericUpDownCount.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.numericUpDownCount.Size = new System.Drawing.Size(120, 23); + this.numericUpDownCount.TabIndex = 3; + // + // buttonSell + // + this.buttonSell.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonSell.Location = new System.Drawing.Point(12, 90); + this.buttonSell.Name = "buttonSell"; + this.buttonSell.Size = new System.Drawing.Size(123, 23); + this.buttonSell.TabIndex = 4; + this.buttonSell.Text = "Продать"; + this.buttonSell.UseVisualStyleBackColor = true; + this.buttonSell.Click += new System.EventHandler(this.ButtonSell_Click); + // + // buttonCancel + // + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonCancel.Location = new System.Drawing.Point(142, 90); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(123, 23); + this.buttonCancel.TabIndex = 5; + this.buttonCancel.Text = "Отмена"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); + // + // FormSellPastry + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(277, 122); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonSell); + this.Controls.Add(this.numericUpDownCount); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.comboBoxPastry); + this.Name = "FormSellPastry"; + this.Text = "Продажа изделия"; + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownCount)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ComboBox comboBoxPastry; + private Label label1; + private Label label2; + private NumericUpDown numericUpDownCount; + private Button buttonSell; + private Button buttonCancel; + } +} \ No newline at end of file diff --git a/Confectionery/FormSellPastry.cs b/Confectionery/FormSellPastry.cs new file mode 100644 index 0000000..17731cd --- /dev/null +++ b/Confectionery/FormSellPastry.cs @@ -0,0 +1,67 @@ +using ConfectioneryContracts.BusinessLogicsContracts; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ConfectioneryView +{ + public partial class FormSellPastry : Form + { + private readonly IShopLogic _shopLogic; + private readonly IPastryLogic _pastryLogic; + + public FormSellPastry(IPastryLogic logic, IShopLogic shopLogic) + { + InitializeComponent(); + _pastryLogic = logic; + _shopLogic = shopLogic; + var list = logic.ReadList(null); + if (list != null) + { + comboBoxPastry.DisplayMember = "PastryName"; + comboBoxPastry.ValueMember = "Id"; + comboBoxPastry.DataSource = list; + comboBoxPastry.SelectedItem = null; + } + } + + private void ButtonSell_Click(object sender, EventArgs e) + { + if (comboBoxPastry.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (numericUpDownCount.Value <= 0) + { + MessageBox.Show("Количество должно быть больше нуля", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + var count = (int)numericUpDownCount.Value; + var pastry = _pastryLogic.ReadElement(new() { Id = (int)comboBoxPastry.SelectedValue }); + if (pastry == null || !_shopLogic.SellPastries(pastry, count)) + { + MessageBox.Show("Не удалось продать изделия. Информацию смотрите в логах", "Ошибка", + MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + DialogResult = DialogResult.OK; + Close(); + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/Confectionery/FormSellPastry.resx b/Confectionery/FormSellPastry.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/Confectionery/FormSellPastry.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Confectionery/FormShop.Designer.cs b/Confectionery/FormShop.Designer.cs index 694a22f..3a9ec82 100644 --- a/Confectionery/FormShop.Designer.cs +++ b/Confectionery/FormShop.Designer.cs @@ -40,7 +40,10 @@ this.textBoxDateOpening = new System.Windows.Forms.TextBox(); this.buttonCancel = new System.Windows.Forms.Button(); this.buttonSave = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this.numericUpDownMaxPastry = new System.Windows.Forms.NumericUpDown(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxPastry)).BeginInit(); this.SuspendLayout(); // // label1 @@ -74,7 +77,7 @@ this.dataGridView.Location = new System.Drawing.Point(12, 64); this.dataGridView.Name = "dataGridView"; this.dataGridView.RowTemplate.Height = 25; - this.dataGridView.Size = new System.Drawing.Size(583, 213); + this.dataGridView.Size = new System.Drawing.Size(640, 213); this.dataGridView.TabIndex = 2; // // PastryName @@ -105,7 +108,7 @@ // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(386, 9); + this.label3.Location = new System.Drawing.Point(366, 9); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(100, 15); this.label3.TabIndex = 4; @@ -115,20 +118,20 @@ // this.textBoxAddress.Location = new System.Drawing.Point(159, 27); this.textBoxAddress.Name = "textBoxAddress"; - this.textBoxAddress.Size = new System.Drawing.Size(221, 23); + this.textBoxAddress.Size = new System.Drawing.Size(201, 23); this.textBoxAddress.TabIndex = 5; // // textBoxDateOpening // - this.textBoxDateOpening.Location = new System.Drawing.Point(386, 27); + this.textBoxDateOpening.Location = new System.Drawing.Point(366, 27); this.textBoxDateOpening.Name = "textBoxDateOpening"; - this.textBoxDateOpening.Size = new System.Drawing.Size(209, 23); + this.textBoxDateOpening.Size = new System.Drawing.Size(160, 23); this.textBoxDateOpening.TabIndex = 6; // // buttonCancel // this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonCancel.Location = new System.Drawing.Point(492, 283); + this.buttonCancel.Location = new System.Drawing.Point(549, 283); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(103, 23); this.buttonCancel.TabIndex = 7; @@ -139,7 +142,7 @@ // buttonSave // this.buttonSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonSave.Location = new System.Drawing.Point(366, 284); + this.buttonSave.Location = new System.Drawing.Point(423, 284); this.buttonSave.Name = "buttonSave"; this.buttonSave.Size = new System.Drawing.Size(120, 22); this.buttonSave.TabIndex = 8; @@ -147,11 +150,34 @@ this.buttonSave.UseVisualStyleBackColor = true; this.buttonSave.Click += new System.EventHandler(this.ButtonSave_Click); // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(530, 9); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(118, 15); + this.label4.TabIndex = 9; + this.label4.Text = "Максимум изделий:"; + // + // numericUpDownMaxPastry + // + this.numericUpDownMaxPastry.Location = new System.Drawing.Point(532, 27); + this.numericUpDownMaxPastry.Maximum = new decimal(new int[] { + 10000000, + 0, + 0, + 0}); + this.numericUpDownMaxPastry.Name = "numericUpDownMaxPastry"; + this.numericUpDownMaxPastry.Size = new System.Drawing.Size(120, 23); + this.numericUpDownMaxPastry.TabIndex = 10; + // // FormShop // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(607, 317); + this.ClientSize = new System.Drawing.Size(664, 317); + this.Controls.Add(this.numericUpDownMaxPastry); + this.Controls.Add(this.label4); this.Controls.Add(this.buttonSave); this.Controls.Add(this.buttonCancel); this.Controls.Add(this.textBoxDateOpening); @@ -165,6 +191,7 @@ this.Text = "Просмотр изделий магазина"; this.Load += new System.EventHandler(this.FormShop_Load); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxPastry)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -184,5 +211,7 @@ private DataGridViewTextBoxColumn PastryName; private DataGridViewTextBoxColumn Price; private DataGridViewTextBoxColumn Count; + private Label label4; + private NumericUpDown numericUpDownMaxPastry; } } \ No newline at end of file diff --git a/Confectionery/FormShop.cs b/Confectionery/FormShop.cs index c755270..fa5c0f5 100644 --- a/Confectionery/FormShop.cs +++ b/Confectionery/FormShop.cs @@ -66,7 +66,8 @@ namespace ConfectioneryView { var model = GetShop(extendDate ? Id : Convert.ToInt32(comboBoxShop.SelectedValue)); if (model != null) - { + { + numericUpDownMaxPastry.Value = model.MaxCountPastries; comboBoxShop.Text = model.Name; textBoxAddress.Text = model.Address; textBoxDateOpening.Text = Convert.ToString(model.DateOpening); @@ -113,7 +114,8 @@ namespace ConfectioneryView { Name = comboBoxShop.Text, Address = textBoxAddress.Text, - DateOpening = dateTime + DateOpening = dateTime, + MaxCountPastries = (int)numericUpDownMaxPastry.Value, }; var vmodel = GetShop(Id); bool operationResult = false; diff --git a/Confectionery/FormShop.resx b/Confectionery/FormShop.resx index c4ce247..5191e62 100644 --- a/Confectionery/FormShop.resx +++ b/Confectionery/FormShop.resx @@ -66,4 +66,13 @@ True + + True + + + True + + + True + \ No newline at end of file diff --git a/Confectionery/Program.cs b/Confectionery/Program.cs index d0c5149..e76fcdb 100644 --- a/Confectionery/Program.cs +++ b/Confectionery/Program.cs @@ -1,13 +1,12 @@ -using ConfectioneryListImplement.Implements; -using ConfectioneryBusinessLogic; +using ConfectioneryFileImplement.Implements; using ConfectioneryBusinessLogic.BusinessLogics; using ConfectioneryContracts.BusinessLogicsContracts; using ConfectioneryContracts.StoragesContract; -using ConfectioneryListImplement; +using ConfectioneryFileImplement; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog.Extensions.Logging; - +using ConfectioneryBusinessLogic; namespace ConfectioneryView { @@ -54,6 +53,7 @@ namespace ConfectioneryView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file diff --git a/ConfectioneryContracts/BindingModels/ShopBindingModel.cs b/ConfectioneryContracts/BindingModels/ShopBindingModel.cs index 38d8750..f627224 100644 --- a/ConfectioneryContracts/BindingModels/ShopBindingModel.cs +++ b/ConfectioneryContracts/BindingModels/ShopBindingModel.cs @@ -9,6 +9,8 @@ namespace ConfectioneryContracts.BindingModels public string Address { get; set; } = string.Empty; + public int MaxCountPastries { get; set; } + public DateTime DateOpening { get; set; } = DateTime.Now; public Dictionary Pastries diff --git a/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs b/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs index 3ba0749..6390a91 100644 --- a/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs +++ b/ConfectioneryContracts/BusinessLogicsContracts/IShopLogic.cs @@ -13,5 +13,8 @@ namespace ConfectioneryContracts.BusinessLogicsContracts bool Update(ShopBindingModel model); bool Delete(ShopBindingModel model); bool AddPastry(ShopSearchModel model, IPastryModel pastry, int count); + int GetFreePlacesWithPastriesInShops(int countPastries); + bool AddPastriesInShops(IPastryModel pastry, int count); + public bool SellPastries(IPastryModel pastry, int needCount); } } diff --git a/ConfectioneryContracts/StoragesContract/IShopStorage.cs b/ConfectioneryContracts/StoragesContract/IShopStorage.cs index 4276f2d..1f53aa5 100644 --- a/ConfectioneryContracts/StoragesContract/IShopStorage.cs +++ b/ConfectioneryContracts/StoragesContract/IShopStorage.cs @@ -1,6 +1,7 @@ using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.SearchModels; using ConfectioneryContracts.ViewModels; +using ConfectioneryDataModels.Models; namespace ConfectioneryContracts.StoragesContract { @@ -12,5 +13,8 @@ namespace ConfectioneryContracts.StoragesContract ShopViewModel? Insert(ShopBindingModel model); ShopViewModel? Update(ShopBindingModel model); ShopViewModel? Delete(ShopBindingModel model); + + bool HasNeedPastries(IPastryModel pastry, int needCount); + public bool SellPastries(IPastryModel pastry, int needCount); } } diff --git a/ConfectioneryContracts/ViewModels/ShopViewModel.cs b/ConfectioneryContracts/ViewModels/ShopViewModel.cs index a87ca8d..f7fce9b 100644 --- a/ConfectioneryContracts/ViewModels/ShopViewModel.cs +++ b/ConfectioneryContracts/ViewModels/ShopViewModel.cs @@ -12,6 +12,9 @@ namespace ConfectioneryContracts.ViewModels [DisplayName("Адрес магазина")] public string Address { get; set; } = string.Empty; + [DisplayName("Максимальное количество изделий в магазине")] + public int MaxCountPastries { get; set; } + [DisplayName("Время открытия")] public DateTime DateOpening { get; set; } = DateTime.Now; @@ -22,5 +25,6 @@ namespace ConfectioneryContracts.ViewModels } = new(); public int Id { get; set; } + } } diff --git a/ConfectioneryDataModels/IShopModel.cs b/ConfectioneryDataModels/IShopModel.cs index c0883e9..31936ea 100644 --- a/ConfectioneryDataModels/IShopModel.cs +++ b/ConfectioneryDataModels/IShopModel.cs @@ -6,6 +6,7 @@ namespace ConfectioneryDataModels { string Name { get; } string Address { get; } + int MaxCountPastries { get; } DateTime DateOpening { get; } Dictionary Pastries { get; } }