Compare commits
9 Commits
2ae13a6dfe
...
9853ba17da
Author | SHA1 | Date | |
---|---|---|---|
9853ba17da | |||
5204fafe4f | |||
31c0173dac | |||
6ee1a91f89 | |||
25cd2c9c8b | |||
66547a63e2 | |||
5ff187a72f | |||
3e8bbabeb1 | |||
757ced9b9e |
@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomobilePlantRestApi", "A
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomobilePlantClientApp", "AutomobilePlantClientApp\AutomobilePlantClientApp.csproj", "{E72BF12B-595D-42B8-B994-B9740A392B02}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomobilePlantShopApp", "AutomobilePlantShopApp\AutomobilePlantShopApp.csproj", "{0FC4B81C-8B2D-466F-AE81-8740C6B39817}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -63,6 +65,10 @@ Global
|
||||
{E72BF12B-595D-42B8-B994-B9740A392B02}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E72BF12B-595D-42B8-B994-B9740A392B02}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E72BF12B-595D-42B8-B994-B9740A392B02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0FC4B81C-8B2D-466F-AE81-8740C6B39817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0FC4B81C-8B2D-466F-AE81-8740C6B39817}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0FC4B81C-8B2D-466F-AE81-8740C6B39817}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0FC4B81C-8B2D-466F-AE81-8740C6B39817}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -4,6 +4,7 @@ using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.StoragesContracts;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Enums;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -17,12 +18,18 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IOrderStorage _orderStorage;
|
||||
private readonly IShopStorage _shopStorage;
|
||||
private readonly IShopLogic _shopLogic;
|
||||
private readonly ICarStorage _carStorage;
|
||||
static readonly object locker = new object();
|
||||
|
||||
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
|
||||
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IShopLogic shopLogic, ICarStorage carStorage, IShopStorage shopStorage)
|
||||
{
|
||||
_logger = logger;
|
||||
_orderStorage = orderStorage;
|
||||
_shopLogic = shopLogic;
|
||||
_carStorage = carStorage;
|
||||
_shopStorage = shopStorage;
|
||||
}
|
||||
|
||||
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
|
||||
@ -58,16 +65,80 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
public bool CreateOrder(OrderBindingModel model)
|
||||
{
|
||||
CheckModel(model);
|
||||
if (model.Status != OrderStatus.Неизвестен) return false;
|
||||
if (model.Status != OrderStatus.Неизвестен)
|
||||
return false;
|
||||
model.Status = OrderStatus.Принят;
|
||||
if (_orderStorage.Insert(model) == null)
|
||||
{
|
||||
model.Status = OrderStatus.Неизвестен;
|
||||
_logger.LogWarning("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckThenSupplyMany(ICarModel car, int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
_logger.LogWarning("Check then supply operation error. Car count < 0.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int freeSpace = 0;
|
||||
foreach (var shop in _shopStorage.GetFullList())
|
||||
{
|
||||
freeSpace += shop.MaxCountCars;
|
||||
foreach (var c in shop.ShopCars)
|
||||
{
|
||||
freeSpace -= c.Value.Item2;
|
||||
}
|
||||
}
|
||||
|
||||
if (freeSpace < count)
|
||||
{
|
||||
_logger.LogWarning("Check then supply operation error. There's no place for new cars in shops.");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var shop in _shopStorage.GetFullList())
|
||||
{
|
||||
freeSpace = shop.MaxCountCars;
|
||||
|
||||
foreach (var c in shop.ShopCars)
|
||||
freeSpace -= c.Value.Item2;
|
||||
|
||||
if (freeSpace <= 0)
|
||||
continue;
|
||||
|
||||
if (freeSpace >= count)
|
||||
{
|
||||
if (_shopLogic.SupplyCars(new ShopSearchModel() { Id = shop.Id }, car, count))
|
||||
count = 0;
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Supply error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (freeSpace < count)
|
||||
{
|
||||
if (_shopLogic.SupplyCars(new ShopSearchModel() { Id = shop.Id }, car, freeSpace))
|
||||
count -= freeSpace;
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Supply error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ChangeStatus(OrderBindingModel model, OrderStatus status)
|
||||
{
|
||||
CheckModel(model, false);
|
||||
@ -82,6 +153,23 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
_logger.LogWarning("Status change operation failed");
|
||||
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
|
||||
}
|
||||
|
||||
if (status == OrderStatus.Выдан)
|
||||
{
|
||||
var car = _carStorage.GetElement(new CarSearchModel() { Id = model.CarId });
|
||||
if (car == null)
|
||||
{
|
||||
_logger.LogWarning("Status change operation failed. Car not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckThenSupplyMany(car, model.Count))
|
||||
{
|
||||
_logger.LogWarning("Status change operation failed. Shop supply error.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (element.ImplementerId.HasValue)
|
||||
model.ImplementerId = element.ImplementerId;
|
||||
OrderStatus oldStatus = model.Status;
|
||||
|
@ -13,14 +13,16 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
private readonly IComponentStorage _componentStorage;
|
||||
private readonly ICarStorage _carStorage;
|
||||
private readonly IOrderStorage _orderStorage;
|
||||
private readonly IShopStorage _shopStorage;
|
||||
private readonly AbstractSaveToExcel _saveToExcel;
|
||||
private readonly AbstractSaveToWord _saveToWord;
|
||||
private readonly AbstractSaveToPdf _saveToPdf;
|
||||
public ReportLogic(ICarStorage carStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
|
||||
public ReportLogic(ICarStorage carStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, IShopStorage shopStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
|
||||
{
|
||||
_carStorage = carStorage;
|
||||
_componentStorage = componentStorage;
|
||||
_orderStorage = orderStorage;
|
||||
_shopStorage = shopStorage;
|
||||
_saveToExcel = saveToExcel;
|
||||
_saveToWord = saveToWord;
|
||||
_saveToPdf = saveToPdf;
|
||||
@ -113,5 +115,62 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
Orders = GetOrders(model)
|
||||
});
|
||||
}
|
||||
public void SaveShopsToWordFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToWord.CreateTableDoc(new WordInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Список магазинов",
|
||||
Shops = _shopStorage.GetFullList()
|
||||
});
|
||||
}
|
||||
public void SaveShopCarsToExcelFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToExcel.CreateShopReport(new ExcelInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Загруженность магазинов",
|
||||
ShopCars = GetShopCars()
|
||||
});
|
||||
}
|
||||
public List<ReportShopCarsViewModel> GetShopCars()
|
||||
{
|
||||
var shops = _shopStorage.GetFullList();
|
||||
var list = new List<ReportShopCarsViewModel>();
|
||||
foreach (var shop in shops)
|
||||
{
|
||||
var record = new ReportShopCarsViewModel
|
||||
{
|
||||
ShopName = shop.Name,
|
||||
Cars = new List<Tuple<string, int>>(),
|
||||
Count = 0
|
||||
};
|
||||
foreach (var carCount in shop.ShopCars.Values)
|
||||
{
|
||||
record.Cars.Add(new Tuple<string, int>(carCount.Item1.CarName, carCount.Item2));
|
||||
record.Count += carCount.Item2;
|
||||
}
|
||||
list.Add(record);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
public List<ReportDateOrdersViewModel> GetDateOrders()
|
||||
{
|
||||
return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportDateOrdersViewModel
|
||||
{
|
||||
DateCreate = x.Key,
|
||||
CountOrders = x.Count(),
|
||||
SumOrders = x.Sum(y => y.Sum)
|
||||
}).ToList();
|
||||
}
|
||||
public void SaveDateOrdersToPdfFile(ReportBindingModel model)
|
||||
{
|
||||
_saveToPdf.CreateReportDateDoc(new PdfInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Заказы по датам",
|
||||
DateOrders = GetDateOrders()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,206 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.BusinessLogicsContracts;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.StoragesContracts;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantBusinessLogic.BusinessLogics
|
||||
{
|
||||
public class ShopLogic : IShopLogic
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IShopStorage _shopStorage;
|
||||
|
||||
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
|
||||
{
|
||||
_logger = logger;
|
||||
_shopStorage = shopStorage;
|
||||
}
|
||||
|
||||
public ShopViewModel? ReadElement(ShopSearchModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
|
||||
_logger.LogInformation("ReadElement. Shop Name:{0}, ID:{1}", model.Name, model.Id);
|
||||
|
||||
var element = _shopStorage.GetElement(model);
|
||||
if (element == null)
|
||||
{
|
||||
_logger.LogWarning("ReadElement. element not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public List<ShopViewModel>? ReadList(ShopSearchModel? model)
|
||||
{
|
||||
_logger.LogInformation("ReadList. Shop Name:{0}, ID:{1} ", model?.Name, model?.Id);
|
||||
|
||||
var list = (model == null) ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(model);
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public bool SupplyCars(ShopSearchModel model, ICarModel car, int count)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
|
||||
if (car == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(car));
|
||||
}
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new ArgumentNullException("Count of cars in supply must be more than 0", nameof(count));
|
||||
}
|
||||
|
||||
var shopElement = _shopStorage.GetElement(model);
|
||||
if (shopElement == null)
|
||||
{
|
||||
_logger.LogWarning("Required shop element not found in storage");
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Shop element found. ID: {0}, Name: {1}", shopElement.Id, shopElement.Name);
|
||||
|
||||
int countCars = 0;
|
||||
foreach (var c in shopElement.ShopCars)
|
||||
countCars += c.Value.Item2;
|
||||
|
||||
if (count > shopElement.MaxCountCars - countCars)
|
||||
{
|
||||
_logger.LogWarning("Required shop will be overflowed");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shopElement.ShopCars.TryGetValue(car.Id, out var sameCar))
|
||||
{
|
||||
shopElement.ShopCars[car.Id] = (car, sameCar.Item2 + count);
|
||||
_logger.LogInformation("Same car found by supply. Added {0} of {1} in {2} shop", count, car.CarName, shopElement.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
shopElement.ShopCars[car.Id] = (car, count);
|
||||
_logger.LogInformation("New car added by supply. Added {0} of {1} in {2} shop", count, car.CarName, shopElement.Name);
|
||||
}
|
||||
|
||||
_shopStorage.Update(new()
|
||||
{
|
||||
Id = shopElement.Id,
|
||||
Name = shopElement.Name,
|
||||
Address = shopElement.Address,
|
||||
MaxCountCars = shopElement.MaxCountCars,
|
||||
OpeningDate = shopElement.OpeningDate,
|
||||
ShopCars = shopElement.ShopCars
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Create(ShopBindingModel model)
|
||||
{
|
||||
CheckModel(model);
|
||||
|
||||
if (_shopStorage.Insert(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Update(ShopBindingModel model)
|
||||
{
|
||||
CheckModel(model);
|
||||
|
||||
if (_shopStorage.Update(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Update operation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(ShopBindingModel model)
|
||||
{
|
||||
CheckModel(model, false);
|
||||
|
||||
if (_shopStorage.Delete(model) == null)
|
||||
{
|
||||
_logger.LogWarning("Delete operation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CheckModel(ShopBindingModel model, bool withParams = true)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
|
||||
if (!withParams)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
throw new ArgumentNullException("Нет названия магазина!", nameof(model.Name));
|
||||
}
|
||||
|
||||
if (model.MaxCountCars < 0)
|
||||
{
|
||||
throw new InvalidOperationException("Отрицательное максимальное количество авто!");
|
||||
}
|
||||
|
||||
_logger.LogInformation("Shop. Name: {0}, Address: {1}, ID: {2}", model.Name, model.Address, model.Id);
|
||||
|
||||
var element = _shopStorage.GetElement(new ShopSearchModel
|
||||
{
|
||||
Name = model.Name
|
||||
});
|
||||
|
||||
if (element != null && element.Id != model.Id)
|
||||
{
|
||||
throw new InvalidOperationException("Магазин с таким названием уже есть");
|
||||
}
|
||||
}
|
||||
|
||||
public bool SellCar(ICarModel car, int count)
|
||||
{
|
||||
return _shopStorage.SellCar(car, count);
|
||||
}
|
||||
}
|
||||
}
|
@ -71,6 +71,68 @@ namespace AutomobilePlantBusinessLogic.OfficePackage
|
||||
}
|
||||
SaveExcel(info);
|
||||
}
|
||||
public void CreateShopReport(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 pc in info.ShopCars)
|
||||
{
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = pc.ShopName,
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
rowIndex++;
|
||||
foreach (var (CarName, Count) in pc.Cars)
|
||||
{
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "B",
|
||||
RowIndex = rowIndex,
|
||||
Text = CarName,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
Text = Count.ToString(),
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
rowIndex++;
|
||||
}
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = "Итого",
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
InsertCellInWorksheet(new ExcelCellParameters
|
||||
{
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
Text = pc.Count.ToString(),
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
rowIndex++;
|
||||
}
|
||||
SaveExcel(info);
|
||||
}
|
||||
/// <summary>
|
||||
/// Создание excel-файла
|
||||
/// </summary>
|
||||
|
@ -44,6 +44,39 @@ namespace AutomobilePlantBusinessLogic.OfficePackage
|
||||
});
|
||||
SavePdf(info);
|
||||
}
|
||||
public void CreateReportDateDoc(PdfInfo info)
|
||||
{
|
||||
CreatePdf(info);
|
||||
CreateParagraph(new PdfParagraph
|
||||
{
|
||||
Text = info.Title,
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
CreateTable(new List<string> { "3cm", "3cm", "7cm" });
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { "Дата", "Количество", "Сумма" },
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
foreach (var order in info.DateOrders)
|
||||
{
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { order.DateCreate.ToShortDateString(), order.CountOrders.ToString(), order.SumOrders.ToString() },
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
}
|
||||
CreateParagraph(new PdfParagraph
|
||||
{
|
||||
Text = $"Итого: {info.DateOrders.Sum(x => x.SumOrders)}\t",
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
SavePdf(info);
|
||||
}
|
||||
/// <summary>
|
||||
/// Создание doc-файла
|
||||
/// </summary>
|
||||
|
@ -35,6 +35,27 @@ namespace AutomobilePlantBusinessLogic.OfficePackage
|
||||
}
|
||||
SaveWord(info);
|
||||
}
|
||||
public void CreateTableDoc(WordInfo wordInfo)
|
||||
{
|
||||
CreateWord(wordInfo);
|
||||
var list = new List<string>();
|
||||
foreach (var shop in wordInfo.Shops)
|
||||
{
|
||||
list.Add(shop.Name);
|
||||
list.Add(shop.Address);
|
||||
list.Add(shop.OpeningDate.ToString());
|
||||
}
|
||||
var wordTable = new WordTable
|
||||
{
|
||||
Headers = new List<string> {
|
||||
"Название",
|
||||
"Адрес",
|
||||
"Дата открытия"},
|
||||
Texts = list
|
||||
};
|
||||
CreateTable(wordTable);
|
||||
SaveWord(wordInfo);
|
||||
}
|
||||
/// <summary>
|
||||
/// Создание doc-файла
|
||||
/// </summary>
|
||||
@ -51,5 +72,10 @@ namespace AutomobilePlantBusinessLogic.OfficePackage
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract void SaveWord(WordInfo info);
|
||||
/// <summary>
|
||||
/// создание таблицы
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract void CreateTable(WordTable info);
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,10 @@ namespace AutomobilePlantBusinessLogic.OfficePackage.HelperModels
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
public List<ReportShopCarsViewModel> ShopCars
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ namespace AutomobilePlantBusinessLogic.OfficePackage.HelperModels
|
||||
public DateTime DateFrom { get; set; }
|
||||
public DateTime DateTo { get; set; }
|
||||
public List<ReportOrdersViewModel> Orders { get; set; } = new();
|
||||
public List<ReportDateOrdersViewModel> DateOrders { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ namespace AutomobilePlantBusinessLogic.OfficePackage.HelperModels
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public List<CarViewModel> Cars { get; set; } = new();
|
||||
public List<ShopViewModel> Shops { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
namespace AutomobilePlantBusinessLogic.OfficePackage.HelperModels
|
||||
{
|
||||
public class WordTable
|
||||
{
|
||||
public List<string> Headers { get; set; } = new();
|
||||
public List<string> Texts { get; set; } = new();
|
||||
}
|
||||
}
|
@ -120,5 +120,85 @@ namespace AutomobilePlantBusinessLogic.OfficePackage.Implements
|
||||
_wordDocument.MainDocumentPart!.Document.Save();
|
||||
_wordDocument.Close();
|
||||
}
|
||||
protected override void CreateTable(WordTable table)
|
||||
{
|
||||
if (_docBody == null || table == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Table tab = new Table();
|
||||
TableProperties props = new TableProperties(
|
||||
new TableBorders(
|
||||
new TopBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
},
|
||||
new BottomBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
},
|
||||
new LeftBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
},
|
||||
new RightBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
},
|
||||
new InsideHorizontalBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
},
|
||||
new InsideVerticalBorder
|
||||
{
|
||||
Val = new EnumValue<BorderValues>(BorderValues.Single),
|
||||
Size = 12
|
||||
}
|
||||
)
|
||||
);
|
||||
tab.AppendChild<TableProperties>(props);
|
||||
TableGrid tableGrid = new TableGrid();
|
||||
for (int i = 0; i < table.Headers.Count; i++)
|
||||
{
|
||||
tableGrid.AppendChild(new GridColumn());
|
||||
}
|
||||
tab.AppendChild(tableGrid);
|
||||
TableRow tableRow = new TableRow();
|
||||
foreach (var text in table.Headers)
|
||||
{
|
||||
tableRow.AppendChild(CreateTableCell(text));
|
||||
}
|
||||
tab.AppendChild(tableRow);
|
||||
int height = table.Texts.Count / table.Headers.Count;
|
||||
int width = table.Headers.Count;
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
tableRow = new TableRow();
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
var element = table.Texts[i * table.Headers.Count + j];
|
||||
tableRow.AppendChild(CreateTableCell(element));
|
||||
}
|
||||
tab.AppendChild(tableRow);
|
||||
}
|
||||
|
||||
_docBody.AppendChild(tab);
|
||||
|
||||
}
|
||||
private TableCell CreateTableCell(string element)
|
||||
{
|
||||
var tableParagraph = new Paragraph();
|
||||
var run = new Run();
|
||||
run.AppendChild(new Text { Text = element });
|
||||
tableParagraph.AppendChild(run);
|
||||
var tableCell = new TableCell();
|
||||
tableCell.AppendChild(tableParagraph);
|
||||
return tableCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantContracts.BindingModels
|
||||
{
|
||||
public class ShopBindingModel : IShopModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
public int MaxCountCars { get; set; }
|
||||
|
||||
public DateTime OpeningDate { get; set; }
|
||||
|
||||
public Dictionary<int, (ICarModel, int)> ShopCars
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
}
|
||||
}
|
@ -31,6 +31,31 @@ namespace AutomobilePlantContracts.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 SaveShopCarsToExcelFile(ReportBindingModel model);
|
||||
/// <summary>
|
||||
/// Получение списка магазинов
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<ReportShopCarsViewModel> GetShopCars();
|
||||
/// <summary>
|
||||
/// Получение списка заказов с группировкой по датам
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<ReportDateOrdersViewModel> GetDateOrders();
|
||||
/// <summary>
|
||||
/// Сохранение заказов с группировкой по датам в файл-Pdf
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveDateOrdersToPdfFile(ReportBindingModel model);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantContracts.BusinessLogicsContracts
|
||||
{
|
||||
public interface IShopLogic
|
||||
{
|
||||
ShopViewModel? ReadElement(ShopSearchModel model);
|
||||
List<ShopViewModel>? ReadList(ShopSearchModel? model);
|
||||
bool Create(ShopBindingModel model);
|
||||
bool Update(ShopBindingModel model);
|
||||
bool Delete(ShopBindingModel model);
|
||||
bool SupplyCars(ShopSearchModel model, ICarModel car, int count);
|
||||
bool SellCar(ICarModel car, int count);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantContracts.SearchModels
|
||||
{
|
||||
public class ShopSearchModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantContracts.StoragesContracts
|
||||
{
|
||||
public interface IShopStorage
|
||||
{
|
||||
ShopViewModel? GetElement(ShopSearchModel model);
|
||||
List<ShopViewModel> GetFullList();
|
||||
List<ShopViewModel> GetFilteredList(ShopSearchModel model);
|
||||
ShopViewModel? Insert(ShopBindingModel model);
|
||||
ShopViewModel? Update(ShopBindingModel model);
|
||||
ShopViewModel? Delete(ShopBindingModel model);
|
||||
bool SellCar(ICarModel model, int count);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace AutomobilePlantContracts.ViewModels
|
||||
{
|
||||
public class ReportDateOrdersViewModel
|
||||
{
|
||||
public DateTime DateCreate { get; set; }
|
||||
public int CountOrders { get; set; }
|
||||
public double SumOrders { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace AutomobilePlantContracts.ViewModels
|
||||
{
|
||||
public class ReportShopCarsViewModel
|
||||
{
|
||||
public string ShopName { get; set; } = string.Empty;
|
||||
public int Count { get; set; }
|
||||
public List<Tuple<string, int>> Cars { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantContracts.ViewModels
|
||||
{
|
||||
public class ShopViewModel : IShopModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Shop's name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Address")]
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Maximum cars' count in shop")]
|
||||
public int MaxCountCars { get; set; }
|
||||
|
||||
[DisplayName("Opening date")]
|
||||
public DateTime OpeningDate { get; set; }
|
||||
|
||||
public Dictionary<int, (ICarModel, int)> ShopCars { get; set; } = new();
|
||||
|
||||
public List<Tuple<string, int>>? CarAndCount { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantDataModels.Models
|
||||
{
|
||||
public interface IShopModel : IId
|
||||
{
|
||||
string Name { get; }
|
||||
string Address { get; }
|
||||
int MaxCountCars { get; }
|
||||
DateTime OpeningDate { get; }
|
||||
Dictionary<int, (ICarModel, int)> ShopCars { get; }
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@ namespace AutomobilePlantDatabaseImplement
|
||||
public virtual DbSet<Car> Cars { set; get; }
|
||||
public virtual DbSet<CarComponent> CarComponents { set; get; }
|
||||
public virtual DbSet<Order> Orders { set; get; }
|
||||
public virtual DbSet<Shop> Shops { set; get; }
|
||||
public virtual DbSet<ShopCar> ShopCars { set; get; }
|
||||
public virtual DbSet<Client> Clients { set; get; }
|
||||
public virtual DbSet<Implementer> Implementers { set; get; }
|
||||
}
|
||||
|
@ -0,0 +1,143 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.StoragesContracts;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDatabaseImplement.Models;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantDatabaseImplement.Implements
|
||||
{
|
||||
public class ShopStorage : IShopStorage
|
||||
{
|
||||
public ShopViewModel? GetElement(ShopSearchModel model)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
|
||||
{
|
||||
return new();
|
||||
}
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
return context.Shops.Include(x => x.Cars).ThenInclude(x => x.Car).FirstOrDefault(x =>
|
||||
(!string.IsNullOrEmpty(model.Name) && x.Name == model.Name) ||
|
||||
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
return new();
|
||||
}
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
return context.Shops.Include(x => x.Cars).ThenInclude(x => x.Car).Where(x => x.Name.Contains(model.Name)).ToList().Select(x => x.GetViewModel).ToList();
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFullList()
|
||||
{
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
return context.Shops.Include(x => x.Cars).ThenInclude(x => x.Car).ToList().Select(x => x.GetViewModel).ToList();
|
||||
}
|
||||
|
||||
public ShopViewModel? Insert(ShopBindingModel model)
|
||||
{
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var newShop = Shop.Create(context, model);
|
||||
if (newShop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (context.Shops.Any(x => x.Name == newShop.Name))
|
||||
{
|
||||
throw new Exception("Название магазина уже занято");
|
||||
}
|
||||
|
||||
context.Shops.Add(newShop);
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
return newShop.GetViewModel;
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public ShopViewModel? Update(ShopBindingModel model)
|
||||
{
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var shop = context.Shops.Include(x => x.Cars).FirstOrDefault(x => x.Id == model.Id);
|
||||
if (shop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
shop.Update(model);
|
||||
context.SaveChanges();
|
||||
if (model.ShopCars.Count > 0)
|
||||
{
|
||||
shop.UpdateCars(context, model);
|
||||
}
|
||||
transaction.Commit();
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public ShopViewModel? Delete(ShopBindingModel model)
|
||||
{
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
var shop = context.Shops.Include(x => x.Cars).FirstOrDefault(x => x.Id == model.Id);
|
||||
if (shop != null)
|
||||
{
|
||||
context.Shops.Remove(shop);
|
||||
context.SaveChanges();
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool SellCar(ICarModel model, int count)
|
||||
{
|
||||
using var context = new AutomobilePlantDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
|
||||
foreach (var shopCars in context.ShopCars.Where(x => x.CarId == model.Id))
|
||||
{
|
||||
var min = Math.Min(count, shopCars.Count);
|
||||
shopCars.Count -= min;
|
||||
count -= min;
|
||||
if (count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
context.SaveChanges();
|
||||
transaction.Commit();
|
||||
}
|
||||
else
|
||||
transaction.Rollback();
|
||||
|
||||
if (count > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
248
AutomobilePlant/AutomobilePlantDatabaseImplement/Migrations/20240310130521_HardMbINeedIt.Designer.cs
generated
Normal file
248
AutomobilePlant/AutomobilePlantDatabaseImplement/Migrations/20240310130521_HardMbINeedIt.Designer.cs
generated
Normal file
@ -0,0 +1,248 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using AutomobilePlantDatabaseImplement;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AutomobilePlantDatabaseImplement.Migrations
|
||||
{
|
||||
[DbContext(typeof(AutomobilePlantDatabase))]
|
||||
[Migration("20240310130521_HardMbINeedIt")]
|
||||
partial class HardMbINeedIt
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.16")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Car", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CarName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Cars");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.CarComponent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("CarId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ComponentId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CarId");
|
||||
|
||||
b.HasIndex("ComponentId");
|
||||
|
||||
b.ToTable("CarComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.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("AutomobilePlantDatabaseImplement.Models.Order", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("CarId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DateCreate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<DateTime?>("DateImplement")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<double>("Sum")
|
||||
.HasColumnType("float");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CarId");
|
||||
|
||||
b.ToTable("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.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<int>("MaxCountCars")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("OpeningDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Shops");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("CarId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ShopId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CarId");
|
||||
|
||||
b.HasIndex("ShopId");
|
||||
|
||||
b.ToTable("ShopCars");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.CarComponent", b =>
|
||||
{
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
|
||||
.WithMany("Components")
|
||||
.HasForeignKey("CarId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Component", "Component")
|
||||
.WithMany("ProductComponents")
|
||||
.HasForeignKey("ComponentId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Car");
|
||||
|
||||
b.Navigation("Component");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Order", b =>
|
||||
{
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
|
||||
.WithMany("Orders")
|
||||
.HasForeignKey("CarId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Car");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
|
||||
{
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
|
||||
.WithMany()
|
||||
.HasForeignKey("CarId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Shop", "Shop")
|
||||
.WithMany("Cars")
|
||||
.HasForeignKey("ShopId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Car");
|
||||
|
||||
b.Navigation("Shop");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Car", b =>
|
||||
{
|
||||
b.Navigation("Components");
|
||||
|
||||
b.Navigation("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Component", b =>
|
||||
{
|
||||
b.Navigation("ProductComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Navigation("Cars");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AutomobilePlantDatabaseImplement.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class HardMbINeedIt : 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"),
|
||||
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
OpeningDate = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
MaxCountCars = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Shops", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ShopCars",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
CarId = table.Column<int>(type: "int", nullable: false),
|
||||
ShopId = table.Column<int>(type: "int", nullable: false),
|
||||
Count = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ShopCars", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShopCars_Cars_CarId",
|
||||
column: x => x.CarId,
|
||||
principalTable: "Cars",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ShopCars_Shops_ShopId",
|
||||
column: x => x.ShopId,
|
||||
principalTable: "Shops",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShopCars_CarId",
|
||||
table: "ShopCars",
|
||||
column: "CarId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShopCars_ShopId",
|
||||
table: "ShopCars",
|
||||
column: "ShopId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ShopCars");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Shops");
|
||||
}
|
||||
}
|
||||
}
|
@ -183,6 +183,59 @@ namespace AutomobilePlantDatabaseImplement.Migrations
|
||||
b.ToTable("Orders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.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<int>("MaxCountCars")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTime>("OpeningDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Shops");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("CarId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ShopId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CarId");
|
||||
|
||||
b.HasIndex("ShopId");
|
||||
|
||||
b.ToTable("ShopCars");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.CarComponent", b =>
|
||||
{
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
|
||||
@ -227,6 +280,25 @@ namespace AutomobilePlantDatabaseImplement.Migrations
|
||||
b.Navigation("Implementer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
|
||||
{
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
|
||||
.WithMany()
|
||||
.HasForeignKey("CarId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AutomobilePlantDatabaseImplement.Models.Shop", "Shop")
|
||||
.WithMany("Cars")
|
||||
.HasForeignKey("ShopId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Car");
|
||||
|
||||
b.Navigation("Shop");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Car", b =>
|
||||
{
|
||||
b.Navigation("Components");
|
||||
@ -244,6 +316,11 @@ namespace AutomobilePlantDatabaseImplement.Migrations
|
||||
b.Navigation("CarComponents");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
|
||||
{
|
||||
b.Navigation("Cars");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Implementer", b =>
|
||||
{
|
||||
b.Navigation("Orders");
|
||||
|
114
AutomobilePlant/AutomobilePlantDatabaseImplement/Models/Shop.cs
Normal file
114
AutomobilePlant/AutomobilePlantDatabaseImplement/Models/Shop.cs
Normal file
@ -0,0 +1,114 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantDatabaseImplement.Models
|
||||
{
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string Address { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public DateTime OpeningDate { get; set; }
|
||||
|
||||
[ForeignKey("ShopId")]
|
||||
public List<ShopCar> Cars { get; set; } = new();
|
||||
|
||||
private Dictionary<int, (ICarModel, int)>? _shopCars = null;
|
||||
|
||||
[NotMapped]
|
||||
public Dictionary<int, (ICarModel, int)> ShopCars
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_shopCars == null)
|
||||
{
|
||||
_shopCars = Cars.ToDictionary(recPC => recPC.CarId, recPC => (recPC.Car as ICarModel, recPC.Count));
|
||||
}
|
||||
return _shopCars;
|
||||
}
|
||||
}
|
||||
|
||||
[Required]
|
||||
public int MaxCountCars { get; set; }
|
||||
|
||||
public static Shop Create(AutomobilePlantDatabase context, ShopBindingModel model)
|
||||
{
|
||||
return new Shop()
|
||||
{
|
||||
Id = model.Id,
|
||||
Name = model.Name,
|
||||
Address = model.Address,
|
||||
OpeningDate = model.OpeningDate,
|
||||
Cars = model.ShopCars.Select(x => new ShopCar
|
||||
{
|
||||
Car = context.Cars.First(y => y.Id == x.Key),
|
||||
Count = x.Value.Item2
|
||||
}).ToList(),
|
||||
MaxCountCars = model.MaxCountCars
|
||||
};
|
||||
}
|
||||
|
||||
public void Update(ShopBindingModel model)
|
||||
{
|
||||
Name = model.Name;
|
||||
Address = model.Address;
|
||||
OpeningDate = model.OpeningDate;
|
||||
MaxCountCars = model.MaxCountCars;
|
||||
}
|
||||
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
Name = Name,
|
||||
Address = Address,
|
||||
OpeningDate = OpeningDate,
|
||||
ShopCars = ShopCars,
|
||||
MaxCountCars = MaxCountCars
|
||||
};
|
||||
|
||||
public void UpdateCars(AutomobilePlantDatabase context, ShopBindingModel model)
|
||||
{
|
||||
var ShopCars = context.ShopCars.Where(rec => rec.ShopId == model.Id).ToList();
|
||||
if (ShopCars != null && ShopCars.Count > 0)
|
||||
{
|
||||
// удалили те, которых нет в модели
|
||||
context.ShopCars.RemoveRange(ShopCars.Where(rec => !model.ShopCars.ContainsKey(rec.CarId)));
|
||||
context.SaveChanges();
|
||||
ShopCars = context.ShopCars.Where(rec => rec.ShopId == model.Id).ToList();
|
||||
// обновили количество у существующих записей
|
||||
foreach (var updateCar in ShopCars)
|
||||
{
|
||||
updateCar.Count = model.ShopCars[updateCar.CarId].Item2;
|
||||
model.ShopCars.Remove(updateCar.CarId);
|
||||
}
|
||||
context.SaveChanges();
|
||||
}
|
||||
var shop = context.Shops.First(x => x.Id == Id);
|
||||
foreach (var elem in model.ShopCars)
|
||||
{
|
||||
context.ShopCars.Add(new ShopCar
|
||||
{
|
||||
Shop = shop,
|
||||
Car = context.Cars.First(x => x.Id == elem.Key),
|
||||
Count = elem.Value.Item2
|
||||
});
|
||||
context.SaveChanges();
|
||||
}
|
||||
_shopCars = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AutomobilePlantDatabaseImplement.Models
|
||||
{
|
||||
public class ShopCar
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int CarId { get; set; }
|
||||
|
||||
[Required]
|
||||
public int ShopId { get; set; }
|
||||
|
||||
[Required]
|
||||
public int Count { get; set; }
|
||||
|
||||
public virtual Shop Shop { get; set; } = new();
|
||||
|
||||
public virtual Car Car { get; set; } = new();
|
||||
}
|
||||
}
|
@ -14,11 +14,13 @@ namespace AutomobilePlantFileImplement
|
||||
private readonly string ComponentFileName = "Component.xml";
|
||||
private readonly string OrderFileName = "Order.xml";
|
||||
private readonly string CarFileName = "Car.xml";
|
||||
private readonly string ShopFileName = "Shop.xml";
|
||||
private readonly string ClientFileName = "Client.xml";
|
||||
private readonly string ImplementerFileName = "Implementer.xml";
|
||||
public List<Component> Components { get; private set; }
|
||||
public List<Order> Orders { get; private set; }
|
||||
public List<Car> Cars { get; private set; }
|
||||
public List<Shop> Shops { get; private set; }
|
||||
public List<Client> Clients { get; private set; }
|
||||
public List<Implementer> Implementers { get; private set; }
|
||||
public static DataFileSingleton GetInstance()
|
||||
@ -32,6 +34,7 @@ namespace AutomobilePlantFileImplement
|
||||
public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
|
||||
public void SaveCars() => SaveData(Cars, CarFileName, "Cars", x => x.GetXElement);
|
||||
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
|
||||
public void SaveShops() => SaveData(Shops, ShopFileName, "Shops", x => x.GetXElement);
|
||||
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
|
||||
public void SaveImplementers() => SaveData(Orders, ImplementerFileName, "Implementers", x => x.GetXElement);
|
||||
private DataFileSingleton()
|
||||
@ -39,6 +42,7 @@ namespace AutomobilePlantFileImplement
|
||||
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
|
||||
Cars = LoadData(CarFileName, "Car", x => Car.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, "Impleneter", x => Implementer.Create(x)!)!;
|
||||
}
|
||||
|
@ -0,0 +1,137 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.StoragesContracts;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using AutomobilePlantFileImplement.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantFileImplement.Implements
|
||||
{
|
||||
public class ShopStorage : IShopStorage
|
||||
{
|
||||
private readonly DataFileSingleton source;
|
||||
public ShopStorage()
|
||||
{
|
||||
source = DataFileSingleton.GetInstance();
|
||||
}
|
||||
public ShopViewModel? GetElement(ShopSearchModel model)
|
||||
{
|
||||
if (!model.Id.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return source.Shops.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
return new();
|
||||
}
|
||||
return source.Shops
|
||||
.Select(x => x.GetViewModel)
|
||||
.Where(x => x.Name.Contains(model.Name ?? string.Empty))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFullList()
|
||||
{
|
||||
return source.Shops.Select(shop => shop.GetViewModel).ToList();
|
||||
}
|
||||
|
||||
public ShopViewModel? Insert(ShopBindingModel model)
|
||||
{
|
||||
model.Id = source.Shops.Count > 0 ? source.Shops.Max(x => x.Id) + 1 : 1;
|
||||
var newShop = Shop.Create(model);
|
||||
if (newShop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
source.Shops.Add(newShop);
|
||||
source.SaveShops();
|
||||
return newShop.GetViewModel;
|
||||
}
|
||||
|
||||
public ShopViewModel? Update(ShopBindingModel model)
|
||||
{
|
||||
var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id);
|
||||
if (shop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
shop.Update(model);
|
||||
source.SaveShops();
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
public ShopViewModel? Delete(ShopBindingModel model)
|
||||
{
|
||||
var shop = source.Shops.FirstOrDefault(x => x.Id == model.Id);
|
||||
if (shop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
source.Shops.Remove(shop);
|
||||
source.SaveShops();
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
|
||||
public bool SellCar(ICarModel model, int count)
|
||||
{
|
||||
var car = source.Cars.FirstOrDefault(x => x.Id == model.Id);
|
||||
|
||||
if (car == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var shopCars = source.Shops.SelectMany(shop => shop.ShopCars.Where(c => c.Value.Item1.Id == car.Id));
|
||||
|
||||
int countStore = 0;
|
||||
|
||||
foreach (var it in shopCars)
|
||||
countStore += it.Value.Item2;
|
||||
|
||||
if (count > countStore)
|
||||
return false;
|
||||
|
||||
foreach (var shop in source.Shops)
|
||||
{
|
||||
var cars = shop.ShopCars;
|
||||
|
||||
foreach (var c in cars.Where(x => x.Value.Item1.Id == car.Id))
|
||||
{
|
||||
int min = Math.Min(c.Value.Item2, count);
|
||||
cars[c.Value.Item1.Id] = (c.Value.Item1, c.Value.Item2 - min);
|
||||
count -= min;
|
||||
|
||||
if (count <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
shop.Update(new ShopBindingModel
|
||||
{
|
||||
Id = shop.Id,
|
||||
Name = shop.Name,
|
||||
Address = shop.Address,
|
||||
MaxCountCars = shop.MaxCountCars,
|
||||
OpeningDate = shop.OpeningDate,
|
||||
ShopCars = cars
|
||||
});
|
||||
|
||||
source.SaveShops();
|
||||
|
||||
if (count <= 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
116
AutomobilePlant/AutomobilePlantFileImplement/Models/Shop.cs
Normal file
116
AutomobilePlant/AutomobilePlantFileImplement/Models/Shop.cs
Normal file
@ -0,0 +1,116 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace AutomobilePlantFileImplement.Models
|
||||
{
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
public int Id { get; private set; }
|
||||
public string Name { get; private set; } = string.Empty;
|
||||
public string Address { get; private set; } = string.Empty;
|
||||
public int MaxCountCars { get; private set; }
|
||||
public DateTime OpeningDate { get; private set; }
|
||||
public Dictionary<int, int> Cars { get; private set; } = new();
|
||||
private Dictionary<int, (ICarModel, int)>? _shopCars = null;
|
||||
|
||||
public Dictionary<int, (ICarModel, int)> ShopCars
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_shopCars == null)
|
||||
{
|
||||
var source = DataFileSingleton.GetInstance();
|
||||
_shopCars = Cars.ToDictionary(
|
||||
x => x.Key,
|
||||
y => ((source.Cars.FirstOrDefault(z => z.Id == y.Key) as ICarModel)!, y.Value)
|
||||
);
|
||||
}
|
||||
return _shopCars;
|
||||
}
|
||||
}
|
||||
|
||||
public static Shop? Create(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Shop()
|
||||
{
|
||||
Id = model.Id,
|
||||
Name = model.Name,
|
||||
Address = model.Address,
|
||||
MaxCountCars = model.MaxCountCars,
|
||||
OpeningDate = model.OpeningDate,
|
||||
Cars = model.ShopCars.ToDictionary(x => x.Key, x => x.Value.Item2)
|
||||
};
|
||||
}
|
||||
|
||||
public static Shop? Create(XElement element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new Shop()
|
||||
{
|
||||
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
|
||||
Name = element.Element("Name")!.Value,
|
||||
Address = element.Element("Address")!.Value,
|
||||
MaxCountCars = Convert.ToInt32(element.Element("MaxCountCars")!.Value),
|
||||
OpeningDate = Convert.ToDateTime(element.Element("OpeningDate")!.Value),
|
||||
Cars = element.Element("ShopCars")!.Elements("ShopCar").ToDictionary(
|
||||
x => Convert.ToInt32(x.Element("Key")?.Value),
|
||||
x => Convert.ToInt32(x.Element("Value")?.Value)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void Update(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Name = model.Name;
|
||||
Address = model.Address;
|
||||
MaxCountCars = model.MaxCountCars;
|
||||
OpeningDate = model.OpeningDate;
|
||||
if (model.ShopCars.Count > 0)
|
||||
{
|
||||
Cars = model.ShopCars.ToDictionary(x => x.Key, x => x.Value.Item2);
|
||||
_shopCars = null;
|
||||
}
|
||||
}
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
Name = Name,
|
||||
Address = Address,
|
||||
MaxCountCars = MaxCountCars,
|
||||
OpeningDate = OpeningDate,
|
||||
ShopCars = ShopCars,
|
||||
};
|
||||
|
||||
public XElement GetXElement => new(
|
||||
"Shop",
|
||||
new XAttribute("Id", Id),
|
||||
new XElement("Name", Name),
|
||||
new XElement("Address", Address),
|
||||
new XElement("MaxCountCars", MaxCountCars),
|
||||
new XElement("OpeningDate", OpeningDate.ToString()),
|
||||
new XElement("ShopCars", Cars.Select(x =>
|
||||
new XElement("ShopCar",
|
||||
new XElement("Key", x.Key),
|
||||
new XElement("Value", x.Value)))
|
||||
.ToArray()));
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace AutomobilePlantListImplement
|
||||
public List<Component> Components { get; set; }
|
||||
public List<Order> Orders { get; set; }
|
||||
public List<Car> Cars { get; set; }
|
||||
public List<Shop> Shops { get; set; }
|
||||
public List<Client> Clients { get; set; }
|
||||
public List<Implementer> Implementers { get; set; }
|
||||
private DataListSingleton()
|
||||
@ -20,6 +21,7 @@ namespace AutomobilePlantListImplement
|
||||
Components = new List<Component>();
|
||||
Orders = new List<Order>();
|
||||
Cars = new List<Car>();
|
||||
Shops = new List<Shop>();
|
||||
Clients = new List<Client>();
|
||||
Implementers = new List<Implementer>();
|
||||
}
|
||||
|
@ -0,0 +1,131 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.StoragesContracts;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using AutomobilePlantListImplement.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantListImplement.Implements
|
||||
{
|
||||
public class ShopStorage : IShopStorage
|
||||
{
|
||||
public bool SellCar(ICarModel car, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private readonly DataListSingleton _source;
|
||||
|
||||
public ShopStorage()
|
||||
{
|
||||
_source = DataListSingleton.GetInstance();
|
||||
}
|
||||
|
||||
public ShopViewModel? GetElement(ShopSearchModel model)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
if ((!string.IsNullOrEmpty(model.Name) && shop.Name == model.Name) || (model.Id.HasValue && shop.Id == model.Id))
|
||||
{
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
|
||||
{
|
||||
var result = new List<ShopViewModel>();
|
||||
|
||||
if (string.IsNullOrEmpty(model.Name))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
if (shop.Name.Contains(model.Name))
|
||||
{
|
||||
result.Add(shop.GetViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<ShopViewModel> GetFullList()
|
||||
{
|
||||
var result = new List<ShopViewModel>();
|
||||
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
result.Add(shop.GetViewModel);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ShopViewModel? Insert(ShopBindingModel model)
|
||||
{
|
||||
model.Id = 1;
|
||||
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
if (model.Id <= shop.Id)
|
||||
{
|
||||
model.Id = shop.Id + 1;
|
||||
}
|
||||
}
|
||||
|
||||
var newShop = Shop.Create(model);
|
||||
|
||||
if (newShop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_source.Shops.Add(newShop);
|
||||
|
||||
return newShop.GetViewModel;
|
||||
}
|
||||
|
||||
public ShopViewModel? Update(ShopBindingModel model)
|
||||
{
|
||||
foreach (var shop in _source.Shops)
|
||||
{
|
||||
if (shop.Id == model.Id)
|
||||
{
|
||||
shop.Update(model);
|
||||
return shop.GetViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ShopViewModel? Delete(ShopBindingModel model)
|
||||
{
|
||||
for (int i = 0; i < _source.Shops.Count; ++i)
|
||||
{
|
||||
if (_source.Shops[i].Id == model.Id)
|
||||
{
|
||||
var element = _source.Shops[i];
|
||||
_source.Shops.RemoveAt(i);
|
||||
return element.GetViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
60
AutomobilePlant/AutomobilePlantListImplement/Models/Shop.cs
Normal file
60
AutomobilePlant/AutomobilePlantListImplement/Models/Shop.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using AutomobilePlantDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutomobilePlantListImplement.Models
|
||||
{
|
||||
public class Shop : IShopModel
|
||||
{
|
||||
public int Id { get; private set; }
|
||||
public string Name { get; private set; } = string.Empty;
|
||||
public string Address { get; private set; } = string.Empty;
|
||||
public int MaxCountCars { get; private set; }
|
||||
public DateTime OpeningDate { get; private set; }
|
||||
public Dictionary<int, (ICarModel, int)> ShopCars { get; private set; } = new();
|
||||
|
||||
public static Shop? Create(ShopBindingModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Shop()
|
||||
{
|
||||
Id = model.Id,
|
||||
Name = model.Name,
|
||||
Address = model.Address,
|
||||
OpeningDate = model.OpeningDate,
|
||||
ShopCars = new()
|
||||
};
|
||||
}
|
||||
|
||||
public void Update(ShopBindingModel? model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Name = model.Name;
|
||||
Address = model.Address;
|
||||
OpeningDate = model.OpeningDate;
|
||||
ShopCars = model.ShopCars;
|
||||
}
|
||||
|
||||
public ShopViewModel GetViewModel => new()
|
||||
{
|
||||
Id = Id,
|
||||
Name = Name,
|
||||
Address = Address,
|
||||
OpeningDate = OpeningDate,
|
||||
ShopCars = ShopCars
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.BusinessLogicsContracts;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AutomobilePlantRestApi.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class ShopController : Controller
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IShopLogic _shop;
|
||||
|
||||
public ShopController(ILogger<ShopController> logger, IShopLogic shopLogic)
|
||||
{
|
||||
_logger = logger;
|
||||
_shop = shopLogic;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public List<ShopViewModel>? GetShopList()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ShopViewModel> shops = _shop.ReadList(null);
|
||||
for (int i = 0; i < shops.Count; i++)
|
||||
shops[i].CarAndCount = shops[i].ShopCars.Values.ToList().Select( x => (x.Item1.CarName, x.Item2).ToTuple() ).ToList();
|
||||
return shops;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения списка магазинов");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ShopViewModel? GetShop(int shopId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _shop.ReadElement(new ShopSearchModel
|
||||
{
|
||||
Id = shopId
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения магазина по id={Id}", shopId);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void CreateShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shop.Create(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка создания магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void UpdateShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shop.Update(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void DeleteShop(ShopBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shop.Delete(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка удаления магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
[HttpPost]
|
||||
public void SupplyCarsToShop(Tuple<ShopSearchModel, CarBindingModel, int> shop_car_k)
|
||||
{
|
||||
try
|
||||
{
|
||||
_shop.SupplyCars(shop_car_k.Item1, shop_car_k.Item2, shop_car_k.Item3);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка пополнения магазина");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,10 +12,12 @@ builder.Logging.AddLog4Net("log4net.config");
|
||||
builder.Services.AddTransient<IClientStorage, ClientStorage>();
|
||||
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
|
||||
builder.Services.AddTransient<ICarStorage, CarStorage>();
|
||||
builder.Services.AddTransient<IShopStorage, ShopStorage>();
|
||||
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
|
||||
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
|
||||
builder.Services.AddTransient<IClientLogic, ClientLogic>();
|
||||
builder.Services.AddTransient<ICarLogic, CarLogic>();
|
||||
builder.Services.AddTransient<IShopLogic, ShopLogic>();
|
||||
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
56
AutomobilePlant/AutomobilePlantShopApp/APIClient.cs
Normal file
56
AutomobilePlant/AutomobilePlantShopApp/APIClient.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace AutomobilePlantShopApp
|
||||
{
|
||||
public static class APIClient
|
||||
{
|
||||
private static readonly HttpClient _client = new();
|
||||
public static bool isAuth { get; private set; } = false;
|
||||
public static string ConfigPassword { get; private set; } = string.Empty;
|
||||
|
||||
public static bool Login(string password)
|
||||
{
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
throw new Exception("Enter the password");
|
||||
}
|
||||
return isAuth = password.Equals(ConfigPassword);
|
||||
}
|
||||
|
||||
public static void Connect(IConfiguration configuration)
|
||||
{
|
||||
ConfigPassword = configuration["Password"];
|
||||
_client.BaseAddress = new Uri(configuration["IPAddress"]);
|
||||
_client.DefaultRequestHeaders.Accept.Clear();
|
||||
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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="..\AutomobilePlantContracts\AutomobilePlantContracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,151 @@
|
||||
using AutomobilePlantShopApp.Models;
|
||||
using AutomobilePlantContracts.BindingModels;
|
||||
using AutomobilePlantContracts.SearchModels;
|
||||
using AutomobilePlantContracts.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AutomobilePlantShopApp.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
|
||||
public HomeController(ILogger<HomeController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View(APIClient.GetRequest<List<ShopViewModel>>($"api/shop/getshoplist"));
|
||||
}
|
||||
|
||||
public IActionResult Privacy()
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Enter()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Enter(string password)
|
||||
{
|
||||
if (!APIClient.Login(password))
|
||||
{
|
||||
throw new Exception("Wrong password");
|
||||
}
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Create(string name, string address, DateTime openingDate, int count)
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
throw new Exception("How did you get here? Only authorized persons can enter here");
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new Exception("The maximum number of items in a store must be greater than zero");
|
||||
}
|
||||
APIClient.PostRequest("api/shop/createshop", new ShopBindingModel
|
||||
{
|
||||
Name = name,
|
||||
MaxCountCars = count,
|
||||
Address = address,
|
||||
OpeningDate = openingDate
|
||||
});
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Delete()
|
||||
{
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshoplist");
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Delete(int shop)
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
throw new Exception("Only authorized persons can enter here");
|
||||
}
|
||||
|
||||
APIClient.PostRequest($"api/shop/deleteshop", new ShopBindingModel { Id = shop });
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Update()
|
||||
{
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshoplist");
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Update(int shop, string name, string address, DateTime openingDate, int count)
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
throw new Exception("Only authorized persons can enter here");
|
||||
}
|
||||
|
||||
APIClient.PostRequest($"api/shop/updateshop", new ShopBindingModel
|
||||
{
|
||||
Id = shop,
|
||||
Name = name,
|
||||
Address = address,
|
||||
OpeningDate = openingDate,
|
||||
MaxCountCars = count
|
||||
}
|
||||
);
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
public IActionResult Supply()
|
||||
{
|
||||
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshoplist");
|
||||
ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>("api/main/getcarlist");
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Supply(int shopId, int carId, int count)
|
||||
{
|
||||
if (!APIClient.isAuth)
|
||||
{
|
||||
throw new Exception("Only authorized persons can enter here");
|
||||
}
|
||||
|
||||
APIClient.PostRequest($"api/shop/supplycarstoshop", (new ShopSearchModel { Id = shopId }, new CarBindingModel { Id = carId }, count));
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[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 AutomobilePlantShopApp.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
31
AutomobilePlant/AutomobilePlantShopApp/Program.cs
Normal file
31
AutomobilePlant/AutomobilePlantShopApp/Program.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using AutomobilePlantShopApp;
|
||||
|
||||
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:5813",
|
||||
"sslPort": 44307
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"AutomobilePlantShopApp": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7137;http://localhost:5047",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4 mb-5">Create shop</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Name:</div>
|
||||
<div class="col-8"><input type="text" name="name" id="name" /></div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Opening date:</div>
|
||||
<div class="col-8">
|
||||
<input type="date" id="openingDate" name="openingDate" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Address:</div>
|
||||
<div class="col-8"><input type="text" id="address" name="address" /></div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Maximum number of cars:</div>
|
||||
<div class="col-8"><input type="number" id="count" name="count" /></div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-8">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input type="submit" value="Create" class="btn btn-success" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,17 @@
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Delete shop</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Name:</div>
|
||||
<div class="col-8">
|
||||
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops,"Id", "Name"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,16 @@
|
||||
@{
|
||||
ViewData["Title"] = "Enter";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Enter in application</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Password:</div>
|
||||
<div class="col-8"><input type="password" name="password" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Enter" class="btn btnprimary" /></div>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,67 @@
|
||||
@using AutomobilePlantContracts.ViewModels
|
||||
@model List<ShopViewModel>
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Shops</h1>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model == null)
|
||||
{
|
||||
<h3 class="display-4">Log in!</h3>
|
||||
return;
|
||||
}
|
||||
<p>
|
||||
<a class="text-decoration-none me-3 text-black h5" asp-action="Create">Create shop</a>
|
||||
<a class="text-decoration-none me-3 text-black h5" asp-action="Update">Update shop</a>
|
||||
<a class="text-decoration-none me-3 text-black h5" asp-action="Supply">Supply shop</a>
|
||||
<a class="text-decoration-none text-black h5" asp-action="Delete">Delete shop</a>
|
||||
</p>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Number
|
||||
</th>
|
||||
<th>
|
||||
Name
|
||||
</th>
|
||||
<th>
|
||||
Address
|
||||
</th>
|
||||
<th>
|
||||
Opening date
|
||||
</th>
|
||||
<th>
|
||||
Maximum number of cars
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var shop in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => shop.Id)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => shop.Name)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => shop.Address)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => shop.OpeningDate)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => shop.MaxCountCars)
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
@ -0,0 +1,6 @@
|
||||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
|
||||
<p>Use this page to detail your site's privacy policy.</p>
|
@ -0,0 +1,29 @@
|
||||
@{
|
||||
ViewData["Title"] = "Supply";
|
||||
}
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="display-4">Supply shop</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Shop:</div>
|
||||
<div class="col-8 ">
|
||||
<select id="shopId" name="shopId" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops,"Id", "Name"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Car:</div>
|
||||
<div class="col-8">
|
||||
<select id="carId" name="carId" class="form-control" asp-items="@(new SelectList(@ViewBag.Cars,"Id", "CarName"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col-4">Count:</div>
|
||||
<div class="col-8">
|
||||
<input type="text" name="count" id="count" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input type="submit" value="Supply" class="btn btn-success" />
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,78 @@
|
||||
@{
|
||||
ViewData["Title"] = "Update";
|
||||
}
|
||||
<div class="text-center">
|
||||
<h2 class="display-4 mb-5">Update shop</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Shop:</div>
|
||||
<div class="col-8">
|
||||
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops,"Id", "Name"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Name:</div>
|
||||
<div class="col-8"><input type="text" id="name" name="name" /></div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Address:</div>
|
||||
<div class="col-8"><input type="text" id="address" name="address" /></div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Opening date:</div>
|
||||
<div class="col-8">
|
||||
<input type="datetime-local" id="openingDate" name="openingDate" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Maximum number of cars:</div>
|
||||
<div class="col-8"><input type="number" id="maxCountCars" name="maxCountCars" /></div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">Car in the shop:</div>
|
||||
<div class="col-8">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Car</th>
|
||||
<th>Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="carTable">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center ">
|
||||
<input type="submit" value="Update" class="btn btn-success ps-5 pe-5" />
|
||||
</div>
|
||||
</form>
|
||||
<<script>
|
||||
$('#shop').on('change', function () {
|
||||
getData();
|
||||
});
|
||||
|
||||
function getData() {
|
||||
var shopId = $('#shop').val();
|
||||
var shopData = @Html.Raw(Json.Serialize(ViewBag.Shops));
|
||||
var selectedShop = shopData.find(function (shop) {
|
||||
return shop.id == shopId;
|
||||
});
|
||||
|
||||
if (selectedShop) {
|
||||
$("#name").val(selectedShop.name);
|
||||
$("#openingDate").val(new Date(selectedShop.openingDate).toISOString().substring(0, 16));
|
||||
$("#address").val(selectedShop.address);
|
||||
$("#maxCountCars").val(selectedShop.maxCountCars);
|
||||
fillTable(selectedShop.carAndCount);
|
||||
}
|
||||
}
|
||||
|
||||
function fillTable(shopCars) {
|
||||
$("#carTable").empty();
|
||||
|
||||
for (var car in shopCars)
|
||||
$("#carTable").append('<tr><td>' + shopCars[car].item1 + '</td><td>' + shopCars[car].item2 + '</td></tr>');
|
||||
}
|
||||
</script>
|
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - ShopApp</title>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
<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>
|
||||
</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">AutomobilePlantShopApp</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 justify-content-between">
|
||||
<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">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</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 - AutomobilePlantShopApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
|
||||
</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,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,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - AutomobilePlantShopApp</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="~/AutomobilePlantShopApp.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">AutomobilePlantShopApp</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 justify-content-between">
|
||||
<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">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</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 - AutomobilePlantShopApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
|
||||
</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 AutomobilePlantShopApp
|
||||
@using AutomobilePlantShopApp.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
11
AutomobilePlant/AutomobilePlantShopApp/appsettings.json
Normal file
11
AutomobilePlant/AutomobilePlantShopApp/appsettings.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"IPAddress": "http://localhost:5275/",
|
||||
"Password": "password"
|
||||
}
|
18
AutomobilePlant/AutomobilePlantShopApp/wwwroot/css/site.css
Normal file
18
AutomobilePlant/AutomobilePlantShopApp/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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/favicon.ico
Normal file
BIN
AutomobilePlant/AutomobilePlantShopApp/wwwroot/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
4997
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
vendored
Normal file
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.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
4996
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
vendored
Normal file
4996
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.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
427
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
vendored
Normal file
427
AutomobilePlant/AutomobilePlantShopApp/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 */
|
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-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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
vendored
Normal file
424
AutomobilePlant/AutomobilePlantShopApp/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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
vendored
Normal file
4866
AutomobilePlant/AutomobilePlantShopApp/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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
vendored
Normal file
4857
AutomobilePlant/AutomobilePlantShopApp/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
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css
vendored
Normal file
11221
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
vendored
Normal file
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11197
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
vendored
Normal file
11197
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
vendored
Normal file
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/css/bootstrap.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
6780
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
vendored
Normal file
6780
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
vendored
Normal file
7
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
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
4977
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
vendored
Normal file
4977
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
vendored
Normal file
1
AutomobilePlant/AutomobilePlantShopApp/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
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