LabWork02_Hard Work in progress 2

This commit is contained in:
parent dc7cdf6cc2
commit 8e6b339919
11 changed files with 385 additions and 19 deletions

View File

@ -4,6 +4,7 @@ using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Enums;
using AircraftPlantDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -28,15 +29,33 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
/// </summary>
private readonly IOrderStorage _orderStorage;
/// <summary>
/// Взаимодействие с хранилищем магазинов
/// </summary>
private IShopStorage _shopStorage;
/// <summary>
/// Бизнес-логика магазинов
/// </summary>
private IShopLogic _shopLogic;
/// <summary>
/// Взаимодействие с хранилищем изделий
/// </summary>
private IPlaneStorage _planeStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="orderStorage"></param>
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopStorage shopStorage, IShopLogic shopLogic, IPlaneStorage planeStorage)
{
_logger = logger;
_orderStorage = orderStorage;
_shopStorage = shopStorage;
_shopLogic = shopLogic;
_planeStorage = planeStorage;
}
/// <summary>
@ -165,6 +184,21 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
return false;
}
if (newStatus == OrderStatus.Готов)
{
var plane = _planeStorage.GetElement(new PlaneSearchModel { Id = model.Id });
if (plane == null)
{
_logger.LogWarning("Status change error. Plane not found");
return false;
}
if (!CheckSupply(plane, model.Count))
{
_logger.LogWarning("Status change error. Shop doesnt have planes");
return false;
}
}
model.Status = newStatus;
if (model.Status == OrderStatus.Выдан)
@ -183,5 +217,79 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
}
return true;
}
/// <summary>
/// Проверка заказа
/// </summary>
/// <param name="plane"></param>
/// <param name="count"></param>
/// <returns></returns>
public bool CheckSupply(IPlaneModel model, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check supply operation error. Planes count < 0");
return false;
}
int sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxPlanes).Sum();
int sumCount = _shopStorage.GetFullList().Select(x => x.ShopPlanes.Select(y => y.Value.Item2).Sum()).Sum();
int free = sumCapacity - sumCount;
if (free < count)
{
_logger.LogWarning("Check supply error. No place for new planes");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
free = shop.MaxPlanes;
foreach (var plane in shop.ShopPlanes)
{
free -= plane.Value.Item2;
}
if (free == 0)
{
continue;
}
if (free >= count)
{
if (_shopLogic.AddPlaneInShop(new()
{
Id = shop.Id
}, model, count))
{
count = 0;
}
else
{
_logger.LogWarning("Supply error");
return false;
}
}
else
{
if (_shopLogic.AddPlaneInShop(new()
{
Id = shop.Id
}, model, free))
{
count -= free;
}
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
}
}

View File

@ -165,6 +165,13 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
}
_logger.LogInformation("AddPlaneInShop find. Id:{Id}", element.Id);
var countPlanes = element.ShopPlanes.Select(x => x.Value.Item2).Sum();
if (element.MaxPlanes - countPlanes < count)
{
_logger.LogWarning("Shop is overflowed");
return false;
}
if (element.ShopPlanes.TryGetValue(plane.Id, out var pair))
{
element.ShopPlanes[plane.Id] = (plane, count + pair.Item2);
@ -182,7 +189,8 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
Address = element.Address,
ShopName = element.ShopName,
DateOpening = element.DateOpening,
ShopPlanes = element.ShopPlanes
ShopPlanes = element.ShopPlanes,
MaxPlanes = element.MaxPlanes
});
return true;
}

View File

@ -59,17 +59,17 @@ namespace AircraftPlantContracts.StoragesContracts
/// <summary>
/// Продажа изделий
/// </summary>
/// <param name="plane"></param>
/// <param name="model"></param>
/// <param name="count"></param>
/// <returns></returns>
bool SellPlanes(IPlaneModel plane, int count);
bool SellPlanes(IPlaneModel model, int count);
/// <summary>
/// Проверка наличия изделий в магазинах в нужном количестве
/// Проверка наличия в нужном количестве
/// </summary>
/// <param name="plane"></param>
/// <param name="model"></param>
/// <param name="count"></param>
/// <returns></returns>
bool Restock(IPlaneModel plane, int count);
bool CheckCount(IPlaneModel model, int count);
}
}

View File

@ -33,6 +33,11 @@ namespace AircraftPlantFileImplement
/// </summary>
private readonly string PlaneFileName = "Plane.xml";
/// <summary>
/// Название файла для хранения информации о магазинах
/// </summary>
private readonly string ShopFileName = "Shop.xml";
/// <summary>
/// Список классов-моделей компонентов
/// </summary>
@ -48,6 +53,11 @@ namespace AircraftPlantFileImplement
/// </summary>
public List<Plane> Planes { get; set; }
/// <summary>
/// Список классов-моделей магазина
/// </summary>
public List<Shop> Shops { get; set; }
/// <summary>
/// Конструктор
/// </summary>
@ -56,6 +66,7 @@ namespace AircraftPlantFileImplement
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Planes = LoadData(PlaneFileName, "Plane", x => Plane.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Shops = LoadData(ShopFileName, "Shop", x => Shop.Create(x)!)!;
}
/// <summary>
@ -86,6 +97,11 @@ namespace AircraftPlantFileImplement
/// </summary>
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
/// <summary>
/// Сохранение магазинов
/// </summary>
public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement);
/// <summary>
/// Метод для загрузки данных из xml-файла
/// </summary>

View File

@ -0,0 +1,197 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using AircraftPlantFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantFileImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для магазина
/// </summary>
public class ShopStorage : IShopStorage
{
/// <summary>
/// Хранилище
/// </summary>
private readonly DataFileSingleton _source;
/// <summary>
/// Конструктор
/// </summary>
public ShopStorage()
{
_source = DataFileSingleton.GetInstance();
}
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<ShopViewModel> GetFullList()
{
return _source.Shops
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
return _source.Shops
.Where(x => x.ShopName.Contains(model.ShopName))
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return null;
}
return _source.Shops
.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ShopName) &&
x.ShopName == model.ShopName) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Редактирование элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Продажа изделий
/// </summary>
/// <param name="model"></param>
/// <param name="count"></param>
/// <returns></returns>
public bool SellPlanes(IPlaneModel model, int count)
{
var plane = _source.Planes.FirstOrDefault(x => x.Id == model.Id);
if (plane == null || !CheckCount(model, count))
{
return false;
}
foreach (var shop in _source.Shops)
{
var planes = shop.ShopPlanes;
foreach (var elem in planes.Where(x => x.Value.Item1.Id == plane.Id))
{
var selling = Math.Min(elem.Value.Item2, count);
planes[elem.Value.Item1.Id] = (elem.Value.Item1, elem.Value.Item2 - selling);
count -= selling;
if (count <= 0)
{
break;
}
}
shop.Update(new ShopBindingModel
{
Id = model.Id,
ShopName = shop.ShopName,
Address = shop.Address,
DateOpening = shop.DateOpening,
ShopPlanes = planes,
MaxPlanes = shop.MaxPlanes
});
}
_source.SaveShops();
return true;
}
/// <summary>
/// Проверка наличия в нужном количестве
/// </summary>
/// <param name="model"></param>
/// <param name="count"></param>
/// <returns></returns>
public bool CheckCount(IPlaneModel model, int count)
{
int store = _source.Shops
.Select(x => x.ShopPlanes
.Select(y => (y.Value.Item1.Id == model.Id ? y.Value.Item2 : 0))
.Sum()).Sum();
return store >= count;
}
}
}

View File

@ -152,8 +152,7 @@ namespace AircraftPlantFileImplement.Models
new XElement("ShopPlanes", Planes.Select(x =>
new XElement("ShopPlanes",
new XElement("Key", x.Key),
new XElement("Value", x.Value)))),
new XElement("MaxPlanes", MaxPlanes.ToString()
.ToArray()));
new XElement("Value", x.Value))).ToArray()),
new XElement("MaxPlanes", MaxPlanes.ToString()));
}
}

View File

@ -159,19 +159,19 @@ namespace AircraftPlantListImplement.Implements
/// <param name="count"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool SellPlanes(IPlaneModel plane, int count)
public bool SellPlanes(IPlaneModel model, int count)
{
throw new NotImplementedException();
}
/// <summary>
/// Проверка наличия изделий в магазинах в нужном количестве
/// Проверка наличия в нужном количестве
/// </summary>
/// <param name="plane"></param>
/// <param name="model"></param>
/// <param name="count"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public bool Restock(IPlaneModel plane, int count)
public bool CheckCount(IPlaneModel model, int count)
{
throw new NotImplementedException();
}

View File

@ -66,7 +66,8 @@ namespace AircraftPlantListImplement.Models
ShopName = model.ShopName,
Address = model.Address,
DateOpening = model.DateOpening,
ShopPlanes = model.ShopPlanes
ShopPlanes = model.ShopPlanes,
MaxPlanes = model.MaxPlanes
};
}
@ -85,6 +86,7 @@ namespace AircraftPlantListImplement.Models
Address = model.Address;
DateOpening = model.DateOpening;
ShopPlanes = model.ShopPlanes;
MaxPlanes = model.MaxPlanes;
}
/// <summary>
@ -96,7 +98,8 @@ namespace AircraftPlantListImplement.Models
ShopName = ShopName,
Address = Address,
DateOpening = DateOpening,
ShopPlanes = ShopPlanes
ShopPlanes = ShopPlanes,
MaxPlanes = MaxPlanes
};
}
}

View File

@ -40,7 +40,10 @@
ColumnCount = new DataGridViewTextBoxColumn();
buttonCancel = new Button();
buttonSave = new Button();
labelMaxPlanes = new Label();
numericUpDownMaxPlanes = new NumericUpDown();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownMaxPlanes).BeginInit();
SuspendLayout();
//
// labelName
@ -99,13 +102,13 @@
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnID, ColumnPlaneName, ColumnCount });
dataGridView.GridColor = Color.White;
dataGridView.Location = new Point(12, 99);
dataGridView.Location = new Point(12, 128);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(560, 321);
dataGridView.Size = new Size(560, 292);
dataGridView.TabIndex = 6;
//
// ColumnID
@ -148,11 +151,29 @@
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// labelMaxPlanes
//
labelMaxPlanes.AutoSize = true;
labelMaxPlanes.Location = new Point(12, 101);
labelMaxPlanes.Name = "labelMaxPlanes";
labelMaxPlanes.Size = new Size(83, 15);
labelMaxPlanes.TabIndex = 9;
labelMaxPlanes.Text = "Вместимость:";
//
// numericUpDownMaxPlanes
//
numericUpDownMaxPlanes.Location = new Point(110, 99);
numericUpDownMaxPlanes.Name = "numericUpDownMaxPlanes";
numericUpDownMaxPlanes.Size = new Size(200, 23);
numericUpDownMaxPlanes.TabIndex = 10;
//
// FormShop
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(584, 461);
Controls.Add(numericUpDownMaxPlanes);
Controls.Add(labelMaxPlanes);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(dataGridView);
@ -166,6 +187,7 @@
Text = "Магазин";
Load += FormShop_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownMaxPlanes).EndInit();
ResumeLayout(false);
PerformLayout();
}
@ -184,5 +206,7 @@
private DataGridViewTextBoxColumn ColumnID;
private DataGridViewTextBoxColumn ColumnPlaneName;
private DataGridViewTextBoxColumn ColumnCount;
private Label labelMaxPlanes;
private NumericUpDown numericUpDownMaxPlanes;
}
}

View File

@ -72,6 +72,7 @@ namespace AircraftPlantView
textBoxName.Text = view.ShopName;
textBoxAddress.Text = view.Address;
dateTimePicker.Text = view.DateOpening.ToString();
numericUpDownMaxPlanes.Value = view.MaxPlanes;
_shopPlanes = view.ShopPlanes ?? new Dictionary<int, (IPlaneModel, int)>();
LoadData();
}
@ -109,7 +110,8 @@ namespace AircraftPlantView
Id = _id ?? 0,
ShopName = textBoxName.Text,
Address = textBoxAddress.Text,
DateOpening = dateTimePicker.Value.Date
DateOpening = dateTimePicker.Value.Date,
MaxPlanes = Convert.ToInt32(numericUpDownMaxPlanes.Value)
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)

View File

@ -126,4 +126,13 @@
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnID.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnPlaneName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>