LabWork06_Hard
This commit is contained in:
commit
0faf124bef
23
AircraftPlant/AircraftPlant.log.2024-04-08
Normal file
23
AircraftPlant/AircraftPlant.log.2024-04-08
Normal file
@ -0,0 +1,23 @@
|
||||
2024-04-08 10:12:55,009 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: https://localhost:7122
|
||||
2024-04-08 10:12:55,090 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: http://localhost:5092
|
||||
2024-04-08 10:12:55,097 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Application started. Press Ctrl+C to shut down.
|
||||
2024-04-08 10:12:55,100 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Hosting environment: Development
|
||||
2024-04-08 10:12:55,102 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Content root path: D:\ULSTU\Семестр 4\РПП\AircraftPlant\AircraftPlantRestApi\
|
||||
2024-04-08 10:13:00,428 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [49] - MESSAGE: ReadList. PlaneName:(null).Id:(null)
|
||||
2024-04-08 10:13:03,695 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [58] - MESSAGE: ReadList. Count:2
|
||||
2024-04-08 10:13:37,635 INFO AircraftPlantBusinessLogic.BusinessLogics.ClientLogic.ReadElement [74] - MESSAGE: ReadElement. ClientEmail:client1.Id:(null)
|
||||
2024-04-08 10:13:37,766 INFO AircraftPlantBusinessLogic.BusinessLogics.ClientLogic.ReadElement [83] - MESSAGE: ReadElement find. Id:1
|
||||
2024-04-08 10:13:37,802 INFO AircraftPlantBusinessLogic.BusinessLogics.ClientLogic.ReadElement [74] - MESSAGE: ReadElement. ClientEmail:client1.Id:(null)
|
||||
2024-04-08 10:13:37,849 INFO AircraftPlantBusinessLogic.BusinessLogics.ClientLogic.ReadElement [83] - MESSAGE: ReadElement find. Id:1
|
||||
2024-04-08 10:13:37,914 INFO AircraftPlantBusinessLogic.BusinessLogics.OrderLogic.ReadList [50] - MESSAGE: ReadList. Order.Id:(null)
|
||||
2024-04-08 10:13:37,956 INFO AircraftPlantBusinessLogic.BusinessLogics.OrderLogic.ReadList [59] - MESSAGE: ReadList. Count:2
|
||||
2024-04-08 10:13:45,625 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [49] - MESSAGE: ReadList. PlaneName:(null).Id:(null)
|
||||
2024-04-08 10:13:45,628 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [58] - MESSAGE: ReadList. Count:2
|
||||
2024-04-08 10:13:48,493 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadElement [75] - MESSAGE: ReadElement. PlaneName:(null).Id:1
|
||||
2024-04-08 10:13:48,514 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:1
|
||||
2024-04-08 10:13:50,536 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadElement [75] - MESSAGE: ReadElement. PlaneName:(null).Id:1
|
||||
2024-04-08 10:13:50,540 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:1
|
||||
2024-04-08 10:13:50,584 INFO AircraftPlantBusinessLogic.BusinessLogics.OrderLogic.CheckModel [144] - MESSAGE: Order. OrderID:0.Sum:1650. PlaneId: 1
|
||||
2024-04-08 10:13:50,780 INFO AircraftPlantBusinessLogic.BusinessLogics.OrderLogic.ReadList [50] - MESSAGE: ReadList. Order.Id:(null)
|
||||
2024-04-08 10:13:50,783 INFO AircraftPlantBusinessLogic.BusinessLogics.OrderLogic.ReadList [59] - MESSAGE: ReadList. Count:3
|
||||
|
@ -19,7 +19,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AircraftPlantDatabaseImplem
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AircraftPlantRestApi", "AircraftPlantRestApi\AircraftPlantRestApi.csproj", "{C4F1D3FB-A993-4C1A-82AF-29D15DC0E280}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AircraftPlantClientApp", "AircraftPlantClientApp\AircraftPlantClientApp.csproj", "{56B441C1-18BC-4BD8-A5C1-318B63081200}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AircraftPlantClientApp", "AircraftPlantClientApp\AircraftPlantClientApp.csproj", "{56B441C1-18BC-4BD8-A5C1-318B63081200}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AircraftPlantShopApp", "AircraftPlantShopApp\AircraftPlantShopApp.csproj", "{3E7EF5E1-7791-4427-8934-6CE02A8D67CB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -63,6 +65,10 @@ Global
|
||||
{56B441C1-18BC-4BD8-A5C1-318B63081200}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{56B441C1-18BC-4BD8-A5C1-318B63081200}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{56B441C1-18BC-4BD8-A5C1-318B63081200}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3E7EF5E1-7791-4427-8934-6CE02A8D67CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3E7EF5E1-7791-4427-8934-6CE02A8D67CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3E7EF5E1-7791-4427-8934-6CE02A8D67CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3E7EF5E1-7791-4427-8934-6CE02A8D67CB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -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,16 +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>
|
||||
@ -185,7 +203,7 @@ orderStorage)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
if (element.Status + 1 != newStatus)
|
||||
if (element.Status + 1 != newStatus && element.Status != OrderStatus.Ожидание)
|
||||
{
|
||||
_logger.LogWarning("Change status operation failed");
|
||||
return false;
|
||||
@ -193,6 +211,27 @@ orderStorage)
|
||||
|
||||
model.Status = newStatus;
|
||||
|
||||
if (newStatus == OrderStatus.Выдан)
|
||||
{
|
||||
var plane = _planeStorage.GetElement(new PlaneSearchModel { Id = element.PlaneId });
|
||||
if (plane == null)
|
||||
{
|
||||
_logger.LogWarning("Status change error. Plane not found");
|
||||
return false;
|
||||
}
|
||||
if (!CheckSupply(plane, element.Count))
|
||||
{
|
||||
_logger.LogWarning("Status change error. Shop is overflowed");
|
||||
|
||||
model.Status = OrderStatus.Ожидание;
|
||||
if (_orderStorage.Update(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Change status operation failed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (model.Status == OrderStatus.Выдан)
|
||||
{
|
||||
model.DateImplement = DateTime.Now;
|
||||
@ -209,5 +248,79 @@ orderStorage)
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="planeStorage"></param>
|
||||
public PlaneLogic(ILogger<PlaneLogic> logger, IPlaneStorage
|
||||
planeStorage)
|
||||
public PlaneLogic(ILogger<PlaneLogic> logger, IPlaneStorage planeStorage)
|
||||
{
|
||||
_logger = logger;
|
||||
_planeStorage = planeStorage;
|
||||
|
@ -33,6 +33,11 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
/// </summary>
|
||||
private readonly IOrderStorage _orderStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Хранилище магазинов
|
||||
/// </summary>
|
||||
private readonly IShopStorage _shopStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Взаимодействие с отчетами в Excel-формате
|
||||
/// </summary>
|
||||
@ -57,12 +62,13 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
/// <param name="saveToExcel"></param>
|
||||
/// <param name="saveToWord"></param>
|
||||
/// <param name="saveToPdf"></param>
|
||||
public ReportLogic(IPlaneStorage planeStorage, IComponentStorage componentStorage, IOrderStorage orderStorage,
|
||||
public ReportLogic(IPlaneStorage planeStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, IShopStorage shopStorage,
|
||||
AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
|
||||
{
|
||||
_planeStorage = planeStorage;
|
||||
_componentStorage = componentStorage;
|
||||
_orderStorage = orderStorage;
|
||||
_shopStorage = shopStorage;
|
||||
|
||||
_saveToExcel = saveToExcel;
|
||||
_saveToWord = saveToWord;
|
||||
@ -102,6 +108,39 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка заказов с группировкой по датам
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ReportGroupOrdersViewModel> GetGroupOrders()
|
||||
{
|
||||
return _orderStorage.GetFullList()
|
||||
.GroupBy(x => x.DateCreate.Date)
|
||||
.Select(x => new ReportGroupOrdersViewModel
|
||||
{
|
||||
DateCreate = x.Key,
|
||||
Count = x.Count(),
|
||||
Sum = x.Select(y => y.Sum).Sum()
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка магазинов с указанием хранимых изделий
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ReportShopPlanesViewModel> GetShopPlanes()
|
||||
{
|
||||
return _shopStorage.GetFullList()
|
||||
.Select(x => new ReportShopPlanesViewModel
|
||||
{
|
||||
ShopName = x.ShopName,
|
||||
Planes = x.ShopPlanes.Select(x => (x.Value.Item1.PlaneName, x.Value.Item2)).ToList(),
|
||||
TotalCount = x.ShopPlanes.Select(x => x.Value.Item2).Sum()
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение изделий в Word-файл
|
||||
/// </summary>
|
||||
@ -145,5 +184,47 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
Orders = GetOrders(model)
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение магазинов в Word-файл
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void SaveShopsToWordFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToWord.CreateShopsDoc(new WordInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Список магазинов",
|
||||
Shops = _shopStorage.GetFullList()
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение магазинов с указанием изделий в файл-Excel
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void SaveShopPlanesToExcelFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToExcel.CreateShopPlanesReport(new ExcelInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Ассортимент магазинов",
|
||||
ShopPlanes = GetShopPlanes()
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение заказов с группировкой по датам в файл-Pdf
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void SaveGroupOrdersToPdfFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToPdf.CreateGroupOrdersDoc(new PdfInfo
|
||||
{
|
||||
FileName= model.FileName,
|
||||
Title = "Список заказов с группировкой по датам",
|
||||
GroupOrders = GetGroupOrders()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,258 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.BusinessLogicsContracts;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.StoragesContracts;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
{
|
||||
/// <summary>
|
||||
/// Реализация интерфейса бизнес-логики для магазинов
|
||||
/// </summary>
|
||||
public class ShopLogic : IShopLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// Логгер
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Взаимодействие с хранилищем магазинов
|
||||
/// </summary>
|
||||
private readonly IShopStorage _shopStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="shopStorage"></param>
|
||||
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
|
||||
{
|
||||
_logger = logger;
|
||||
_shopStorage = shopStorage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public List<ShopViewModel>? 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение отдельной записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public bool Create(ShopBindingModel model)
|
||||
{
|
||||
CheckModel(model);
|
||||
|
||||
if (_shopStorage.Insert(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Изменение записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public bool Update(ShopBindingModel model)
|
||||
{
|
||||
CheckModel(model);
|
||||
|
||||
if (_shopStorage.Update(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Update operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавление изделия в магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public bool AddPlaneInShop(ShopSearchModel model, IPlaneModel plane, int count)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new ArgumentException("Количество изделий должно быть больше 0", nameof(count));
|
||||
}
|
||||
_logger.LogInformation("AddPlaneInShop. ShopName:{ShopName}.Id:{ Id}", model.ShopName, model.Id);
|
||||
var element = _shopStorage.GetElement(model);
|
||||
if (element == null)
|
||||
{
|
||||
_logger.LogWarning("AddPlaneInShop element not found");
|
||||
return false;
|
||||
}
|
||||
_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);
|
||||
_logger.LogInformation("AddPlaneInShop. Added {count} {plane} to '{ShopName}' shop", count, plane.PlaneName, element.ShopName);
|
||||
}
|
||||
else
|
||||
{
|
||||
element.ShopPlanes[plane.Id] = (plane, count);
|
||||
_logger.LogInformation("AddPlaneInShop. Added {count} new plane {plane} to '{ShopName}' shop", count, plane.PlaneName, element.ShopName);
|
||||
}
|
||||
|
||||
_shopStorage.Update(new()
|
||||
{
|
||||
Id = element.Id,
|
||||
Address = element.Address,
|
||||
ShopName = element.ShopName,
|
||||
DateOpening = element.DateOpening,
|
||||
ShopPlanes = element.ShopPlanes,
|
||||
MaxPlanes = element.MaxPlanes
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Продажа изделий
|
||||
/// </summary>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public bool SellPlanes(IPlaneModel plane, int count)
|
||||
{
|
||||
if (plane == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(plane));
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new ArgumentException("Количество изделий должно быть больше 0", nameof(count));
|
||||
}
|
||||
|
||||
if (_shopStorage.SellPlanes(plane, count))
|
||||
{
|
||||
_logger.LogInformation("Selling sucsess");
|
||||
return true;
|
||||
}
|
||||
_logger.LogInformation("Selling failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="withParams"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
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:{ShopName}.Address:{ Address}. Id:{ Id}", 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("Магазин с таким названием уже есть");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -82,6 +82,10 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Выполняем заказы в статусе "Ожидание"
|
||||
await RunOrderInWaiting(implementer);
|
||||
// Выполняем заказы в статусе "Выполняется"
|
||||
await RunOrderInWork(implementer);
|
||||
|
||||
await Task.Run(() =>
|
||||
@ -171,5 +175,54 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ищем заказ, которые в ожидании
|
||||
/// </summary>
|
||||
/// <param name="implementer"></param>
|
||||
/// <returns></returns>
|
||||
private async Task RunOrderInWaiting(ImplementerViewModel implementer)
|
||||
{
|
||||
if (_orderLogic == null || implementer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var orders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel
|
||||
{
|
||||
ImplementerId = implementer.Id,
|
||||
Status = OrderStatus.Ожидание
|
||||
}));
|
||||
if (orders == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// доделываем работу
|
||||
foreach (var order in orders)
|
||||
{
|
||||
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
|
||||
_orderLogic.FinishOrder(new OrderBindingModel
|
||||
{
|
||||
Id = order.Id
|
||||
});
|
||||
|
||||
// отдыхаем
|
||||
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
|
||||
}
|
||||
}
|
||||
// заказа может не быть, просто игнорируем ошибку
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Error try get work");
|
||||
}
|
||||
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while do work");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,82 @@ namespace AircraftPlantBusinessLogic.OfficePackage
|
||||
SaveExcel(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание отчета в Excel-формате
|
||||
/// по магазинам с расшифровкой по изделиям
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
public void CreateShopPlanesReport(ExcelInfo info)
|
||||
{
|
||||
CreateExcel(info);
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "A",
|
||||
RowIndex = 1,
|
||||
Text = info.Title,
|
||||
StyleInfo = ExcelStyleInfoType.Title
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters
|
||||
{
|
||||
CellFromName = "A1",
|
||||
CellToName = "C1"
|
||||
});
|
||||
|
||||
uint rowIndex = 2;
|
||||
foreach (var sp in info.ShopPlanes)
|
||||
{
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = sp.ShopName,
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
rowIndex++;
|
||||
|
||||
foreach (var (Plane, Count) in sp.Planes)
|
||||
{
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "B",
|
||||
RowIndex = rowIndex,
|
||||
Text = Plane,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBroder
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
Text = Count.ToString(),
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBroder
|
||||
});
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = "Итого",
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
Text = sp.TotalCount.ToString(),
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
SaveExcel(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание excel-файла
|
||||
/// </summary>
|
||||
|
@ -46,6 +46,39 @@ namespace AircraftPlantBusinessLogic.OfficePackage
|
||||
SavePdf(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание отчета в Pdf-формате
|
||||
/// по закзам с группировкой по датам
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
public void CreateGroupOrdersDoc(PdfInfo info)
|
||||
{
|
||||
CreatePdf(info);
|
||||
CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
|
||||
|
||||
CreateTable(new List<string> { "4cm", "3cm", "2cm" });
|
||||
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { "Дата заказа", "Количество", "Сумма" },
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
|
||||
foreach (var order in info.GroupOrders)
|
||||
{
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { order.DateCreate.ToShortDateString(), order.Count.ToString(), order.Sum.ToString() },
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
}
|
||||
CreateParagraph(new PdfParagraph { Text = $"Итого: {info.GroupOrders.Sum(x => x.Sum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Right });
|
||||
|
||||
SavePdf(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание pdf-файла
|
||||
/// </summary>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using AircraftPlantBusinessLogic.OfficePackage.HelperEnums;
|
||||
using AircraftPlantBusinessLogic.OfficePackage.HelperModels;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -51,6 +52,52 @@ namespace AircraftPlantBusinessLogic.OfficePackage
|
||||
SaveWord(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание отчета по магазинам в doc-формате
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
public void CreateShopsDoc(WordInfo info)
|
||||
{
|
||||
CreateWord(info);
|
||||
|
||||
CreateParagraph(new WordParagraph
|
||||
{
|
||||
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
|
||||
TextProperties = new WordTextProperties
|
||||
{
|
||||
Size = "24",
|
||||
JustificationType = WordJustificationType.Center
|
||||
}
|
||||
});
|
||||
|
||||
CreateTable(new List<string> { "3000", "3000", "3000" });
|
||||
CreateRow(new WordRow
|
||||
{
|
||||
Texts = new List<string> { "Название", "Адрес", "Дата открытия" },
|
||||
TextProperties = new WordTextProperties
|
||||
{
|
||||
Size = "24",
|
||||
Bold = true,
|
||||
JustificationType = WordJustificationType.Center
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var shop in info.Shops)
|
||||
{
|
||||
CreateRow(new WordRow
|
||||
{
|
||||
Texts = new List<string> { shop.ShopName, shop.Address, shop.DateOpening.ToString() },
|
||||
TextProperties = new WordTextProperties
|
||||
{
|
||||
Size = "22",
|
||||
JustificationType = WordJustificationType.Both
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SaveWord(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание doc-файла
|
||||
/// </summary>
|
||||
@ -63,6 +110,18 @@ namespace AircraftPlantBusinessLogic.OfficePackage
|
||||
/// <param name="paragraph"></param>
|
||||
protected abstract void CreateParagraph(WordParagraph paragraph);
|
||||
|
||||
/// <summary>
|
||||
/// Создание таблицы
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
protected abstract void CreateTable(List<string> columns);
|
||||
|
||||
/// <summary>
|
||||
/// Создание строки
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
protected abstract void CreateRow(WordRow row);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение файла
|
||||
/// </summary>
|
||||
|
@ -27,5 +27,10 @@ namespace AircraftPlantBusinessLogic.OfficePackage.HelperModels
|
||||
/// Список изделий с расшифровкой по компонентам
|
||||
/// </summary>
|
||||
public List<ReportPlaneComponentViewModel> PlaneComponents { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Список магазинов с расшифровкой по изделиям
|
||||
/// </summary>
|
||||
public List<ReportShopPlanesViewModel> ShopPlanes { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -37,5 +37,10 @@ namespace AircraftPlantBusinessLogic.OfficePackage.HelperModels
|
||||
/// Список заказов
|
||||
/// </summary>
|
||||
public List<ReportOrdersViewModel> Orders { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Список заказов с группировкой по датам
|
||||
/// </summary>
|
||||
public List<ReportGroupOrdersViewModel> GroupOrders { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -27,5 +27,10 @@ namespace AircraftPlantBusinessLogic.OfficePackage.HelperModels
|
||||
/// Список изделий
|
||||
/// </summary>
|
||||
public List<PlaneViewModel> Planes { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Список магазинов
|
||||
/// </summary>
|
||||
public List<ShopViewModel> Shops { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantBusinessLogic.OfficePackage.HelperModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для передачи данных
|
||||
/// для создания строки файла-Word
|
||||
/// </summary>
|
||||
public class WordRow
|
||||
{
|
||||
/// <summary>
|
||||
/// Список текстов в строке
|
||||
/// </summary>
|
||||
public List<string> Texts { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Свойства строки
|
||||
/// </summary>
|
||||
public WordTextProperties? TextProperties { get; set; }
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -26,6 +27,11 @@ namespace AircraftPlantBusinessLogic.OfficePackage.Implements
|
||||
/// </summary>
|
||||
private Body? _docBody;
|
||||
|
||||
/// <summary>
|
||||
/// Таблица
|
||||
/// </summary>
|
||||
private Table? _table;
|
||||
|
||||
/// <summary>
|
||||
/// Получение типа выравнивания текста
|
||||
/// </summary>
|
||||
@ -141,6 +147,90 @@ namespace AircraftPlantBusinessLogic.OfficePackage.Implements
|
||||
_docBody.AppendChild(docParagraph);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание таблицы
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
protected override void CreateTable(List<string> columns)
|
||||
{
|
||||
if (_docBody == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_table = new Table();
|
||||
|
||||
var tableProperties = new TableProperties();
|
||||
tableProperties.AppendChild(new TableLayout { Type = TableLayoutValues.Fixed });
|
||||
tableProperties.AppendChild(new TableBorders(
|
||||
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
|
||||
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
|
||||
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
|
||||
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
|
||||
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
|
||||
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 }
|
||||
));
|
||||
tableProperties.AppendChild(new TableWidth { Type = TableWidthUnitValues.Auto });
|
||||
_table.AppendChild(tableProperties);
|
||||
|
||||
TableGrid tableGrid = new TableGrid();
|
||||
foreach (var column in columns)
|
||||
{
|
||||
tableGrid.AppendChild(new GridColumn() { Width = column });
|
||||
}
|
||||
_table.AppendChild(tableGrid);
|
||||
|
||||
_docBody.AppendChild(_table);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание строки
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
protected override void CreateRow(WordRow row)
|
||||
{
|
||||
if (_docBody == null || _table == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TableRow docRow = new TableRow();
|
||||
foreach (var column in row.Texts)
|
||||
{
|
||||
var docParagraph = new Paragraph();
|
||||
WordParagraph paragraph = new WordParagraph
|
||||
{
|
||||
Texts = new List<(string, WordTextProperties)> { (column, row.TextProperties) },
|
||||
TextProperties = row.TextProperties
|
||||
};
|
||||
|
||||
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
|
||||
|
||||
foreach (var run in paragraph.Texts)
|
||||
{
|
||||
var docRun = new Run();
|
||||
|
||||
var properties = new RunProperties();
|
||||
properties.AppendChild(new FontSize { Val = run.Item2.Size });
|
||||
if (run.Item2.Bold)
|
||||
{
|
||||
properties.AppendChild(new Bold());
|
||||
}
|
||||
docRun.AppendChild(properties);
|
||||
|
||||
docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve });
|
||||
|
||||
docParagraph.AppendChild(docRun);
|
||||
}
|
||||
|
||||
TableCell docCell = new TableCell();
|
||||
docCell.AppendChild(docParagraph);
|
||||
docRow.AppendChild(docCell);
|
||||
}
|
||||
|
||||
_table.AppendChild(docRow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение файла
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,50 @@
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.BindingModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для передачи данных пользователя
|
||||
/// в методы для сохранения данных для магазинов
|
||||
/// </summary>
|
||||
public class ShopBindingModel : IShopModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
public string ShopName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
public DateTime DateOpening { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
public Dictionary<int, (IPlaneModel, int)> ShopPlanes
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
public int MaxPlanes { get; set; }
|
||||
}
|
||||
}
|
@ -26,6 +26,18 @@ namespace AircraftPlantContracts.BusinessLogicsContracts
|
||||
/// <returns></returns>
|
||||
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка заказов с группировкой по датам
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<ReportGroupOrdersViewModel> GetGroupOrders();
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка магазинов с указанием хранимых изделий
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<ReportShopPlanesViewModel> GetShopPlanes();
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение изделий в файл-Word
|
||||
/// </summary>
|
||||
@ -43,5 +55,23 @@ namespace AircraftPlantContracts.BusinessLogicsContracts
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveOrdersToPdfFile(ReportBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение магазинов в Word-файл
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveShopsToWordFile(ReportBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение магазинов с указанием изделий в файл-Excel
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveShopPlanesToExcelFile(ReportBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение заказов с группировкой по датам в файл-Pdf
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveGroupOrdersToPdfFile(ReportBindingModel model);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.BusinessLogicsContracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Интерфейс для описания работы бизнес-логики для магазинов
|
||||
/// </summary>
|
||||
public interface IShopLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение списка
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
List<ShopViewModel>? ReadList(ShopSearchModel? model);
|
||||
|
||||
/// <summary>
|
||||
/// Получение отдельной записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
ShopViewModel? ReadElement(ShopSearchModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Создание записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
bool Create(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Изменение записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
bool Update(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление записи
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
bool Delete(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление изделия в магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
bool AddPlaneInShop(ShopSearchModel model, IPlaneModel plane, int count);
|
||||
|
||||
/// <summary>
|
||||
/// Продажа изделий
|
||||
/// </summary>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
bool SellPlanes(IPlaneModel plane, int count);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.SearchModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для передачи данных пользователя
|
||||
/// в методы для поиска данных для магазинов
|
||||
/// </summary>
|
||||
public class ShopSearchModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
public string? ShopName { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.StoragesContracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Интерфейс для описания работы с хранилищем для магазинов
|
||||
/// </summary>
|
||||
public interface IShopStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение полного списка
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<ShopViewModel> GetFullList();
|
||||
|
||||
/// <summary>
|
||||
/// Получение фильтрованного списка
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
List<ShopViewModel> GetFilteredList(ShopSearchModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Получение элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
ShopViewModel? GetElement(ShopSearchModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
ShopViewModel? Insert(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
ShopViewModel? Update(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
ShopViewModel? Delete(ShopBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Продажа изделий
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
bool SellPlanes(IPlaneModel model, int count);
|
||||
|
||||
/// <summary>
|
||||
/// Проверка наличия в нужном количестве
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
bool CheckCount(IPlaneModel model, int count);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для отчета по заказам с группировкой по датам
|
||||
/// </summary>
|
||||
public class ReportGroupOrdersViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Дата создания заказа
|
||||
/// </summary>
|
||||
public DateTime DateCreate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество изделий
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Сумма заказа
|
||||
/// </summary>
|
||||
public double Sum { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для отчета по магазинам с расшифровкой по изделиям
|
||||
/// </summary>
|
||||
public class ReportShopPlanesViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
public string ShopName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список изделий в магазине
|
||||
/// </summary>
|
||||
public List<(string Plane, int Count)> Planes { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantContracts.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Модель для передачи данных пользователю
|
||||
/// для отображения для магазинов
|
||||
/// </summary>
|
||||
public class ShopViewModel : IShopModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
[DisplayName("Название магазина")]
|
||||
public string ShopName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
[DisplayName("Адрес магазина")]
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
[DisplayName("Дата открытия")]
|
||||
public DateTime DateOpening { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
public Dictionary<int, (IPlaneModel, int)> ShopPlanes
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
[DisplayName("Максимальное количество изделий")]
|
||||
public int MaxPlanes { get; set; }
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ namespace AircraftPlantDataModels.Enums
|
||||
|
||||
Готов = 2,
|
||||
|
||||
Выдан = 3
|
||||
Выдан = 3,
|
||||
|
||||
Ожидание = 4
|
||||
}
|
||||
}
|
||||
|
39
AircraftPlant/AircraftPlantDataModels/Models/IShopModel.cs
Normal file
39
AircraftPlant/AircraftPlantDataModels/Models/IShopModel.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantDataModels.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Интерфейс для модели магазина
|
||||
/// </summary>
|
||||
public interface IShopModel : IId
|
||||
{
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
string ShopName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
string Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
DateTime DateOpening { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
Dictionary<int, (IPlaneModel, int)> ShopPlanes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
int MaxPlanes { get; }
|
||||
}
|
||||
}
|
@ -46,6 +46,16 @@ namespace AircraftPlantDatabaseImplement
|
||||
/// </summary>
|
||||
public virtual DbSet<Order> Orders { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Таблица магазинов
|
||||
/// </summary>
|
||||
public virtual DbSet<Shop> Shops { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Связь между магазинами и изделиями
|
||||
/// </summary>
|
||||
public virtual DbSet<ShopPlane> ShopPlanes { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// Таблица клиентов
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,222 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.StoragesContracts;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDatabaseImplement.Models;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantDatabaseImplement.Implements
|
||||
{
|
||||
/// <summary>
|
||||
/// Реализация интерфейса хранилища для магазинов
|
||||
/// </summary>
|
||||
public class ShopStorage : IShopStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение полного списка
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ShopViewModel> GetFullList()
|
||||
{
|
||||
using var context = new AircraftPlantDatabase();
|
||||
return context.Shops
|
||||
.Include(x => x.Planes)
|
||||
.ThenInclude(x => x.Plane)
|
||||
.ToList()
|
||||
.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();
|
||||
}
|
||||
|
||||
using var context = new AircraftPlantDatabase();
|
||||
return context.Shops
|
||||
.Include(x => x.Planes)
|
||||
.ThenInclude(x => x.Plane)
|
||||
.Where(x => x.ShopName.Contains(model.ShopName))
|
||||
.ToList()
|
||||
.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;
|
||||
}
|
||||
|
||||
using var context = new AircraftPlantDatabase();
|
||||
return context.Shops
|
||||
.Include(x => x.Planes)
|
||||
.ThenInclude(x => x.Plane)
|
||||
.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)
|
||||
{
|
||||
using var context = new AircraftPlantDatabase();
|
||||
var newShop = Shop.Create(context, model);
|
||||
if (newShop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
context.Shops.Add(newShop);
|
||||
context.SaveChanges();
|
||||
return newShop.GetViewModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public ShopViewModel? Update(ShopBindingModel model)
|
||||
{
|
||||
using var context = new AircraftPlantDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var shop = context.Shops.FirstOrDefault(rec => rec.Id == model.Id);
|
||||
if (shop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
shop.Update(model);
|
||||
context.SaveChanges();
|
||||
shop.UpdatePlanes(context, model);
|
||||
transaction.Commit();
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public ShopViewModel? Delete(ShopBindingModel model)
|
||||
{
|
||||
using var context = new AircraftPlantDatabase();
|
||||
var element = context.Shops
|
||||
.Include(x => x.Planes)
|
||||
.FirstOrDefault(rec => rec.Id == model.Id);
|
||||
if (element != null)
|
||||
{
|
||||
context.Shops.Remove(element);
|
||||
context.SaveChanges();
|
||||
return element.GetViewModel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Продажа изделий
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public bool SellPlanes(IPlaneModel model, int count)
|
||||
{
|
||||
using var context = new AircraftPlantDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var shops = context.Shops
|
||||
.Include(x => x.Planes)
|
||||
.ThenInclude(x => x.Plane)
|
||||
.ToList()
|
||||
.Where(x => x.ShopPlanes.ContainsKey(model.Id));
|
||||
|
||||
foreach (var shop in shops)
|
||||
{
|
||||
int countInCurrentShop = shop.ShopPlanes[model.Id].Item2;
|
||||
if (countInCurrentShop <= count)
|
||||
{
|
||||
var elem = context.ShopPlanes
|
||||
.Where(x => x.PlaneId == model.Id)
|
||||
.FirstOrDefault(x => x.ShopId == shop.Id);
|
||||
context.ShopPlanes.Remove(elem);
|
||||
shop.ShopPlanes.Remove(model.Id);
|
||||
count -= countInCurrentShop;
|
||||
}
|
||||
else
|
||||
{
|
||||
shop.ShopPlanes[model.Id] = (shop.ShopPlanes[model.Id].Item1, countInCurrentShop - count);
|
||||
count = 0;
|
||||
shop.UpdatePlanes(context, new ShopBindingModel
|
||||
{
|
||||
Id = shop.Id,
|
||||
ShopName = shop.ShopName,
|
||||
Address = shop.Address,
|
||||
DateOpening = shop.DateOpening,
|
||||
ShopPlanes = shop.ShopPlanes,
|
||||
MaxPlanes = shop.MaxPlanes
|
||||
});
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
transaction.Rollback();
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка наличия в нужном количестве
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public bool CheckCount(IPlaneModel model, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
246
AircraftPlant/AircraftPlantDatabaseImplement/Migrations/20240324224237_HardCreate.Designer.cs
generated
Normal file
246
AircraftPlant/AircraftPlantDatabaseImplement/Migrations/20240324224237_HardCreate.Designer.cs
generated
Normal file
@ -0,0 +1,246 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using AircraftPlantDatabaseImplement;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AircraftPlantDatabaseImplement.Migrations
|
||||
{
|
||||
[DbContext(typeof(AircraftPlantDatabase))]
|
||||
[Migration("20240324224237_HardCreate")]
|
||||
partial class HardCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ComponentName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<double>("Cost")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Components");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DateCreate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("DateImplement")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("PlaneId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<double>("Sum")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlaneId");
|
||||
|
||||
b.ToTable("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("PlaneName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Planes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("ComponentId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("PlaneId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ComponentId");
|
||||
|
||||
b.HasIndex("PlaneId");
|
||||
|
||||
b.ToTable("PlaneComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("DateOpening")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("MaxPlanes")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ShopName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Shops");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.ShopPlane", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("PlaneId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ShopId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlaneId");
|
||||
|
||||
b.HasIndex("ShopId");
|
||||
|
||||
b.ToTable("ShopPlanes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
|
||||
{
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", null)
|
||||
.WithMany("Orders")
|
||||
.HasForeignKey("PlaneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
|
||||
{
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Component", "Component")
|
||||
.WithMany("PlaneComponents")
|
||||
.HasForeignKey("ComponentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
|
||||
.WithMany("Components")
|
||||
.HasForeignKey("PlaneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Component");
|
||||
|
||||
b.Navigation("Plane");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.ShopPlane", b =>
|
||||
{
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
|
||||
.WithMany()
|
||||
.HasForeignKey("PlaneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Shop", "Shop")
|
||||
.WithMany("Planes")
|
||||
.HasForeignKey("ShopId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Plane");
|
||||
|
||||
b.Navigation("Shop");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
|
||||
{
|
||||
b.Navigation("PlaneComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
|
||||
{
|
||||
b.Navigation("Components");
|
||||
|
||||
b.Navigation("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Navigation("Planes");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AircraftPlantDatabaseImplement.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class HardCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Shops",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ShopName = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
DateOpening = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
MaxPlanes = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Shops", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShopPlanes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
ShopId = table.Column<int>(type: "int", nullable: false),
|
||||
PlaneId = table.Column<int>(type: "int", nullable: false),
|
||||
Count = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShopPlanes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShopPlanes_Planes_PlaneId",
|
||||
column: x => x.PlaneId,
|
||||
principalTable: "Planes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShopPlanes_Shops_ShopId",
|
||||
column: x => x.ShopId,
|
||||
principalTable: "Shops",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShopPlanes_PlaneId",
|
||||
table: "ShopPlanes",
|
||||
column: "PlaneId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShopPlanes_ShopId",
|
||||
table: "ShopPlanes",
|
||||
column: "ShopId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ShopPlanes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Shops");
|
||||
}
|
||||
}
|
||||
}
|
@ -183,6 +183,59 @@ namespace AircraftPlantDatabaseImplement.Migrations
|
||||
b.ToTable("PlaneComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("DateOpening")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("MaxPlanes")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ShopName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Shops");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.ShopPlane", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("PlaneId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ShopId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlaneId");
|
||||
|
||||
b.HasIndex("ShopId");
|
||||
|
||||
b.ToTable("ShopPlanes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
|
||||
{
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
|
||||
@ -227,6 +280,25 @@ namespace AircraftPlantDatabaseImplement.Migrations
|
||||
b.Navigation("Plane");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.ShopPlane", b =>
|
||||
{
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
|
||||
.WithMany()
|
||||
.HasForeignKey("PlaneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AircraftPlantDatabaseImplement.Models.Shop", "Shop")
|
||||
.WithMany("Planes")
|
||||
.HasForeignKey("ShopId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Plane");
|
||||
|
||||
b.Navigation("Shop");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
|
||||
{
|
||||
b.Navigation("Orders");
|
||||
@ -248,6 +320,11 @@ namespace AircraftPlantDatabaseImplement.Migrations
|
||||
|
||||
b.Navigation("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Navigation("Planes");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
157
AircraftPlant/AircraftPlantDatabaseImplement/Models/Shop.cs
Normal file
157
AircraftPlant/AircraftPlantDatabaseImplement/Models/Shop.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantDatabaseImplement.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Сущность "Магазин"
|
||||
/// </summary>
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ShopName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTime DateOpening { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
private Dictionary<int, (IPlaneModel, int)>? _shopPlanes = null;
|
||||
|
||||
[NotMapped]
|
||||
public Dictionary<int, (IPlaneModel, int)> ShopPlanes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_shopPlanes == null)
|
||||
{
|
||||
_shopPlanes = Planes
|
||||
.ToDictionary(recSP => recSP.PlaneId, recSP => (recSP.Plane as IPlaneModel, recSP.Count));
|
||||
}
|
||||
return _shopPlanes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
public int MaxPlanes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Связь с классом связи магазина и изделий
|
||||
/// </summary>
|
||||
[ForeignKey("ShopId")]
|
||||
public List<ShopPlane> Planes { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Создание модели магазина
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public static Shop Create(AircraftPlantDatabase context, ShopBindingModel model)
|
||||
{
|
||||
return new Shop
|
||||
{
|
||||
Id = model.Id,
|
||||
ShopName = model.ShopName,
|
||||
Address = model.Address,
|
||||
DateOpening = model.DateOpening,
|
||||
MaxPlanes = model.MaxPlanes,
|
||||
Planes = model.ShopPlanes.Select(x => new ShopPlane
|
||||
{
|
||||
Plane = context.Planes.First(y => y.Id == x.Key),
|
||||
Count = x.Value.Item2
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Изменение модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void Update(ShopBindingModel model)
|
||||
{
|
||||
ShopName = model.ShopName;
|
||||
Address = model.Address;
|
||||
DateOpening = model.DateOpening;
|
||||
MaxPlanes = model.MaxPlanes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение модели магазина
|
||||
/// </summary>
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
ShopName = ShopName,
|
||||
Address = Address,
|
||||
DateOpening = DateOpening,
|
||||
ShopPlanes = ShopPlanes,
|
||||
MaxPlanes = MaxPlanes
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Метод обновления списка связей
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="model"></param>
|
||||
public void UpdatePlanes(AircraftPlantDatabase context, ShopBindingModel model)
|
||||
{
|
||||
var shopPlanes = context.ShopPlanes.Where(rec => rec.ShopId == model.Id).ToList();
|
||||
if (shopPlanes != null && shopPlanes.Count > 0)
|
||||
{
|
||||
// Удаление изделий, которых нет в магазине
|
||||
context.ShopPlanes.RemoveRange(shopPlanes.Where(rec => !model.ShopPlanes.ContainsKey(rec.PlaneId)));
|
||||
context.SaveChanges();
|
||||
// Обновление количества у существующих записей
|
||||
foreach (var updatePlanes in shopPlanes)
|
||||
{
|
||||
updatePlanes.Count = model.ShopPlanes[updatePlanes.PlaneId].Item2;
|
||||
model.ShopPlanes.Remove(updatePlanes.PlaneId);
|
||||
}
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
||||
var shop = context.Shops.First(x => x.Id == Id);
|
||||
foreach (var sp in model.ShopPlanes)
|
||||
{
|
||||
context.ShopPlanes.Add(new ShopPlane
|
||||
{
|
||||
Shop = shop,
|
||||
Plane = context.Planes.First(x => x.Id == sp.Key),
|
||||
Count = sp.Value.Item2
|
||||
});
|
||||
context.SaveChanges();
|
||||
}
|
||||
_shopPlanes = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantDatabaseImplement.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Класс для связи магазина и изделия
|
||||
/// </summary>
|
||||
public class ShopPlane
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор магазина
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int ShopId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор изделия
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int PlaneId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество изделий
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Магазин
|
||||
/// </summary>
|
||||
public virtual Shop Shop { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Изделие
|
||||
/// </summary>
|
||||
public virtual Plane Plane { get; set; } = new();
|
||||
}
|
||||
}
|
@ -38,6 +38,11 @@ namespace AircraftPlantFileImplement
|
||||
/// </summary>
|
||||
private readonly string ClientFileName = "Client.xml";
|
||||
|
||||
/// <summary>
|
||||
/// Название файла для хранения информации о магазинах
|
||||
/// </summary>
|
||||
private readonly string ShopFileName = "Shop.xml";
|
||||
|
||||
/// <summary>
|
||||
/// Название файла для хранения информации о исполнителях
|
||||
/// </summary>
|
||||
@ -58,6 +63,11 @@ namespace AircraftPlantFileImplement
|
||||
/// </summary>
|
||||
public List<Plane> Planes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список классов-моделей магазина
|
||||
/// </summary>
|
||||
public List<Shop> Shops { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список классов-моделей клиентов
|
||||
/// </summary>
|
||||
@ -76,6 +86,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)!)!;
|
||||
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
|
||||
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
|
||||
}
|
||||
@ -108,6 +119,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>
|
||||
/// Сохранение клиентов
|
||||
/// </summary>
|
||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace AircraftPlantFileImplement.Implements
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
158
AircraftPlant/AircraftPlantFileImplement/Models/Shop.cs
Normal file
158
AircraftPlant/AircraftPlantFileImplement/Models/Shop.cs
Normal file
@ -0,0 +1,158 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace AircraftPlantFileImplement.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Сущность "Магазин"
|
||||
/// </summary>
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
public string ShopName { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
public string Address { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
public DateTime DateOpening { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий магазина в виде
|
||||
/// «идентификатор изделия – количество изделий»
|
||||
/// </summary>
|
||||
public Dictionary<int, int> Planes { get; private set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
private Dictionary<int, (IPlaneModel, int)>? _shopPlanes = null;
|
||||
public Dictionary<int, (IPlaneModel, int)> ShopPlanes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_shopPlanes == null)
|
||||
{
|
||||
var source = DataFileSingleton.GetInstance();
|
||||
_shopPlanes = Planes.ToDictionary(x => x.Key, y => ((source.Planes.FirstOrDefault(z => z.Id == y.Key) as IPlaneModel)!, y.Value));
|
||||
}
|
||||
return _shopPlanes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
public int MaxPlanes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Создание модели магазина из данных файла
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
/// <returns></returns>
|
||||
public static Shop? Create(XElement element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new()
|
||||
{
|
||||
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
|
||||
ShopName = element.Element("ShopName")!.Value,
|
||||
Address = element.Element("Address")!.Value,
|
||||
DateOpening = Convert.ToDateTime(element.Element("DateOpening")!.Value),
|
||||
Planes = element.Element("ShopPlanes")!.Elements("ShopPlanes")!
|
||||
.ToDictionary(x => Convert.ToInt32(x.Element("Key")?.Value), x => Convert.ToInt32(x.Element("Value")?.Value)),
|
||||
MaxPlanes = Convert.ToInt32(element.Element("MaxPlanes")!.Value)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public static Shop? Create(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Shop()
|
||||
{
|
||||
Id = model.Id,
|
||||
ShopName = model.ShopName,
|
||||
Address = model.Address,
|
||||
DateOpening = model.DateOpening,
|
||||
Planes = model.ShopPlanes.ToDictionary(x => x.Key, x => x.Value.Item2),
|
||||
MaxPlanes = model.MaxPlanes
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Изменение модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void Update(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShopName = model.ShopName;
|
||||
Address = model.Address;
|
||||
DateOpening = model.DateOpening;
|
||||
Planes = model.ShopPlanes.ToDictionary(x => x.Key, x => x.Value.Item2);
|
||||
MaxPlanes = model.MaxPlanes;
|
||||
_shopPlanes = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение модели магазина
|
||||
/// </summary>
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
ShopName = ShopName,
|
||||
Address = Address,
|
||||
DateOpening = DateOpening,
|
||||
ShopPlanes = ShopPlanes,
|
||||
MaxPlanes = MaxPlanes
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Запись данных о модели магазина в файл
|
||||
/// </summary>
|
||||
public XElement GetXElement => new("Shop",
|
||||
new XAttribute("Id", Id),
|
||||
new XElement("ShopName", ShopName),
|
||||
new XElement("Address", Address),
|
||||
new XElement("DateOpening", DateOpening.ToString()),
|
||||
new XElement("ShopPlanes", Planes.Select(x =>
|
||||
new XElement("ShopPlanes",
|
||||
new XElement("Key", x.Key),
|
||||
new XElement("Value", x.Value))).ToArray()),
|
||||
new XElement("MaxPlanes", MaxPlanes.ToString()));
|
||||
}
|
||||
}
|
@ -32,6 +32,11 @@ namespace AircraftPlantListImplement
|
||||
/// </summary>
|
||||
public List<Plane> Planes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список классов-моделей магазинов
|
||||
/// </summary>
|
||||
public List<Shop> Shops { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Список классов-моделей клиентов
|
||||
/// </summary>
|
||||
@ -50,6 +55,7 @@ namespace AircraftPlantListImplement
|
||||
Components = new List<Component>();
|
||||
Orders = new List<Order>();
|
||||
Planes = new List<Plane>();
|
||||
Shops = new List<Shop>();
|
||||
Clients = new List<Client>();
|
||||
Implementers = new List<Implementer>();
|
||||
}
|
||||
|
@ -0,0 +1,179 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.StoragesContracts;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using AircraftPlantListImplement.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantListImplement.Implements
|
||||
{
|
||||
/// <summary>
|
||||
/// Реализация интерфейса хранилища для магазина
|
||||
/// </summary>
|
||||
public class ShopStorage : IShopStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// Хранилище
|
||||
/// </summary>
|
||||
private readonly DataListSingleton _source;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
public ShopStorage()
|
||||
{
|
||||
_source = DataListSingleton.GetInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение полного списка
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ShopViewModel> GetFullList()
|
||||
{
|
||||
var result = new List<ShopViewModel>();
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
result.Add(shop.GetViewModel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение фильтрованного списка
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
|
||||
{
|
||||
var result = new List<ShopViewModel>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавление элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public ShopViewModel? Update(ShopBindingModel model)
|
||||
{
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
if (shop.Id == model.Id)
|
||||
{
|
||||
shop.Update(model);
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удаление элемента
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Продажа изделий
|
||||
/// </summary>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public bool SellPlanes(IPlaneModel model, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка наличия в нужном количестве
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public bool CheckCount(IPlaneModel model, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
105
AircraftPlant/AircraftPlantListImplement/Models/Shop.cs
Normal file
105
AircraftPlant/AircraftPlantListImplement/Models/Shop.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AircraftPlantListImplement.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Сущность "Магазин"
|
||||
/// </summary>
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор
|
||||
/// </summary>
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название магазина
|
||||
/// </summary>
|
||||
public string ShopName { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес магазина
|
||||
/// </summary>
|
||||
public string Address { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Дата открытия магазина
|
||||
/// </summary>
|
||||
public DateTime DateOpening { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Коллекция изделий в магазине
|
||||
/// </summary>
|
||||
public Dictionary<int, (IPlaneModel, int)> ShopPlanes
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
} = new Dictionary<int, (IPlaneModel, int)>();
|
||||
|
||||
/// <summary>
|
||||
/// Максимальное количество изделий
|
||||
/// </summary>
|
||||
public int MaxPlanes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Создание модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public static Shop? Create(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Shop()
|
||||
{
|
||||
Id = model.Id,
|
||||
ShopName = model.ShopName,
|
||||
Address = model.Address,
|
||||
DateOpening = model.DateOpening,
|
||||
ShopPlanes = model.ShopPlanes,
|
||||
MaxPlanes = model.MaxPlanes
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Изменение модели магазина
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void Update(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShopName = model.ShopName;
|
||||
Address = model.Address;
|
||||
DateOpening = model.DateOpening;
|
||||
ShopPlanes = model.ShopPlanes;
|
||||
MaxPlanes = model.MaxPlanes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение модели магазина
|
||||
/// </summary>
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
ShopName = ShopName,
|
||||
Address = Address,
|
||||
DateOpening = DateOpening,
|
||||
ShopPlanes = ShopPlanes,
|
||||
MaxPlanes = MaxPlanes
|
||||
};
|
||||
}
|
||||
}
|
154
AircraftPlant/AircraftPlantRestApi/Controllers/ShopController.cs
Normal file
154
AircraftPlant/AircraftPlantRestApi/Controllers/ShopController.cs
Normal file
@ -0,0 +1,154 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.BusinessLogicsContracts;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantDatabaseImplement.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AircraftPlantRestApi.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Контроллер для работы с магазинами
|
||||
/// </summary>
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ShopController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Логгер
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Бизнес-логика для магазинов
|
||||
/// </summary>
|
||||
private readonly IShopLogic _shopLogic;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="shopLogic"></param>
|
||||
public ShopController(ILogger<MainController> logger, IShopLogic shopLogic)
|
||||
{
|
||||
_logger = logger;
|
||||
_shopLogic = shopLogic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка магазинов
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public List<ShopViewModel>? GetShops()
|
||||
{
|
||||
try
|
||||
{
|
||||
return _shopLogic.ReadList(null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения списка магазинов");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение магазина
|
||||
/// </summary>
|
||||
/// <param name="shopId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public Tuple<ShopViewModel, List<Tuple<string, int>>>? GetShop(int shopId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var shop = _shopLogic.ReadElement(new ShopSearchModel { Id = shopId });
|
||||
if (shop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Tuple.Create(shop, shop.ShopPlanes.Select(x => Tuple.Create(x.Value.Item1.PlaneName, x.Value.Item2)).ToList());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения магазина по id={Id}", shopId);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создать магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
[HttpPost]
|
||||
public void CreateShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shopLogic.Create(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка создания магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Изменить магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
[HttpPost]
|
||||
public void UpdateShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
model.ShopPlanes = null!;
|
||||
_shopLogic.Update(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления данных");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удалить магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
[HttpPost]
|
||||
public void DeleteShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shopLogic.Delete(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка удаления магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить изделие в магазин
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
[HttpPost]
|
||||
public void AddPlaneInShop(Tuple<ShopSearchModel, PlaneViewModel, int> model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shopLogic.AddPlaneInShop(model.Item1, model.Item2, model.Item3);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка добавления изделия в магазин");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,11 +14,13 @@ builder.Services.AddTransient<IClientStorage, ClientStorage>();
|
||||
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
|
||||
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
|
||||
builder.Services.AddTransient<IPlaneStorage, PlaneStorage>();
|
||||
builder.Services.AddTransient<IShopStorage, ShopStorage>();
|
||||
|
||||
builder.Services.AddTransient<IClientLogic, ClientLogic>();
|
||||
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
|
||||
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
|
||||
builder.Services.AddTransient<IPlaneLogic, PlaneLogic>();
|
||||
builder.Services.AddTransient<IShopLogic, ShopLogic>();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
|
91
AircraftPlant/AircraftPlantShopApp/APIClient.cs
Normal file
91
AircraftPlant/AircraftPlantShopApp/APIClient.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace AircraftPlantShopApp
|
||||
{
|
||||
/// <summary>
|
||||
/// API-клиент
|
||||
/// </summary>
|
||||
public class APIClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Http-клиент
|
||||
/// </summary>
|
||||
private static readonly HttpClient _client = new();
|
||||
|
||||
/// <summary>
|
||||
/// Пароль
|
||||
/// </summary>
|
||||
public static string Password { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Доступ
|
||||
/// </summary>
|
||||
public static bool Access { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
public static void Connect(IConfiguration configuration)
|
||||
{
|
||||
Password = configuration["Password"];
|
||||
_client.BaseAddress = new Uri(configuration["IPAddress"]);
|
||||
_client.DefaultRequestHeaders.Accept.Clear();
|
||||
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get-запрос
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="requestUrl"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static T? GetRequest<T>(string requestUrl)
|
||||
{
|
||||
var response = _client.GetAsync(requestUrl);
|
||||
var result = response.Result.Content.ReadAsStringAsync().Result;
|
||||
if (response.Result.IsSuccessStatusCode)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post-запрос
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="requestUrl"></param>
|
||||
/// <param name="model"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static void PostRequest<T>(string requestUrl, T model)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(model);
|
||||
var data = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = _client.PostAsync(requestUrl, data);
|
||||
|
||||
var result = response.Result.Content.ReadAsStringAsync().Result;
|
||||
if (!response.Result.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка доступа
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckPassword(string password)
|
||||
{
|
||||
return APIClient.Access = password == Password;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AircraftPlantContracts\AircraftPlantContracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
296
AircraftPlant/AircraftPlantShopApp/Controllers/HomeController.cs
Normal file
296
AircraftPlant/AircraftPlantShopApp/Controllers/HomeController.cs
Normal file
@ -0,0 +1,296 @@
|
||||
using AircraftPlantContracts.BindingModels;
|
||||
using AircraftPlantContracts.SearchModels;
|
||||
using AircraftPlantContracts.ViewModels;
|
||||
using AircraftPlantShopApp.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AircraftPlantShopApp.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Контроллер
|
||||
/// </summary>
|
||||
public class HomeController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Логгер
|
||||
/// </summary>
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
public HomeController(ILogger<HomeController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вход в приложение
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IActionResult Enter()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вход в приложение
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpPost]
|
||||
public void Enter(string password)
|
||||
{
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
throw new Exception("Введите пароль");
|
||||
}
|
||||
|
||||
if (!APIClient.CheckPassword(password))
|
||||
{
|
||||
throw new Exception("Неправильный пароль");
|
||||
}
|
||||
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение списка магазинов
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Index()
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View(APIClient.GetRequest<List<ShopViewModel>>($"api/shop/getshops"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение магазина
|
||||
/// </summary>
|
||||
/// <param name="shopId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpGet]
|
||||
public Tuple<ShopViewModel, string>? GetShop(int shopId)
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
|
||||
var result = APIClient.GetRequest<Tuple<ShopViewModel, List<Tuple<string, int>>>>($"api/shop/getshop?shopid={shopId}");
|
||||
if (result == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
string table = "";
|
||||
for (int i = 0; i < result.Item2.Count; i++)
|
||||
{
|
||||
var plane = result.Item2[i].Item1;
|
||||
var count = result.Item2[i].Item2;
|
||||
table += "<tr>";
|
||||
table += $"<td>{plane}</td>";
|
||||
table += $"<td>{count}</td>";
|
||||
table += "</tr>";
|
||||
}
|
||||
return Tuple.Create(result.Item1, table);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создать магазин
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Create()
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создать магазин
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpPost]
|
||||
public void Create(string name, string address, DateTime date, int count)
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(address) || count <= 0)
|
||||
{
|
||||
throw new Exception("Введите название");
|
||||
}
|
||||
if (string.IsNullOrEmpty(address))
|
||||
{
|
||||
throw new Exception("Введите адрес");
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new Exception("Введите количество");
|
||||
}
|
||||
|
||||
APIClient.PostRequest("api/shop/createshop", new ShopBindingModel
|
||||
{
|
||||
ShopName = name,
|
||||
Address = address,
|
||||
MaxPlanes = count,
|
||||
DateOpening = date
|
||||
});
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновить магазин
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Update()
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обновить магазин
|
||||
/// </summary>
|
||||
/// <param name="shop"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpPost]
|
||||
public void Update(int shop, string name, string address, DateTime date, int count)
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new Exception("Название магазина не может быть пустым");
|
||||
}
|
||||
if (string.IsNullOrEmpty(address))
|
||||
{
|
||||
throw new Exception("Адрес магазина не может быть пустым");
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new Exception("Вместимость магазина не может быть меньше нуля");
|
||||
}
|
||||
|
||||
APIClient.PostRequest("api/shop/updateshop", new ShopBindingModel
|
||||
{
|
||||
Id = shop,
|
||||
ShopName = name,
|
||||
Address = address,
|
||||
DateOpening = date,
|
||||
MaxPlanes = count
|
||||
});
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удалить магазин
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Delete()
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Удалить магазин
|
||||
/// </summary>
|
||||
/// <param name="shop"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpPost]
|
||||
public void Delete(int shop)
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
|
||||
APIClient.PostRequest("api/shop/deleteshop", new ShopBindingModel
|
||||
{
|
||||
Id = shop
|
||||
});
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить изделие в магазин
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult AddPlane()
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
|
||||
ViewBag.Planes = APIClient.GetRequest<List<PlaneViewModel>>("api/main/getplanelist");
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить изделие в магазин
|
||||
/// </summary>
|
||||
/// <param name="shop"></param>
|
||||
/// <param name="plane"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
[HttpPost]
|
||||
public void AddPlane(int shop, int plane, int count)
|
||||
{
|
||||
if (APIClient.Access == false)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
|
||||
APIClient.PostRequest("api/shop/AddPlaneInShop", Tuple.Create(
|
||||
new ShopSearchModel() { Id = shop },
|
||||
new PlaneViewModel() { Id = plane },
|
||||
count
|
||||
));
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ошибка
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace AircraftPlantShopApp.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
30
AircraftPlant/AircraftPlantShopApp/Program.cs
Normal file
30
AircraftPlant/AircraftPlantShopApp/Program.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using AircraftPlantShopApp;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
|
||||
var app = builder.Build();
|
||||
APIClient.Connect(builder.Configuration);
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.Run();
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:3158",
|
||||
"sslPort": 44306
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"AircraftPlantShopApp": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7210;http://localhost:5174",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
@using AircraftPlantContracts.ViewModels;
|
||||
@using AircraftPlantDataModels.Models;
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
|
||||
@model Dictionary<int, (IPlaneModel, int)>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Добавление изделия в магазин</h2>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Магазин:</div>
|
||||
<div class="col-8">
|
||||
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Изделие:</div>
|
||||
<div class="col-8">
|
||||
<select id="plane" name="plane" class="form-control" asp-items="@(new SelectList(@ViewBag.Planes, "Id", "PlaneName"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Количество:</div>
|
||||
<div class="col-8"><input type="number" id="count" name="count" min="1" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
29
AircraftPlant/AircraftPlantShopApp/Views/Home/Create.cshtml
Normal file
29
AircraftPlant/AircraftPlantShopApp/Views/Home/Create.cshtml
Normal file
@ -0,0 +1,29 @@
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Создание магазина</h2>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Название:</div>
|
||||
<div class="col-8"><input type="text" name="name" id="name" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Адрес:</div>
|
||||
<div class="col-8"><input type="text" id="address" name="address" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Дата открытия:</div>
|
||||
<div class="col-8"><input type="date" id="date" name="date" class="form-control" required /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Вместимость:</div>
|
||||
<div class="col-8"><input type="number" id="count" name="count" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
18
AircraftPlant/AircraftPlantShopApp/Views/Home/Delete.cshtml
Normal file
18
AircraftPlant/AircraftPlantShopApp/Views/Home/Delete.cshtml
Normal file
@ -0,0 +1,18 @@
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Удаление магазина</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Магазин:</div>
|
||||
<div class="col-8">
|
||||
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4"></div>
|
||||
<div class="col-8"><input type="submit" value="Удалить" class="btn btn-danger" /></div>
|
||||
</div>
|
||||
</form>
|
15
AircraftPlant/AircraftPlantShopApp/Views/Home/Enter.cshtml
Normal file
15
AircraftPlant/AircraftPlantShopApp/Views/Home/Enter.cshtml
Normal file
@ -0,0 +1,15 @@
|
||||
@{
|
||||
ViewData["Title"] = "Enter";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Вход в приложение</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Пароль:</div>
|
||||
<div class="col-8"><input type="password" name="password" /></div>
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
60
AircraftPlant/AircraftPlantShopApp/Views/Home/Index.cshtml
Normal file
60
AircraftPlant/AircraftPlantShopApp/Views/Home/Index.cshtml
Normal file
@ -0,0 +1,60 @@
|
||||
@using AircraftPlantContracts.ViewModels
|
||||
|
||||
@model List<ShopViewModel>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Магазины</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
<p>
|
||||
<a asp-action="Create">Создать магазин</a>
|
||||
<a asp-action="Update">Редактировать магазин</a>
|
||||
<a asp-action="Delete">Удалить магазин</a>
|
||||
<a asp-action="AddPlane">Добавить изделия в магазин</a>
|
||||
</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Название магазина
|
||||
</th>
|
||||
<th>
|
||||
Адрес
|
||||
</th>
|
||||
<th>
|
||||
Дата открытия
|
||||
</th>
|
||||
<th>
|
||||
Максимальное количество изделий
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.ShopName)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Address)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.DateOpening)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.MaxPlanes)
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
81
AircraftPlant/AircraftPlantShopApp/Views/Home/Update.cshtml
Normal file
81
AircraftPlant/AircraftPlantShopApp/Views/Home/Update.cshtml
Normal file
@ -0,0 +1,81 @@
|
||||
@using AircraftPlantContracts.ViewModels;
|
||||
@using AircraftPlantDataModels.Models;
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Update";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Редактирование магазина</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Магазин:</div>
|
||||
<div class="col-8">
|
||||
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Название:</div>
|
||||
<div class="col-8"><input type="text" name="name" id="name" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Адрес:</div>
|
||||
<div class="col-8"><input type="text" id="address" name="address" class="form-control" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Дата открытия:</div>
|
||||
<div class="col-8"><input type="datetime-local" id="date" name="date" class="form-control" required /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Вместимость:</div>
|
||||
<div class="col-8"><input type="number" id="count" name="count" class="form-control" /></div>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Изделие
|
||||
</th>
|
||||
<th>
|
||||
Количество
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-elements">
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script>
|
||||
function check() {
|
||||
var shop = $('#shop').val();
|
||||
if (shop) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: "/Home/GetShop",
|
||||
data: { shopId: shop },
|
||||
success: function (result) {
|
||||
$('#name').val(result.item1.shopName);
|
||||
$('#address').val(result.item1.address);
|
||||
$('#date').val(result.item1.dateOpening);
|
||||
$('#count').val(result.item1.maxPlanes);
|
||||
$('#table-elements').html(result.item2);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
check();
|
||||
$('#shop').on('change', function () {
|
||||
check();
|
||||
});
|
||||
</script>
|
||||
}
|
25
AircraftPlant/AircraftPlantShopApp/Views/Shared/Error.cshtml
Normal file
25
AircraftPlant/AircraftPlantShopApp/Views/Shared/Error.cshtml
Normal file
@ -0,0 +1,25 @@
|
||||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - AircraftPlantShopApp</title>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="~/AircraftPlantShopApp.styles.css" asp-append-version="true" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Авиастроительный завод</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
|
||||
<ul class="navbar-nav flex-grow-1">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Магазины</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container">
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="border-top footer text-muted">
|
||||
<div class="container">
|
||||
© 2024 - Авиастроительный завод
|
||||
</div>
|
||||
</footer>
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,48 @@
|
||||
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
for details on configuring this project to bundle and minify static web assets. */
|
||||
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0077cc;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
button.accept-policy {
|
||||
font-size: 1rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
line-height: 60px;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
|
@ -0,0 +1,3 @@
|
||||
@using AircraftPlantShopApp
|
||||
@using AircraftPlantShopApp.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
12
AircraftPlant/AircraftPlantShopApp/appsettings.json
Normal file
12
AircraftPlant/AircraftPlantShopApp/appsettings.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
|
||||
"IPAddress": "http://localhost:5092",
|
||||
"Password": "password"
|
||||
}
|
18
AircraftPlant/AircraftPlantShopApp/wwwroot/css/site.css
Normal file
18
AircraftPlant/AircraftPlantShopApp/wwwroot/css/site.css
Normal file
@ -0,0 +1,18 @@
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
BIN
AircraftPlant/AircraftPlantShopApp/wwwroot/favicon.ico
Normal file
BIN
AircraftPlant/AircraftPlantShopApp/wwwroot/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
4
AircraftPlant/AircraftPlantShopApp/wwwroot/js/site.js
Normal file
4
AircraftPlant/AircraftPlantShopApp/wwwroot/js/site.js
Normal file
@ -0,0 +1,4 @@
|
||||
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2021 Twitter, Inc.
|
||||
Copyright (c) 2011-2021 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
4997
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
4997
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
vendored
Normal file
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
4996
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
vendored
Normal file
4996
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
vendored
Normal file
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
427
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
vendored
Normal file
427
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
vendored
Normal file
@ -0,0 +1,427 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
background-color: currentColor;
|
||||
border: 0;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
hr:not([size]) {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-bs-original-title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.2em;
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0d6efd;
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
color: #0a58ca;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
direction: ltr /* rtl:ignore */;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: #d63384;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-size: 0.875em;
|
||||
color: #fff;
|
||||
background-color: #212529;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: #6c757d;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
/* rtl:raw:
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
*/
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
8
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
vendored
Normal file
8
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
File diff suppressed because one or more lines are too long
424
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
vendored
Normal file
424
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
vendored
Normal file
@ -0,0 +1,424 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
background-color: currentColor;
|
||||
border: 0;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
hr:not([size]) {
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-bs-original-title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.2em;
|
||||
background-color: #fcf8e3;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0d6efd;
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
color: #0a58ca;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
direction: ltr ;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: #d63384;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.2rem 0.4rem;
|
||||
font-size: 0.875em;
|
||||
color: #fff;
|
||||
background-color: #212529;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: #6c757d;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
line-height: inherit;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */
|
File diff suppressed because one or more lines are too long
4866
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
vendored
Normal file
4866
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4857
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
vendored
Normal file
4857
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11221
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css
vendored
Normal file
11221
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
vendored
Normal file
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11197
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
vendored
Normal file
11197
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
vendored
Normal file
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
6780
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
vendored
Normal file
6780
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
vendored
Normal file
1
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
vendored
Normal file
7
AircraftPlant/AircraftPlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user