Compare commits

..

5 Commits

Author SHA1 Message Date
a445a2307d Делаю сохранение в pdf 2024-05-28 14:34:16 +04:00
6e1690d28c Слияние 2024-05-26 19:36:13 +04:00
80322e3819 Merge branch 'dev-guarantor' 2024-05-02 00:13:39 +04:00
525d9fe140 Add guarantor ClientApp 2024-05-02 00:13:15 +04:00
16837f9d4d Report logic 2024-05-02 00:10:15 +04:00
129 changed files with 76695 additions and 82 deletions

View File

@ -18,6 +18,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComputerShopImplementerApp"
{BBCF398B-D800-4D8D-99E8-F7ED2CC14A65} = {BBCF398B-D800-4D8D-99E8-F7ED2CC14A65}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComputerShopGuarantorApp", "ComputerShopGuarantorApp\ComputerShopGuarantorApp.csproj", "{4E08B0E4-12D4-42BB-A794-995A134A23A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -48,6 +50,10 @@ Global
{0E13C365-F2CC-4A32-BDD0-52E2DB324734}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E13C365-F2CC-4A32-BDD0-52E2DB324734}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E13C365-F2CC-4A32-BDD0-52E2DB324734}.Release|Any CPU.Build.0 = Release|Any CPU
{4E08B0E4-12D4-42BB-A794-995A134A23A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E08B0E4-12D4-42BB-A794-995A134A23A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E08B0E4-12D4-42BB-A794-995A134A23A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E08B0E4-12D4-42BB-A794-995A134A23A8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -102,7 +102,7 @@ namespace ComputerShopBusinessLogic.BusinessLogics
if (string.IsNullOrEmpty(Model.Category))
throw new ArgumentException($"У сборки отсутствует категория");
if (Model.Price <= 0)
if (Model.Price < 0)
throw new ArgumentException("Цена сборки должна быть больше 0", nameof(Model.Price));
var Element = _assemblyStorage.GetElement(new AssemblySearchModel

View File

@ -110,7 +110,7 @@ namespace ComputerShopBusinessLogic.BusinessLogics
if (string.IsNullOrEmpty(Model.ProductName))
throw new ArgumentException($"У товара отсутствует название");
if (Model.Price <= 0)
if (Model.Price < 0)
throw new ArgumentException("Цена товара должна быть больше 0", nameof(Model.Price));
if (Model.Warranty <= 0)

View File

@ -0,0 +1,44 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
namespace ComputerShopBusinessLogic.BusinessLogics
{
public class ReportGuarantorLogic : IReportGuarantorLogic
{
private readonly IComponentStorage _componentStorage;
public ReportGuarantorLogic(IComponentStorage ComponentStorage)
{
_componentStorage = ComponentStorage;
}
/// <summary>
/// Получение отчёта для Word или Excel
/// </summary>
public List<ReportComponentWithShipmentViewModel> GetReportComponentsWithShipments(List<ComponentSearchModel> SelectedComponents)
{
return _componentStorage.GetComponentsWithShipments(SelectedComponents);
}
/// <summary>
/// Получение отчёта для отправки на почту
/// </summary>
public List<ReportComponentByDateViewModel> GetReportComponentsByRequestDate(UserSearchModel CurrentUser, ReportBindingModel Report)
{
return _componentStorage.GetComponentsByShipmentDate(Report, CurrentUser);
}
public void SaveReportToWordFile(ReportBindingModel Model)
{
throw new NotImplementedException();
}
public void SaveReportToExcelFile(ReportBindingModel Model)
{
throw new NotImplementedException();
}
}
}

View File

@ -3,6 +3,8 @@ using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
using GarmentFactoryBusinessLogic.OfficePackage;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
@ -17,36 +19,77 @@ namespace ComputerShopBusinessLogic.BusinessLogics
private readonly IRequestStorage _requestStorage;
private readonly IOrderStorage _orderStorage;
public ReportImplementerLogic(IAssemblyStorage assemblyStorage, IRequestStorage requestStorage, IOrderStorage orderStorage)
private readonly AbstractSaveToExcelImplementer _saveToExcel;
private readonly AbstractSaveToWordImplementer _saveToWord;
private readonly AbstractSaveToPdfImplementer _saveToPdf;
public ReportImplementerLogic(IAssemblyStorage assemblyStorage, IRequestStorage requestStorage, IOrderStorage orderStorage,
AbstractSaveToExcelImplementer saveToExcel, AbstractSaveToWordImplementer saveToWord, AbstractSaveToPdfImplementer saveToPdf)
{
_assemblyStorage = assemblyStorage;
_requestStorage = requestStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
/// <summary>
/// Отчёт для doc/xls
/// </summary>
/// <returns></returns>
public List<ReportOrderAssemblyViewModel> GetReportOrdersAssemblies(List<OrderSearchModel> selectedOrders)
public List<ReportOrderAssemblyViewModel> GetReportOrdersAssemblies(/*List<OrderSearchModel>*/List<int> selectedOrders)
{
return _orderStorage.GetOrdersAssemblies(selectedOrders);
}
/// <summary>
/// Отчёт для почты/страницы
/// Отчёт для почты/страницы в формате PDF
/// </summary>
/// <returns></returns>
public List<ReportOrdersViewModel> GetReportOrdersByDates(UserSearchModel currentUser, ReportBindingModel report)
public List<ReportOrdersViewModel> GetReportOrdersByDates(ReportBindingModel report)
{
return _orderStorage.GetOrdersInfoByDates(currentUser, report);
return _orderStorage.GetOrdersInfoByDates(report);
}
public void SaveReportOrderAssembliesToWordFile(ReportBindingModel model)
{
throw new NotImplementedException();
_saveToWord.CreateDoc(new WordInfoImplementer
{
FileName = model.FileName,
Title = "Список сборок по выбранным заявкам",
OrderAssemblies = GetReportOrdersAssemblies(model.Ids)
});;
//throw new NotImplementedException();
}
public void SaveReportOrderAssembliesToExcelFile(ReportBindingModel model)
{
throw new NotImplementedException();
_saveToExcel.CreateReport(new ExcelInfoImplementer
{
FileName = model.FileName,
OrderAssemblies = GetReportOrdersAssemblies(model.Ids)
});
//throw new NotImplementedException();
}
}
//!!!ИСПРАВИТЬ
public void SaveReportOrdersByDatesToPdfFile(ReportBindingModel model)
{
if (model.DateFrom == null)
{
throw new ArgumentException("Дата начала не задана");
}
if (model.DateTo == null)
{
throw new ArgumentException("Дата окончания не задана");
}
_saveToPdf.CreateDoc(new PdfInfoImplementer
{
FileName = model.FileName,
Title = "Список участников",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Orders = GetReportOrdersByDates(model)
});
}
}
}

View File

@ -7,7 +7,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="MailKit" Version="4.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,194 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcelImplementer
{
public void CreateReport(ExcelInfoImplementer info)
{
CreateExcel(info);
//!!!2 абзаца ниже - настройка заголовков, исправить скорее всего
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title1,
StyleInfo = ExcelStyleInfoType.Title
});
//MergeCells(new ExcelMergeParameters
//{
// CellFromName = "A1",
// CellToName = "C1"
//});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = 1,
Text = info.Title2,
StyleInfo = ExcelStyleInfoType.Title
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = 1,
Text = info.Title3,
StyleInfo = ExcelStyleInfoType.Title
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "D",
RowIndex = 1,
Text = info.Title4,
StyleInfo = ExcelStyleInfoType.Title
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "E",
RowIndex = 1,
Text = info.Title5,
StyleInfo = ExcelStyleInfoType.Title
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "F",
RowIndex = 1,
Text = info.Title6,
StyleInfo = ExcelStyleInfoType.Title
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "G",
RowIndex = 1,
Text = info.Title7,
StyleInfo = ExcelStyleInfoType.Title
});
uint rowIndex = 2;
foreach (var orderAs in info.OrderAssemblies)
{
int cnt_of_assemblies = orderAs.Assemblies.Count;
int assemblyIndex = 0;
foreach (var assembly in orderAs.Assemblies)
{
if (!string.IsNullOrEmpty(assembly.AssemblyName) && !string.IsNullOrEmpty(assembly.AssemblyCategory) && assembly.AssemblyPrice != 0)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = orderAs.OrderId.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = orderAs.DateCreateOrder.ToShortDateString(),
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = orderAs.OrderSum.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "D",
RowIndex = rowIndex,
Text = orderAs.OrderStatus.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "E",
RowIndex = rowIndex,
Text = assembly.AssemblyName,
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "F",
RowIndex = rowIndex,
Text = assembly.AssemblyCategory,
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "G",
RowIndex = rowIndex,
Text = assembly.AssemblyPrice.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
}
assemblyIndex++;
if (assemblyIndex < cnt_of_assemblies && !string.IsNullOrEmpty(assembly.AssemblyName) && !string.IsNullOrEmpty(assembly.AssemblyCategory) && assembly.AssemblyPrice != 0)
{
rowIndex++;
}
}
rowIndex++;
// foreach (var (Component, Count) in tc.Components)
// {
// InsertCellInWorksheet(new ExcelCellParameters
// {
// ColumnName = "B",
// RowIndex = rowIndex,
// Text = Component,
// 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 = tc.TotalCount.ToString(),
// StyleInfo = ExcelStyleInfoType.Text
// });
// rowIndex++;
}
SaveExcel(info);
}
protected abstract void CreateExcel(ExcelInfoImplementer info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams);
protected abstract void MergeCells(ExcelMergeParameters excelParams);
protected abstract void SaveExcel(ExcelInfoImplementer info);
}
}

View File

@ -0,0 +1,47 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdfImplementer
{
public void CreateDoc(PdfInfoImplementer info)
{
//CreatePdf(info);
//CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
//CreateParagraph(new PdfParagraph { Text = $"с {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center });
//CreateTable(new List<string> { "2cm", "3cm", "6cm", "3cm", "3cm" });
//CreateRow(new PdfRowParameters
//{
// Texts = new List<string> { "Номер", "Дата заказа", "Текстиль", "Статус", "Сумма" },
// Style = "NormalTitle",
// ParagraphAlignment = PdfParagraphAlignmentType.Center
//});
//foreach (var order in info.Orders)
//{
// CreateRow(new PdfRowParameters
// {
// Texts = new List<string> { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.TextileName, order.Status.ToString(), order.Sum.ToString() },
// Style = "Normal",
// ParagraphAlignment = PdfParagraphAlignmentType.Left
// });
//}
//CreateParagraph(new PdfParagraph { Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Rigth });
//SavePdf(info);
}
protected abstract void CreatePdf(PdfInfoImplementer info);
protected abstract void CreateParagraph(PdfParagraph paragraph);
protected abstract void CreateTable(List<string> columns);
protected abstract void CreateRow(PdfRowParameters rowParameters);
protected abstract void SavePdf(PdfInfoImplementer info);
}
}

View File

@ -0,0 +1,87 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWordImplementer
{
public void CreateDoc(WordInfoImplementer info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var orderAs in info.OrderAssemblies)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)>
{
("Заказ №" + orderAs.OrderId.ToString() + " - " + orderAs.DateCreateOrder.ToShortDateString() + " - " + orderAs.OrderStatus + " - " + orderAs.OrderSum, new WordTextProperties {Size = "24", Bold=true})
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
foreach (var assembly in orderAs.Assemblies)
{
if (!string.IsNullOrEmpty(assembly.AssemblyName) && !string.IsNullOrEmpty(assembly.AssemblyCategory) && assembly.AssemblyPrice != 0)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {
//(orderAs.OrderId.ToString() + "\n", new WordTextProperties {Size = "24", Bold=true}),
//(orderAs.DateCreateOrder.ToShortDateString() + " - ", new WordTextProperties { Size = "24" }),
//(orderAs.OrderSum.ToString() + " - ", new WordTextProperties { Size = "24" }),
//(orderAs.OrderStatus.ToString() + " - ", new WordTextProperties { Size = "24" }),
(assembly.AssemblyName + " - ", new WordTextProperties { Size = "24" }),
(assembly.AssemblyCategory + " - ", new WordTextProperties { Size = "24" }),
(assembly.AssemblyPrice.ToString(), new WordTextProperties { Size = "24" })
}, TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
}
}
SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfoImplementer info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveWord(WordInfoImplementer info);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBorder
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,18 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelCellParameters
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using ComputerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfoImplementer
{
public string FileName { get; set; } = string.Empty;
//public string Title { get; set; } = string.Empty;
//!!!Мб поставить string.Empty, названия задать в ReportImplementerLogic
public string Title1 { get; set; } = "ID заказа";
public string Title2 { get; set; } = "Дата заказа";
public string Title3 { get; set; } = "Стоимость заказа";
public string Title4 { get; set; } = "Статус заказа";
public string Title5 { get; set; } = "Название сборки";
public string Title6 { get; set; } = "Категория сборки";
public string Title7 { get; set; } = "Цена сборки";
public List<ReportOrderAssemblyViewModel> OrderAssemblies { get; set; } = new();
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,18 @@
using ComputerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfoImplementer
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportOrdersViewModel> Orders { get; set; } = new();
}
}

View File

@ -0,0 +1,16 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using ComputerShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class WordInfoImplementer
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportOrderAssemblyViewModel> OrderAssemblies { get; set; } = new();
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.HelperModels
{
public class WordTextProperties
{
public string Size { get; set; } = string.Empty;
public bool Bold { get; set; }
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,324 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.Implements
{
public class SaveToExcelImplementer : AbstractSaveToExcelImplementer
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
/// <summary>
/// Настройка стилей для файла
/// </summary>
/// <param name="workbookpart"></param>
// WorkbookPart содержит информацию о стилях для ячеек в рабочей книге, добавление стилей в неё
private static void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
//Создание шрифтов для основного текста и заголовка (в ячейке A1)
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
fontUsual.Append(new FontName() { Val = "Times New Roman" });
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 14D });
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
fontTitle.Append(new FontName() { Val = "Times New Roman" });
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
fonts.Append(fontUsual);
fonts.Append(fontTitle);
//Создание заливок ячеек
var fills = new Fills() { Count = 2U };
var fill1 = new Fill();
fill1.Append(new PatternFill() { PatternType = PatternValues.None });
var fill2 = new Fill();
fill2.Append(new PatternFill() { PatternType = PatternValues.Gray125 });
fills.Append(fill1);
fills.Append(fill2);
//Создание границ (без границ и с тонкими границами (исп., где название и кол-во компонента))
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var rightBorder = new RightBorder() { Style = BorderStyleValues.Thin };
rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var bottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin };
bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
var cellFormatStyle = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U };
cellStyleFormats.Append(cellFormatStyle);
//Создание 3 стилей ячеек
var cellFormats = new CellFormats() { Count = 3U };
var cellFormatFont = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U, FormatId = 0U, ApplyFont = true };
var cellFormatFontAndBorder = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyFont = true, ApplyBorder = true };
var cellFormatTitle = new CellFormat() { NumberFormatId = 0U, FontId = 1U, FillId = 0U, BorderId = 0U, FormatId = 0U, Alignment = new Alignment() { Vertical = VerticalAlignmentValues.Center, WrapText = true, Horizontal = HorizontalAlignmentValues.Center }, ApplyFont = true };
cellFormats.Append(cellFormatFont);
cellFormats.Append(cellFormatFontAndBorder);
cellFormats.Append(cellFormatTitle);
var cellStyles = new CellStyles() { Count = 1U };
cellStyles.Append(new CellStyle() { Name = "Normal", FormatId = 0U, BuiltinId = 0U });
var differentialFormats = new DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats() { Count = 0U };
var tableStyles = new TableStyles() { Count = 0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleLight16" };
var stylesheetExtensionList = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
stylesheetExtension1.Append(new SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" });
var stylesheetExtension2 = new StylesheetExtension() { Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" };
stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
stylesheetExtension2.Append(new TimelineStyles() { DefaultTimelineStyle = "TimeSlicerStyleLight1" });
stylesheetExtensionList.Append(stylesheetExtension1);
stylesheetExtensionList.Append(stylesheetExtension2);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellStyleFormats);
sp.Stylesheet.Append(cellFormats);
sp.Stylesheet.Append(cellStyles);
sp.Stylesheet.Append(differentialFormats);
sp.Stylesheet.Append(tableStyles);
sp.Stylesheet.Append(stylesheetExtensionList);
}
/// <summary>
/// Получение номера стиля из типа
/// </summary>
/// <param name="styleInfo"></param>
/// <returns></returns>
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBorder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfoImplementer info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, SpreadsheetDocumentType.Workbook);
// Создание книги (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
// Получение/создание хранилища текстов для книги
_shareStringPart = _spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
? _spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
: _spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
// Создание SharedStringTable, если его нет
if (_shareStringPart.SharedStringTable == null)
{
_shareStringPart.SharedStringTable = new SharedStringTable();
}
// Создание листа в книге
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Добавление столбцов с заданной шириной
// Save the stylesheet formats
//stylesPart.Stylesheet.Save();
// Create custom widths for columns
Columns lstColumns = worksheetPart.Worksheet.GetFirstChild<Columns>();
if (lstColumns == null)
{
lstColumns = new Columns();
}
// Min = 1, Max = 1 ==> Apply this to column 1 (A)
// Min = 2, Max = 2 ==> Apply this to column 2 (B)
// Width = 25 ==> Set the width to 25
// CustomWidth = true ==> Tell Excel to use the custom width
lstColumns.Append(new Column() { Min = 1, Max = 1, Width = 10, CustomWidth = true });
lstColumns.Append(new Column() { Min = 2, Max = 2, Width = 10, CustomWidth = true });
lstColumns.Append(new Column() { Min = 3, Max = 3, Width = 20, CustomWidth = true });
lstColumns.Append(new Column() { Min = 4, Max = 4, Width = 10, CustomWidth = true });
lstColumns.Append(new Column() { Min = 5, Max = 5, Width = 20, CustomWidth = true });
lstColumns.Append(new Column() { Min = 6, Max = 6, Width = 20, CustomWidth = true });
lstColumns.Append(new Column() { Min = 7, Max = 7, Width = 20, CustomWidth = true });
worksheetPart.Worksheet.InsertAt(lstColumns, 0);
// Добавление листа в книгу
var sheets = _spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = _spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
_worksheet = worksheetPart.Worksheet;
}
protected override void InsertCellInWorksheet(ExcelCellParameters excelParams)
{
if (_worksheet == null || _shareStringPart == null)
{
return;
}
var sheetData = _worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
// Ищем строку, либо добавляем ее
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).Any())
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).First();
}
else
{
row = new Row() { RowIndex = excelParams.RowIndex };
sheetData.Append(row);
}
// Ищем нужную ячейку
Cell cell;
if (row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).Any())
{
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).First();
}
else
{
// Все ячейки должны быть последовательно друг за другом расположены
// нужно определить, после какой вставлять
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value, excelParams.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell() { CellReference = excelParams.CellReference };
row.InsertBefore(newCell, refCell);
cell = newCell;
}
// вставляем новый текст
_shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(excelParams.Text)));
_shareStringPart.SharedStringTable.Save();
cell.CellValue = new CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count() - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
}
protected override void MergeCells(ExcelMergeParameters excelParams)
{
if (_worksheet == null)
{
return;
}
MergeCells mergeCells;
if (_worksheet.Elements<MergeCells>().Any())
{
mergeCells = _worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (_worksheet.Elements<CustomSheetView>().Any())
{
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<CustomSheetView>().First());
}
else
{
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
protected override void SaveExcel(ExcelInfoImplementer info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Close();
}
}
}

View File

@ -0,0 +1,113 @@
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.Implements
{
public class SaveToPdfImplementer : AbstractSaveToPdfImplementer
{
private Document? _document;
private Section? _section;
private Table? _table;
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Rigth => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfoImplementer info)
{
_document = new Document();
DefineStyles(_document);
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfoImplementer info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -0,0 +1,139 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using GarmentFactoryBusinessLogic.OfficePackage.HelperEnums;
using GarmentFactoryBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryBusinessLogic.OfficePackage.Implements
{
public class SaveToWordImplementer : AbstractSaveToWordImplementer
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
/// <summary>
/// Получение типа выравнивания
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static JustificationValues GetJustificationValues(WordJustificationType type)
{
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
/// <summary>
/// Настройки страницы
/// </summary>
/// <returns></returns>
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
/// <summary>
/// Задание форматирования для абзаца
/// </summary>
/// <param name="paragraphProperties"></param>
/// <returns></returns>
private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties)
{
if (paragraphProperties == null)
{
return null;
}
var properties = new ParagraphProperties();
properties.AppendChild(new Justification()
{
Val = GetJustificationValues(paragraphProperties.JustificationType)
});
properties.AppendChild(new SpacingBetweenLines
{
LineRule = LineSpacingRuleValues.Auto
});
properties.AppendChild(new Indentation());
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (!string.IsNullOrEmpty(paragraphProperties.Size))
{
paragraphMarkRunProperties.AppendChild(new FontSize { Val = paragraphProperties.Size });
}
properties.AppendChild(paragraphMarkRunProperties);
return properties;
}
protected override void CreateWord(WordInfoImplementer info)
{
_wordDocument = WordprocessingDocument.Create(info.FileName, WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
_docBody = mainPart.Document.AppendChild(new Body());
}
protected override void CreateParagraph(WordParagraph paragraph)
{
if (_docBody == null || paragraph == null)
{
return;
}
var docParagraph = new Paragraph();
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
foreach (var run in paragraph.Texts)
{
var docRun = new Run();
var properties = new RunProperties();
properties.AppendChild(new FontSize { Val = run.Item2.Size });
if (run.Item2.Bold)
{
properties.AppendChild(new Bold());
}
docRun.AppendChild(properties);
docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve });
docParagraph.AppendChild(docRun);
}
_docBody.AppendChild(docParagraph);
}
protected override void SaveWord(WordInfoImplementer info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Close();
}
}
}

View File

@ -15,5 +15,7 @@ namespace ComputerShopContracts.BindingModels
public string Category { get; set; } = string.Empty;
public Dictionary<int, (IComponentModel, int)> AssemblyComponents { get; set; } = new();
public Dictionary<int, int> Test { get; set; } = new();
}
}

View File

@ -11,5 +11,10 @@ namespace ComputerShopContracts.BindingModels
public string FileName { get; set; } = string.Empty;
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public int UserId { get; set; }
//Id выбранных записей
public List<int>? Ids { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.ViewModels;
namespace ComputerShopContracts.BusinessLogicContracts
{
public interface IReportGuarantorLogic
{
/// <summary>
/// Получение отчёта для Word или Excel
/// </summary>
List<ReportComponentWithShipmentViewModel> GetReportComponentsWithShipments(List<ComponentSearchModel> SelectedComponents);
/// <summary>
/// Получение отчёта для отправки на почту
/// </summary>
List<ReportComponentByDateViewModel> GetReportComponentsByRequestDate(UserSearchModel CurrentUser, ReportBindingModel Report);
void SaveReportToWordFile(ReportBindingModel Model);
void SaveReportToExcelFile(ReportBindingModel Model);
}
}

View File

@ -15,7 +15,7 @@ namespace ComputerShopContracts.BusinessLogicContracts
/// Получение отчёта для word/excel
/// </summary>
/// <returns></returns>
List<ReportOrderAssemblyViewModel> GetReportOrdersAssemblies(List<OrderSearchModel> selectedOrders);
List<ReportOrderAssemblyViewModel> GetReportOrdersAssemblies(List</*OrderSearchModel*/int> selectedOrders);
/// <summary>
/// Получение отчёта для почты

View File

@ -17,5 +17,9 @@ namespace ComputerShopContracts.StorageContracts
ComponentViewModel? Update(ComponentBindingModel Model);
ComponentViewModel? Delete(ComponentBindingModel Model);
List<ReportComponentWithShipmentViewModel> GetComponentsWithShipments(List<ComponentSearchModel> Models);
List<ReportComponentByDateViewModel> GetComponentsByShipmentDate(ReportBindingModel ReportModel, UserSearchModel UserModel);
}
}

View File

@ -18,7 +18,7 @@ namespace ComputerShopContracts.StorageContracts
OrderViewModel? Update(OrderBindingModel model);
OrderViewModel? Delete(OrderBindingModel model);
//получение данных о заказах для отчётов
List<ReportOrderAssemblyViewModel> GetOrdersAssemblies(List<OrderSearchModel> model);
List<ReportOrdersViewModel> GetOrdersInfoByDates(UserSearchModel currentUser, ReportBindingModel report);
List<ReportOrderAssemblyViewModel> GetOrdersAssemblies(List<int/*OrderSearchModel*/> model);
List<ReportOrdersViewModel> GetOrdersInfoByDates(ReportBindingModel report);
}
}

View File

@ -0,0 +1,25 @@
namespace ComputerShopContracts.ViewModels
{
public class ReportComponentByDateViewModel
{
public int ComponentId { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double ComponentCost { get; set; }
public int AssemblyId { get; set; }
public string AssemblyName { get; set; } = string.Empty;
public double AssemblyPrice { get; set; }
public string AssemblyCategory { get; set; } = string.Empty;
public int RequestId { get; set; }
public DateTime DateRequest { get; set; }
public string ClientFIO { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,13 @@
namespace ComputerShopContracts.ViewModels
{
public class ReportComponentWithShipmentViewModel
{
public int ComponentId { get; set; }
public string ComponentName { get; set; } = string.Empty;
public double ComponentCost { get; set; }
public List<(int Count, string ProductName, double ProductPrice, string ProviderName, DateTime ShipmentDate)> Shipments { get; set; } = new();
}
}

View File

@ -3,6 +3,7 @@ using ComputerShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@ -18,5 +19,7 @@ namespace ComputerShopContracts.ViewModels
//данные о сборках
public List<(string AssemblyName, string AssemblyCategory, double AssemblyPrice)> Assemblies { get; set; }
//public Dictionary<int, IAssemblyModel> Assemblies { get; set; }
}
}

View File

@ -34,9 +34,14 @@ namespace ComputerShopContracts.ViewModels
public RequestViewModel() { }
[JsonConstructor]
public RequestViewModel(Dictionary<int, OrderViewModel> requestOrders)
public RequestViewModel(Dictionary<int, OrderViewModel> requestOrders, AssemblyViewModel assembly)
{
this.RequestOrders = requestOrders.ToDictionary(x => x.Key, x => x.Value as IOrderModel);
this.Assembly = assembly as IAssemblyModel;
}
//public RequestViewModel(Dictionary<int, OrderViewModel> requestOrders)
//{
// this.RequestOrders = requestOrders.ToDictionary(x => x.Key, x => x.Value as IOrderModel);
//}
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComputerShopDataModels.Enums
namespace ComputerShopDataModels.Enums
{
public enum UserRole
{

View File

@ -17,6 +17,7 @@ namespace ComputerShopDatabaseImplement
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
}
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Component> Components { get; set; }
@ -31,9 +32,13 @@ namespace ComputerShopDatabaseImplement
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Request> Requests { get; set; }
public virtual DbSet<Shipment> Shipments { get; set; }
public virtual DbSet<ShipmentOrder> ShipmentOrders { get; set; }
public virtual DbSet<RequestOrder> RequestOrders { get; set; }
}
}

View File

@ -15,7 +15,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Select(x => x.ViewModel)
.ToList();
}
@ -29,7 +29,7 @@ namespace ComputerShopDatabaseImplement.Implements
{
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId && x.Category == Model.Category)
.Select(x => x.ViewModel)
.ToList();
@ -37,7 +37,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId)
.Select(x => x.ViewModel)
.ToList();
@ -52,14 +52,14 @@ namespace ComputerShopDatabaseImplement.Implements
{
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.AssemblyName == Model.AssemblyName)?
.ViewModel;
}
return Context.Assemblies
.Include(x => x.Components)
.ThenInclude(x => x.Assembly)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.Id == Model.Id)?
.ViewModel;
}

View File

@ -3,6 +3,7 @@ using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
using ComputerShopDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace ComputerShopDatabaseImplement.Implements
{
@ -86,5 +87,56 @@ namespace ComputerShopDatabaseImplement.Implements
return ExistingComponent.ViewModel;
}
public List<ReportComponentWithShipmentViewModel> GetComponentsWithShipments(List<ComponentSearchModel> Models)
{
using var Context = new ComputerShopDatabase();
return Context.Components
.Include(x => x.ProductComponents)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Shipment)
.Where(x =>
Models.Select(x => x.Id).Contains(x.Id) // Компонент, указанный пользователем,
&& x.ProductComponents.Any(y => y.Product.Shipment != null)) // который содержится в товаре, имеющем партию товаров
.ToList()
.Select(x => new ReportComponentWithShipmentViewModel
{
ComponentId = x.Id,
ComponentName = x.ComponentName,
ComponentCost = x.Cost,
Shipments = x.ProductComponents
.Select(y => (y.Count, y.Product.ProductName, y.Product.Price, y.Product.Shipment!.ProviderName, y.Product.Shipment.DateShipment))
.ToList(),
})
.ToList();
}
public List<ReportComponentByDateViewModel> GetComponentsByShipmentDate(ReportBindingModel ReportModel, UserSearchModel UserModel)
{
using var Context = new ComputerShopDatabase();
return Context.Components
.Where(c => c.UserId == UserModel.Id)
.Include(c => c.AssemblyComponents)
.ThenInclude(ac => ac.Assembly)
.ThenInclude(a => a.Requests.Where(r => r.DateRequest >= ReportModel.DateFrom && r.DateRequest <= ReportModel.DateTo))
.ToList()
.SelectMany(c => c.AssemblyComponents
.SelectMany(ac => ac.Assembly.Requests.Select(r => new ReportComponentByDateViewModel
{
ComponentId = c.Id,
ComponentName = c.ComponentName,
ComponentCost = c.Cost,
AssemblyId = ac.Assembly.Id,
AssemblyName = ac.Assembly.AssemblyName,
AssemblyPrice = ac.Assembly.Price,
AssemblyCategory = ac.Assembly.Category,
RequestId = r.Id,
DateRequest = r.DateRequest,
ClientFIO = r.ClientFIO,
})))
.ToList();
}
}
}

View File

@ -55,17 +55,18 @@ namespace ComputerShopDatabaseImplement.Implements
}
//получение данных сборок по выбранным заказам для отчёта (doc/xls)
public List<ReportOrderAssemblyViewModel> GetOrdersAssemblies(List<OrderSearchModel> selectedModels)
public List<ReportOrderAssemblyViewModel> GetOrdersAssemblies(List<int>/*<OrderSearchModel>*/ selectedModels)
{
using var context = new ComputerShopDatabase();
//id заказов, которые выбрал пользователь
List<int?> id_of_selected_models = selectedModels.Select(x => x.Id).ToList();
//List<int?> id_of_selected_models = selectedModels.Select(x => x.Id).ToList();
//те заказы из бд, которые выбрал пользователь и имеют сборку
//МБ ИЗМЕНИТЬ, И СДЕЛАТЬ ВЫВОД ВСЕХ ЗАЯВОК (В ТОМ ЧИСЛЕ БЕЗ СБОРОК)
return context.Orders.Include(x => x.Requests)
.ThenInclude(x => x.Request)
.ThenInclude(x => x.Assembly)
.Where(x => id_of_selected_models.Contains(x.Id) && x.Requests.Any(r => r.Request.Assembly != null))
.Where(x => selectedModels.Contains(x.Id) && x.Requests.Any(r => r.Request.Assembly != null))
.ToList()
.Select(x => new ReportOrderAssemblyViewModel
{
@ -79,13 +80,13 @@ namespace ComputerShopDatabaseImplement.Implements
}
//получение заказов (все, что создал сам пользователь) за период с расшифровкой по заявкам и сборкам для отчёта (почта/страница)
public List<ReportOrdersViewModel> GetOrdersInfoByDates(UserSearchModel currentUser, ReportBindingModel report)
public List<ReportOrdersViewModel> GetOrdersInfoByDates(ReportBindingModel report)
{
using var context = new ComputerShopDatabase();
return context.Orders.Include(x => x.Requests)
.ThenInclude(x => x.Request)
.ThenInclude(x => x.Assembly)
.Where(x => x.UserId == currentUser.Id && x.DateCreate >= report.DateFrom && x.DateCreate <= report.DateTo)
.Where(x => x.UserId == report.UserId && x.DateCreate >= report.DateFrom && x.DateCreate <= report.DateTo)
.ToList()
.Select(x => new ReportOrdersViewModel
{

View File

@ -16,7 +16,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Select(x => x.ViewModel)
.ToList();
}
@ -31,7 +31,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId && x.ShipmentId == Model.ShipmentId)
.Select(x => x.ViewModel)
.ToList();
@ -40,7 +40,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.Where(x => x.UserId == Model.UserId)
.Select(x => x.ViewModel)
.ToList();
@ -56,7 +56,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.ProductName == Model.ProductName)?
.ViewModel;
}
@ -64,7 +64,7 @@ namespace ComputerShopDatabaseImplement.Implements
return Context.Products
.Include(x => x.Shipment)
.Include(x => x.Components)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => x.Id == Model.Id)?
.ViewModel;
}

View File

@ -118,7 +118,7 @@ namespace ComputerShopDatabaseImplement.Implements
using var transaction = context.Database.BeginTransaction();
try
{
var request = context.Requests.FirstOrDefault(x => x.Id == model.Id);
var request = context.Requests.Include(x => x.Orders).ThenInclude(x => x.Order).Include(x => x.Assembly).FirstOrDefault(x => x.Id == model.Id);
if (request == null)
{
return null;
@ -141,9 +141,28 @@ namespace ComputerShopDatabaseImplement.Implements
using var context = new ComputerShopDatabase();
var request = context.Requests
.Include(x => x.Orders)
.ThenInclude(x => x.Order)
.Include(x => x.Assembly)
.FirstOrDefault(y => y.Id == model.Id);
if (request != null)
{
double assemblyPrice;
if (request.Assembly == null)
{
assemblyPrice = 0;
}
else
{
assemblyPrice = request.Assembly.Price;
}
//var ordersOfRequest = context.RequestOrders.Where(x => x.RequestId == model.Id).ToList();
foreach (Order order_request in request.RequestOrders.Values)
{
//Если была связанная сборка, то вычитание стоимости сборки, иначе -0
//order_request.ChangeSum(-(request.Assembly?.Price ?? 0));
order_request.ChangeSum(-assemblyPrice);
}
context.Requests.Remove(request);
context.SaveChanges();
return request.GetViewModel;
@ -154,15 +173,40 @@ namespace ComputerShopDatabaseImplement.Implements
public bool ConnectRequestAssembly(RequestBindingModel model)
{
using var context = new ComputerShopDatabase();
var request = context.Requests.FirstOrDefault(x => x.Id == model.Id);
var assembly = context.Assemblies.FirstOrDefault(x => x.Id == model.AssemblyId);
if (request == null || assembly == null)
var request = context.Requests.Include(x => x.Orders).ThenInclude(x => x.Order).Include(x => x.Assembly).FirstOrDefault(x => x.Id == model.Id);
if (request != null)
{
return false;
// Если у заявки до этого уже была другая связанная сборка
// вычитание стоимости сборки из всех связанных чеков
if (request.Assembly != null)
{
foreach (Order order_of_request in request.RequestOrders.Values)
{
order_of_request.ChangeSum(-request.Assembly.Price);
context.SaveChanges();
}
}
//Поиск заявки, с которой надо связать
var newAssembly = context.Assemblies.FirstOrDefault(x => x.Id == model.AssemblyId);
if (newAssembly == null) {
return false;
}
// Прибавление к стоимости всех связанных заказов стоимость новой сборки
foreach (Order order_of_request in request.RequestOrders.Values)
{
order_of_request.ChangeSum(newAssembly.Price);
context.SaveChanges();
}
// Запоминание новой сборки в заявке
request.ConnectAssembly(context, model);
return true;
}
request.ConnectAssembly(context, model);
context.SaveChanges();
return true;
return false;
}
}
}

View File

@ -96,16 +96,16 @@ namespace ComputerShopDatabaseImplement.Models
{
var currentRequest = context.Requests.First(x => x.Id == Id);
//стоимость сборки, связанной с заявкой (или 0, если заявка не связана со сборкой)
double price_of_assembly = (currentRequest.Assembly.Price != null) ? currentRequest.Assembly.Price : 0;
double price_of_assembly = (currentRequest.AssemblyId != null) ? context.Assemblies.First(x => x.Id == currentRequest.AssemblyId).Price : 0;
var requestOrders = context.RequestOrders.Where(x => x.RequestId == model.Id).ToList();
var oldRequestOrders = context.RequestOrders.Where(x => x.RequestId == model.Id).ToList();
//удаление тех заказов, которых нет в модели (+ изменение суммы у удаляемых заказов)
//ИЗМЕНЕНО: удаление всех заказов
if (requestOrders != null && requestOrders.Count > 0)
if (oldRequestOrders != null && oldRequestOrders.Count > 0)
{
//var delOrders = requestOrders.Where(x => !model.RequestOrders.ContainsKey(x.OrderId));
var delOrders = requestOrders;
var delOrders = oldRequestOrders;
foreach (var delOrder in delOrders)
{
context.RequestOrders.Remove(delOrder);
@ -136,21 +136,9 @@ namespace ComputerShopDatabaseImplement.Models
//Связывание заявки со сборкой (+ изменение суммы у соответствующих заказов)
public void ConnectAssembly(ComputerShopDatabase context, RequestBindingModel model)
{
//стоимость старой сборки (или 0, если её не было)
double price_of_old_assembly = (Assembly.Price != null) ? Assembly.Price : 0;
AssemblyId = model.AssemblyId;
Assembly = context.Assemblies.First(x => x.Id == model.AssemblyId);
//изменение стоимости всех связанных заказов
foreach (var request_order in model.RequestOrders)
{
var connectedOrder = context.Orders.First(x => x.Id == request_order.Key);
//вычитание из стоимости заказа старой сборки
connectedOrder.ChangeSum(-price_of_old_assembly);
//прибавление стоимости новой сборки
connectedOrder.ChangeSum(Assembly.Price);
context.SaveChanges();
}
context.SaveChanges();
}
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,32 @@
using ComputerShopGuarantorApp.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace ComputerShopGuarantorApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

View File

@ -0,0 +1,9 @@
namespace ComputerShopGuarantorApp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,27 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// 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();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:17134",
"sslPort": 44341
}
},
"profiles": {
"ComputerShopGuarantorApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7001;http://localhost:5026",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View File

@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -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"] - ComputerShopGuarantorApp</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="~/ComputerShopGuarantorApp.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">ComputerShopGuarantorApp</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">
&copy; 2024 - ComputerShopGuarantorApp - <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>

View File

@ -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;
}

View File

@ -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>

View File

@ -0,0 +1,3 @@
@using ComputerShopGuarantorApp
@using ComputerShopGuarantorApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,4 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.

View File

@ -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.

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

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

View 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

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

View 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

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-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

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

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

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

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

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

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

Some files were not shown because too many files have changed in this diff Show More