Compare commits

...

93 Commits

Author SHA1 Message Date
a85fa1714f change WorkModeling and OrderLogic 2024-06-21 18:36:11 +04:00
f8c72b171c fix merge conflicts 2024-06-21 18:35:50 +04:00
9a5b50286b authentication in ShopApp 2024-06-21 14:29:50 +04:00
a6264c5b1b Fixed Shop view 2024-05-15 00:31:09 +04:00
fd667be8b0 Done views 2024-05-15 00:03:25 +04:00
c9d251a794 Implement controller 2024-05-14 23:53:59 +04:00
2aace65848 Add Shop Web-Application project 2024-05-14 23:46:36 +04:00
6714d4f3ef Add Shop controller 2024-05-14 23:43:30 +04:00
30ba254e86 Fixed conflicts 2024-05-14 22:52:16 +04:00
fab7391ca7 Finish report forms 2024-05-14 22:29:05 +04:00
1ff73bce3a Report forms 2024-05-13 22:38:52 +04:00
22b2783547 Pdf report implement & ReportLogic 2024-05-05 22:32:34 +04:00
10a344f0b1 Excel report implement 2024-05-05 22:22:55 +04:00
8428b895a8 Word report implement 2024-05-05 22:16:39 +04:00
6d525876bc Shop report contacts 2024-05-05 22:02:16 +04:00
a07aff9438 Commit Staged 2024-05-05 21:47:39 +04:00
67bffd6798 Fix Shop-Repair relationship 2024-05-05 21:41:04 +04:00
1d24f91773 update migration 2024-04-17 11:10:28 +04:00
c1a7d73d39 delete PDF-file 2024-04-17 10:01:10 +04:00
3d750ef0b2 DatabaseImplement - ShopStorage 2024-04-17 01:36:29 +04:00
fe3e9171e8 DatabaseImplement/Models 2024-04-17 01:23:18 +04:00
abf3aeca23 Merge branch 'Lab2_Hard' into Lab3_Hard 2024-04-17 01:12:01 +04:00
81b4335193 fix ShopStorage.Sell 2024-04-17 01:07:56 +04:00
da4f49e290 fix WorkerWorkAsync 2024-04-16 23:48:41 +04:00
1b016cc7d8 remove buttons from MainForm 2024-04-16 21:38:14 +04:00
26eadb9fd4 Implementer forms 2024-04-16 21:33:18 +04:00
915758fdf0 update Migration 2024-04-16 20:11:17 +04:00
e3721f13cb DatabaseImplement 2024-04-16 20:08:06 +04:00
3a5157069b add ImplementerController 2024-04-16 19:54:51 +04:00
6700d24634 ListImplement 2024-04-16 19:50:39 +04:00
1e49ce1e21 FileImplement 2024-04-16 00:32:20 +04:00
75911262ea Implementer contracts, data models, business logic 2024-04-16 00:06:12 +04:00
1d6b9b85f6 Merge branch 'Lab5' of http://student.git.athene.tech/olshab/PIbd-22_Shabunov_O.A._AutoWorkshop into Lab5 2024-04-13 01:05:27 +04:00
07a600ed47 OrderStorage GetFilteredList fix 2024-04-13 01:04:31 +04:00
bfe546dd2b ClientStorage GetFilteredList fix 2024-04-13 01:04:30 +04:00
e4a611748c delete WeatherForecast 2024-04-13 01:04:30 +04:00
78c625122d add ClientApp project 2024-04-13 01:04:30 +04:00
4c543e5fde create RestApi project 2024-04-13 01:04:30 +04:00
2ac06320e6 List implement 2024-04-13 01:04:30 +04:00
3e7ccbdc62 File implement 2024-04-13 01:04:30 +04:00
edfe10dd44 database implement 2024-04-13 01:04:30 +04:00
e65f441c79 client BusinessLogic, Contracts, DataModels 2024-04-13 01:04:30 +04:00
f1c6437bc7 delete .pdf 2024-04-13 00:59:11 +04:00
74c055bc42 OrderStorage GetFilteredList fix 2024-04-13 00:46:55 +04:00
e61adfda15 ClientStorage GetFilteredList fix 2024-04-13 00:32:02 +04:00
73aa336a2a delete WeatherForecast 2024-04-13 00:16:40 +04:00
c8ecd34648 add ClientApp project 2024-04-11 14:21:59 +04:00
fa1a969cfe create RestApi project 2024-04-11 12:41:44 +04:00
b6eca8cccd List implement 2024-04-11 01:07:25 +04:00
de84ecc71b File implement 2024-04-11 00:57:19 +04:00
ebe66f4992 database implement 2024-04-11 00:47:41 +04:00
965db848b1 client BusinessLogic, Contracts, DataModels 2024-04-11 00:30:45 +04:00
d363e63eb8 copy ReportOrder.rdlc to output dir 2024-04-11 00:12:16 +04:00
1f791d68d7 1252 encoding fix 2024-04-11 00:09:06 +04:00
3e61ea61df OrderStorage GetFilteredList fix 2024-04-11 00:03:43 +04:00
b81bb26b41 shop repair overflow fix 2024-04-10 23:59:33 +04:00
c10255f4cb filepath fix 2024-04-10 23:57:15 +04:00
b1300d39ef add Report.rdlc 2024-04-10 22:41:45 +04:00
036c45410e pre-add Report.rdlc 2024-04-10 22:22:51 +04:00
ad9847c51c ShopRepairs saving fix 2024-04-10 21:49:56 +04:00
5d703cb615 Sell form 2024-04-10 00:26:00 +04:00
b4c8722cd4 Shop File implement 2024-04-09 23:44:27 +04:00
2fa2dfe6bc add Shop Sale 2024-04-09 23:29:25 +04:00
1a650d93b1 Merge branch 'Lab1_Hard' into Lab2_Hard 2024-04-09 23:09:49 +04:00
b4d4b6d0f4 done Forms/Shop 2024-04-09 22:58:05 +04:00
57d43005e6 fix BusinessLogic 2024-04-09 22:14:14 +04:00
4330a80dd0 start Shop forms 2024-04-03 11:16:21 +04:00
8447239146 ListImplement 2024-04-03 11:06:33 +04:00
8ad6e9478e BusinessLogic, Contracts, DataModels 2024-04-03 10:56:29 +04:00
fe53deabde Report forms 2024-04-03 10:26:18 +04:00
8114ecd7fb done BusinessLogic 2024-04-03 00:29:56 +04:00
054222a8d4 apply migration 2024-04-02 23:29:59 +04:00
4ac87a10ed need Update-Database 2024-04-02 22:18:03 +04:00
332c58bda5 fix DataBaseImplement/Models 2024-04-02 22:00:25 +04:00
e1fdeb7ba3 Database/Migrations 2024-03-20 11:06:47 +04:00
56faadb0ad Database/Implements 2024-03-20 10:14:29 +04:00
27449f920f Database/Models 2024-03-19 23:17:38 +04:00
0d0ccaea66 Delete pdf file 2024-03-19 22:30:21 +04:00
82ce660a86 AutoWorkshopFileImplement/Implements 2024-03-19 22:22:43 +04:00
e3a1f15b7c AutoWorkshopFileImplements/Models 2024-03-19 22:01:33 +04:00
e9691f2f63 Rename MainForm title 2024-03-19 21:18:58 +04:00
a83f263f8d Rename AutoWorkshopView project 2024-03-19 21:06:32 +04:00
0a09ce4051 Fix RepairName 2024-03-19 20:56:40 +04:00
b2bfe09ae5 TakeOrderInWork fix 2024-02-21 11:19:50 +04:00
49059764f0 FormRepairs 2024-02-21 11:04:46 +04:00
98ba30c161 MainForm 2024-02-21 10:49:14 +04:00
61d7f60024 forms 2024-02-21 10:36:30 +04:00
4cb2a32dae start View project 2024-02-20 23:51:24 +04:00
6eea8a37f5 rename AutoWorkshopListImplement 2024-02-20 23:23:35 +04:00
63a6e7f705 AutoWorkshopImplement project 2024-02-20 23:14:51 +04:00
05d759ac94 fix iid data models 2024-02-06 23:44:01 +04:00
dfbe5539dd Contracts 2024-02-06 23:43:23 +04:00
fb5a98c8ed DataModels 2024-02-06 23:26:29 +04:00
362 changed files with 166549 additions and 78 deletions

View File

@ -3,7 +3,25 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshop", "AutoWorkshop\AutoWorkshop.csproj", "{54087BAE-4821-4266-9968-190F9F4355C8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopView", "AutoWorkshopView\AutoWorkshopView.csproj", "{54087BAE-4821-4266-9968-190F9F4355C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopDataModels", "AutoWorkshopDataModels\AutoWorkshopDataModels.csproj", "{D52094D2-A57E-4BAD-B049-3B64065463DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopContracts", "AutoWorkshopContracts\AutoWorkshopContracts.csproj", "{93CF1C25-57B5-4E95-A394-E01AE440E138}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopBusinessLogic", "AutoWorkshopBusinessLogic\AutoWorkshopBusinessLogic.csproj", "{132C30F4-07B1-4D1A-99C0-0A8E538EB2D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopListImplement", "AutoWorkshopImplement\AutoWorkshopListImplement.csproj", "{B564F5E8-2F14-4816-8481-1F9649F1F414}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopFileImplement", "AutoWorkshopFileImplement\AutoWorkshopFileImplement.csproj", "{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopDatabaseImplement", "AutoWorkshopDatabaseImplement\AutoWorkshopDatabaseImplement.csproj", "{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopRestApi", "AutoWorkshopRestApi\AutoWorkshopRestApi.csproj", "{15C54F32-1549-4887-BE08-DC6845B0D7ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoWorkshopClientApp", "AutoWorkshopClientApp\AutoWorkshopClientApp.csproj", "{EAE83B19-8CE1-4589-907A-DB9C8313FA06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoWorkshopShopApp", "AutoWorkshopShopApp\AutoWorkshopShopApp.csproj", "{5934B924-59F1-42B6-9116-33F4947525CC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +33,42 @@ Global
{54087BAE-4821-4266-9968-190F9F4355C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54087BAE-4821-4266-9968-190F9F4355C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54087BAE-4821-4266-9968-190F9F4355C8}.Release|Any CPU.Build.0 = Release|Any CPU
{D52094D2-A57E-4BAD-B049-3B64065463DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D52094D2-A57E-4BAD-B049-3B64065463DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D52094D2-A57E-4BAD-B049-3B64065463DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D52094D2-A57E-4BAD-B049-3B64065463DA}.Release|Any CPU.Build.0 = Release|Any CPU
{93CF1C25-57B5-4E95-A394-E01AE440E138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93CF1C25-57B5-4E95-A394-E01AE440E138}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93CF1C25-57B5-4E95-A394-E01AE440E138}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93CF1C25-57B5-4E95-A394-E01AE440E138}.Release|Any CPU.Build.0 = Release|Any CPU
{132C30F4-07B1-4D1A-99C0-0A8E538EB2D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{132C30F4-07B1-4D1A-99C0-0A8E538EB2D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{132C30F4-07B1-4D1A-99C0-0A8E538EB2D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{132C30F4-07B1-4D1A-99C0-0A8E538EB2D8}.Release|Any CPU.Build.0 = Release|Any CPU
{B564F5E8-2F14-4816-8481-1F9649F1F414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B564F5E8-2F14-4816-8481-1F9649F1F414}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B564F5E8-2F14-4816-8481-1F9649F1F414}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B564F5E8-2F14-4816-8481-1F9649F1F414}.Release|Any CPU.Build.0 = Release|Any CPU
{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{862B0F3D-1B88-45B8-9526-AD21A6D6FA81}.Release|Any CPU.Build.0 = Release|Any CPU
{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}.Debug|Any CPU.Build.0 = Debug|Any CPU
{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}.Release|Any CPU.ActiveCfg = Release|Any CPU
{751668F7-01A3-43F0-BDD8-ABB3A8F5A955}.Release|Any CPU.Build.0 = Release|Any CPU
{15C54F32-1549-4887-BE08-DC6845B0D7ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15C54F32-1549-4887-BE08-DC6845B0D7ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15C54F32-1549-4887-BE08-DC6845B0D7ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15C54F32-1549-4887-BE08-DC6845B0D7ED}.Release|Any CPU.Build.0 = Release|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAE83B19-8CE1-4589-907A-DB9C8313FA06}.Release|Any CPU.Build.0 = Release|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5934B924-59F1-42B6-9116-33F4947525CC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -1,39 +0,0 @@
namespace AutoWorkshop
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace AutoWorkshop
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -1,17 +0,0 @@
namespace AutoWorkshop
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoWorkshopContracts\AutoWorkshopContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,121 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> Logger, IClientStorage ClientStorage)
{
_logger = Logger;
_clientStorage = ClientStorage;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? Model)
{
_logger.LogInformation("ReadList. ClientFIO: {ClientFIO}. Id: {Id}", Model?.ClientFIO, Model?.Id);
var List = Model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(Model);
if (List == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", List.Count);
return List;
}
public ClientViewModel? ReadElement(ClientSearchModel Model)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
_logger.LogInformation("ReadElement. ClientFIO: {ClientFIO}.Id: {Id}", Model.ClientFIO, Model.Id);
ClientViewModel? Client = _clientStorage.GetElement(Model);
if (Client == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", Client.Id);
return Client;
}
public bool Create(ClientBindingModel Model)
{
CheckModel(Model);
if (_clientStorage.Insert(Model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ClientBindingModel Model)
{
CheckModel(Model);
if (_clientStorage.Update(Model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel Model)
{
CheckModel(Model, false);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_clientStorage.Delete(Model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel Model, bool WithParams=true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
if (string.IsNullOrEmpty(Model.ClientFIO))
throw new ArgumentNullException("Нет ФИО клиента", nameof(Model.ClientFIO));
if (string.IsNullOrEmpty(Model.Email))
throw new ArgumentNullException("Нет Email клиента", nameof(Model.ClientFIO));
if (string.IsNullOrEmpty(Model.Password))
throw new ArgumentNullException("Нет пароля клиента", nameof(Model.ClientFIO));
_logger.LogInformation("Client. ClientFIO: {ClientFIO}." +
"Email: {Email}. Password: {Password}. Id: {Id} ", Model.ClientFIO, Model.Email, Model.Password, Model.Id);
ClientViewModel? Client = _clientStorage.GetElement(new ClientSearchModel
{
Email = Model.Email,
});
if (Client != null && Client.Id != Model.Id)
throw new InvalidOperationException("Клиент с таким логином уже есть");
}
}
}

View File

@ -0,0 +1,125 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ComponentLogic : IComponentLogic
{
private readonly ILogger _logger;
private readonly IComponentStorage _componentStorage;
public ComponentLogic(ILogger<ComponentLogic> Logger, IComponentStorage ComponentStorage)
{
_logger = Logger;
_componentStorage = ComponentStorage;
}
public List<ComponentViewModel>? ReadList(ComponentSearchModel? Model)
{
_logger.LogInformation("ReadList. ComponentName:{ComponentName}. Id:{Id}",
Model?.ComponentName, Model?.Id);
var List = Model is null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(Model);
if (List is null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", List.Count);
return List;
}
public ComponentViewModel? ReadElement(ComponentSearchModel? Model)
{
if (Model is null)
throw new ArgumentNullException(nameof(Model));
_logger.LogInformation("ReadElement. ComponentName:{ComponentName}. Id:{Id}",
Model.ComponentName, Model.Id);
var Element = _componentStorage.GetElement(Model);
if (Element is null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement element found. Id:{Id}", Element.Id);
return Element;
}
public bool Create(ComponentBindingModel Model)
{
CheckModel(Model);
if (_componentStorage.Insert(Model) is null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ComponentBindingModel Model)
{
CheckModel(Model);
if (_componentStorage.Update(Model) is null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ComponentBindingModel Model)
{
CheckModel(Model, false);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_componentStorage.Delete(Model) is null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ComponentBindingModel Model, bool WithParams = true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (string.IsNullOrEmpty(Model.ComponentName))
throw new ArgumentNullException("Нет названия компонента", nameof(Model.ComponentName));
if (Model.Cost <= 0)
throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(Model.Cost));
_logger.LogInformation("Repair. ComponentName:{ComponentName}. Cost:{Cost}. Id:{Id}",
Model.ComponentName, Model.Cost, Model.Id);
var Element = _componentStorage.GetElement(new ComponentSearchModel
{
ComponentName = Model.ComponentName
});
if (Element != null && Element.Id != Model.Id)
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}

View File

@ -0,0 +1,135 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
private readonly ILogger _logger;
private readonly IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<IImplementerLogic> Logger, IImplementerStorage ImplementerStorage)
{
_logger = Logger;
_implementerStorage = ImplementerStorage;
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? Model)
{
_logger.LogInformation("ReadList. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}",
Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id);
var List = Model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(Model);
if (List == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", List.Count);
return List;
}
public ImplementerViewModel? ReadElement(ImplementerSearchModel Model)
{
if (Model is null)
{
throw new ArgumentNullException(nameof(Model));
}
_logger.LogInformation("ReadElement. ImplementerFIO: {ImplementerFIO}. Password: {Password}. Id: {Id}",
Model?.ImplementerFIO, Model?.Password?.Length, Model?.Id);
var Element = _implementerStorage.GetElement(Model);
if (Element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", Element.Id);
return Element;
}
public bool Create(ImplementerBindingModel Model)
{
CheckModel(Model);
if (_implementerStorage.Insert(Model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ImplementerBindingModel Model)
{
CheckModel(Model);
if (_implementerStorage.Update(Model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ImplementerBindingModel Model)
{
CheckModel(Model, false);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_implementerStorage.Delete(Model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ImplementerBindingModel Model, bool WithParams = true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (string.IsNullOrEmpty(Model.ImplementerFIO))
throw new ArgumentNullException("Нет ФИО исполнителя", nameof(Model.ImplementerFIO));
if (string.IsNullOrEmpty(Model.Password))
throw new ArgumentNullException("Нет пароля исполнителя", nameof(Model.Password));
if (Model.WorkExperience < 0)
throw new ArgumentNullException("Стаж должен быть неотрицательным целым числом", nameof(Model.WorkExperience));
if (Model.Qualification < 0)
throw new ArgumentNullException("Квалификация должна быть неотрицательным целым числом", nameof(Model.Qualification));
_logger.LogInformation("Implementer. ImplementerFIO: {ImplementerFIO}. Password: {Password}. WorkExperience: {WorkExperience}. Qualification: {Qualification}. Id: {Id}",
Model.ImplementerFIO, Model.Password, Model.WorkExperience, Model.Qualification, Model.Id);
var Implementer = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = Model.ImplementerFIO
});
if (Implementer != null && Implementer.Id != Model.Id)
{
throw new InvalidOperationException("Исполнитель с таким ФИО уже есть");
}
}
}
}

View File

@ -0,0 +1,202 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using DocumentFormat.OpenXml.EMMA;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private static readonly object _locker = new object();
public OrderLogic(ILogger<RepairLogic> Logger, IOrderStorage OrderStorage, IShopStorage ShopStorage)
{
_logger = Logger;
_orderStorage = OrderStorage;
_shopStorage = ShopStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? Model)
{
_logger.LogInformation("ReadList. ClientId: {ClientId}. Status: {Status}. ImplementerId: {ImplementerId}. DateFrom: {DateFrom}. DateTo: {DateTo}. OrderId: {Id}",
Model?.ClientId, Model?.Status, Model?.ImplementerId, Model?.DateFrom, Model?.DateTo, Model?.Id);
var List = Model is null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(Model);
if (List is null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", List.Count);
return List;
}
public bool CreateOrder(OrderBindingModel Model)
{
CheckModel(Model);
if (Model.Status != OrderStatus.Undefined)
{
_logger.LogWarning("Invalid order status");
return false;
}
Model.Status = OrderStatus.Accepted;
if (_orderStorage.Insert(Model) is null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
private bool ChangeOrderStatus(OrderBindingModel Model, OrderStatus NewStatus)
{
Model = FillOrderBindingModel(Model);
if (Model.Status + 1 != NewStatus)
{
_logger.LogWarning("Change status operation failed. Incorrect new status: {NewStatus}. Current status: {currStatus}",
NewStatus, Model.Status);
return false;
}
Model.Status = NewStatus;
if (Model.Status == OrderStatus.Ready)
Model.DateImplement = DateTime.Now;
return UpdateOrder(Model);
}
public bool TakeOrderInWork(OrderBindingModel Model)
{
lock (_locker)
{
return ChangeOrderStatus(Model, OrderStatus.BeingProcessed);
}
}
public bool FinishOrder(OrderBindingModel Model)
{
return ChangeOrderStatus(Model, OrderStatus.Ready);
}
public bool DeliveryOrder(OrderBindingModel Model)
{
lock ( _locker)
{
Model = FillOrderBindingModel(Model);
if (Model.Status != OrderStatus.Ready && Model.Status != OrderStatus.Waiting)
{
_logger.LogWarning("Changing status operation failed");
throw new InvalidOperationException($"Невозможно присвоить статус Delivered заказу с текущим статусом {Model.Status}");
}
if (!_shopStorage.RestockingShops(new SupplyBindingModel
{
RepairId = Model.RepairId,
Count = Model.Count
}))
{
Model.Status = OrderStatus.Waiting;
return UpdateOrder(Model);
}
Model.Status = OrderStatus.Delivered;
return UpdateOrder(Model);
}
}
private void CheckModel(OrderBindingModel Model, bool WithParams = true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (Model.Count <= 0)
throw new ArgumentNullException("Количество ремонтов в заказе быть больше 0", nameof(Model.Count));
if (Model.Sum <= 0)
throw new ArgumentNullException("Стоимость заказа должна быть больше 0", nameof(Model.Sum));
_logger.LogInformation("Order. RepairId:{RepairId}. Count:{Count}. Sum:{Sum}. " +
"Status:{Status}. DateCreate:{DateCreate}. DateImplement:{DateImplement}. Id: {Id}",
Model.RepairId, Model.Count, Model.Sum, Model.Status, Model.DateCreate,
Model.DateImplement, Model.Id);
}
public OrderViewModel? ReadElement(OrderSearchModel Model)
{
if (Model == null)
{
throw new ArgumentNullException(nameof(Model));
}
_logger.LogInformation("ReadElement. ClientId: {ClientId}. Status: {Status}. ImplementerId: {ImplementerId}. DateFrom: {DateFrom}. DateTo: {DateTo}. OrderId: {Id}",
Model.ClientId, Model.Status, Model.ImplementerId, Model.DateFrom, Model.DateTo, Model.Id);
var Order = _orderStorage.GetElement(Model);
if (Order == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", Order.Id);
return Order;
}
private OrderBindingModel FillOrderBindingModel(OrderBindingModel Model)
{
CheckModel(Model, false);
var OrderViewModel = _orderStorage.GetElement(new OrderSearchModel()
{
Id = Model.Id
});
if (OrderViewModel == null)
{
throw new InvalidOperationException(nameof(OrderViewModel));
}
Model.Id = OrderViewModel.Id;
Model.DateCreate = OrderViewModel.DateCreate;
Model.RepairId = OrderViewModel.RepairId;
Model.DateImplement = OrderViewModel.DateImplement;
Model.ClientId = OrderViewModel.ClientId;
Model.Status = OrderViewModel.Status;
Model.Count = OrderViewModel.Count;
Model.Sum = OrderViewModel.Sum;
if (!Model.ImplementerId.HasValue)
{
Model.ImplementerId = OrderViewModel.ImplementerId;
}
return Model;
}
private bool UpdateOrder(OrderBindingModel Model)
{
if (_orderStorage.Update(Model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
_logger.LogWarning("Update operation sucsess");
return true;
}
}
}

View File

@ -0,0 +1,125 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class RepairLogic : IRepairLogic
{
private readonly ILogger _logger;
private readonly IRepairStorage _repairStorage;
public RepairLogic(ILogger<RepairLogic> Logger, IRepairStorage RepairStorage)
{
_logger = Logger;
_repairStorage = RepairStorage;
}
public List<RepairViewModel>? ReadList(RepairSearchModel? Model)
{
_logger.LogInformation("ReadList. RepairName:{RepairName}. Id:{Id}",
Model?.RepairName, Model?.Id);
var List = Model is null ? _repairStorage.GetFullList() : _repairStorage.GetFilteredList(Model);
if (List is null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", List.Count);
return List;
}
public RepairViewModel? ReadElement(RepairSearchModel? Model)
{
if (Model is null)
throw new ArgumentNullException(nameof(Model));
_logger.LogInformation("ReadElement. RepairName:{RepairName}. Id:{Id}",
Model.RepairName, Model.Id);
var Element = _repairStorage.GetElement(Model);
if (Element is null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement element found. Id:{Id}", Element.Id);
return Element;
}
public bool Create(RepairBindingModel Model)
{
CheckModel(Model);
if (_repairStorage.Insert(Model) is null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(RepairBindingModel Model)
{
CheckModel(Model);
if (_repairStorage.Update(Model) is null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(RepairBindingModel Model)
{
CheckModel(Model);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_repairStorage.Delete(Model) is null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(RepairBindingModel Model, bool WithParams = true)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (!WithParams)
return;
if (string.IsNullOrEmpty(Model.RepairName))
throw new ArgumentNullException("Нет названия ремонта", nameof(Model.RepairName));
if (Model.Price <= 0)
throw new ArgumentNullException("Стоимость ремонта должна быть больше 0", nameof(Model.Price));
_logger.LogInformation("Repair. RepairName:{RepairName}. Price:{Price}. Id: {Id}",
Model.RepairName, Model.Price, Model.Id);
var Element = _repairStorage.GetElement(new RepairSearchModel
{
RepairName = Model.RepairName
});
if (Element != null && Element.Id != Model.Id)
throw new InvalidOperationException("Ремонт с таким названием уже есть");
}
}
}

View File

@ -0,0 +1,142 @@
using AutoWorkshopBusinessLogic.OfficePackage;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ReportLogic : IReportLogic
{
private readonly IComponentStorage _componentStorage;
private readonly IRepairStorage _RepairStorage;
private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IRepairStorage RepairStorage, IComponentStorage ComponentStorage, IOrderStorage OrderStorage, IShopStorage ShopStorage,
AbstractSaveToExcel SaveToExcel, AbstractSaveToWord SaveToWord, AbstractSaveToPdf SaveToPdf)
{
_RepairStorage = RepairStorage;
_componentStorage = ComponentStorage;
_orderStorage = OrderStorage;
_shopStorage = ShopStorage;
_saveToExcel = SaveToExcel;
_saveToWord = SaveToWord;
_saveToPdf = SaveToPdf;
}
public List<ReportRepairComponentViewModel> GetRepairComponents()
{
return _RepairStorage.GetFullList().
Select(x => new ReportRepairComponentViewModel
{
RepairName = x.RepairName,
Components = x.RepairComponents.Select(x => (x.Value.Item1.ComponentName, x.Value.Item2)).ToList(),
TotalCount = x.RepairComponents.Select(x => x.Value.Item2).Sum()
})
.ToList();
}
public List<ReportShopsViewModel> GetShops()
{
return _shopStorage.GetFullList().Select(x => new ReportShopsViewModel
{
ShopName = x.ShopName,
Repairs = x.ShopRepairs.Select(x => (x.Value.Item1.RepairName, x.Value.Item2)).ToList(),
TotalCount = x.ShopRepairs.Select(x => x.Value.Item2).Sum()
}).ToList();
}
public List<ReportGroupedOrdersViewModel> GetGroupedOrders()
{
return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportGroupedOrdersViewModel
{
Date = x.Key,
OrdersCount = x.Count(),
OrdersSum = x.Select(y => y.Sum).Sum()
}).ToList();
}
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel Model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel { DateFrom = Model.DateFrom, DateTo = Model.DateTo })
.Select(x => new ReportOrdersViewModel
{
Id = x.Id,
DateCreate = x.DateCreate,
RepairName = x.RepairName,
Sum = x.Sum,
Status = x.Status.ToString()
})
.ToList();
}
public void SaveRepairsToWordFile(ReportBindingModel Model)
{
_saveToWord.CreateRepairsDoc(new WordRepairsInfo
{
FileName = Model.FileName,
Title = "Список ремонтов",
Repairs = _RepairStorage.GetFullList()
});
}
public void SaveRepairComponentToExcelFile(ReportBindingModel Model)
{
_saveToExcel.CreateReport(new ExcelRepairsInfo
{
FileName = Model.FileName,
Title = "Список ремонтов",
RepairComponents = GetRepairComponents()
});
}
public void SaveOrdersToPdfFile(ReportBindingModel Model)
{
_saveToPdf.CreateDoc(new PdfOrdersInfo
{
FileName = Model.FileName,
Title = "Список заказов",
DateFrom = Model.DateFrom!.Value,
DateTo = Model.DateTo!.Value,
Orders = GetOrders(Model)
});
}
public void SaveShopsToWordFile(ReportBindingModel model)
{
_saveToWord.CreateShopsDoc(new WordShopsInfo
{
FileName = model.FileName,
Title = "Список магазинов",
Shops = _shopStorage.GetFullList()
});
}
public void SaveShopsToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateShopRepairsReport(new ExcelShopsInfo
{
FileName = model.FileName,
Title = "Загруженность магазинов",
ShopRepairs = GetShops()
});
}
public void SaveGroupedOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateGroupedOrdersDoc(new PdfGroupedOrdersInfo
{
FileName = model.FileName,
Title = "Список заказов, объединенных по датам",
GroupedOrders = GetGroupedOrders()
});
}
}
}

View File

@ -0,0 +1,194 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.StoragesContracts;
using AutoWorkshopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
private readonly IRepairStorage _repairStorage;
public ShopLogic(ILogger<ShopLogic> Logger, IShopStorage ShopStorage, IRepairStorage RepairStorage)
{
_logger = Logger;
_shopStorage = ShopStorage;
_repairStorage = RepairStorage;
}
public List<ShopViewModel>? ReadList(ShopSearchModel? Model)
{
_logger.LogInformation("ReadList. ShopName:{ShopName}.Id:{ Id}", Model?.ShopName, Model?.Id);
var List = Model == null ? _shopStorage.GetFullList() : _shopStorage.GetFilteredList(Model);
if (List == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", List.Count);
return List;
}
public ShopViewModel? ReadElement(ShopSearchModel Model)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
_logger.LogInformation("ReadElement. ShopName:{ShopName}.Id:{ Id}", Model.ShopName, Model.Id);
var Element = _shopStorage.GetElement(Model);
if (Element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", Element.Id);
return Element;
}
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);
_logger.LogInformation("Delete. Id:{Id}", Model.Id);
if (_shopStorage.Delete(Model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public bool MakeSupply(SupplyBindingModel Model)
{
if (Model == null)
throw new ArgumentNullException(nameof(Model));
if (Model.Count <= 0)
throw new ArgumentException("Количество ремонтов должно быть больше 0");
ShopViewModel? Shop = _shopStorage.GetElement(new ShopSearchModel
{
Id = Model.ShopId
});
if (Shop == null)
throw new ArgumentException("Магазина не существует");
int CurrentRepairsNum = Shop.ShopRepairs.Select(x => x.Value.Item2).Sum();
if (Model.Count > Shop.RepairsMaxCount - CurrentRepairsNum)
{
_logger.LogWarning("Попытка добавить в магазин число элементов, большее RepairsMaxCount");
return false;
}
if (Shop.ShopRepairs.ContainsKey(Model.RepairId))
{
var RepairsNum = Shop.ShopRepairs[Model.RepairId];
RepairsNum.Item2 += Model.Count;
Shop.ShopRepairs[Model.RepairId] = RepairsNum;
}
else
{
var Repair = _repairStorage.GetElement(new RepairSearchModel
{
Id = Model.RepairId
});
if (Repair == null)
throw new ArgumentException($"Поставка: Товар с id {Model.RepairId} не найден");
Shop.ShopRepairs.Add(Model.RepairId, (Repair, Model.Count));
}
_shopStorage.Update(new ShopBindingModel()
{
Id = Shop.Id,
ShopName = Shop.ShopName,
Address = Shop.Address,
OpeningDate = Shop.OpeningDate,
ShopRepairs = Shop.ShopRepairs,
RepairsMaxCount = Shop.RepairsMaxCount,
});
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.Address))
throw new ArgumentException("Адрес магазина длжен быть заполнен", nameof(Model.Address));
if (string.IsNullOrEmpty(Model.ShopName))
throw new ArgumentException("Название магазина должно быть заполнено", nameof(Model.ShopName));
_logger.LogInformation("Shop. ShopName: {ShopName}. Address: {Address}. OpeningDate: {OpeningDate}. Id:{Id}",
Model.ShopName, Model.Address, Model.OpeningDate, Model.Id);
var Element = _shopStorage.GetElement(new ShopSearchModel
{
ShopName = Model.ShopName
});
if (Element != null && Element.Id != Model.Id)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
public bool MakeSell(SupplySearchModel Model)
{
if (!Model.RepairId.HasValue || !Model.Count.HasValue)
return false;
_logger.LogInformation("Поиск ремонтов во всех магазинах");
if (_shopStorage.Sell(Model))
{
_logger.LogInformation("Продажа выполнена успешно");
return true;
}
_logger.LogInformation("Продажа не выполнена");
return false;
}
}
}

View File

@ -0,0 +1,193 @@
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.BusinessLogicContracts;
using AutoWorkshopContracts.BusinessLogicsContracts;
using AutoWorkshopContracts.SearchModels;
using AutoWorkshopContracts.ViewModels;
using AutoWorkshopDataModels.Enums;
using Microsoft.Extensions.Logging;
namespace AutoWorkshopBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> Logger)
{
_logger = Logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic ImplementerLogic, IOrderLogic OrderLogic)
{
_orderLogic = OrderLogic;
var Implementers = ImplementerLogic.ReadList(null);
if (Implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var Orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Accepted });
var BeingProcessedOrders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.BeingProcessed });
var WaitingOrders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Waiting });
if (Orders == null || BeingProcessedOrders == null || WaitingOrders == null)
{
_logger.LogWarning("DoWork. Orders are null");
return;
}
if (Orders.Count == 0 && BeingProcessedOrders.Count == 0 && WaitingOrders.Count == 0)
{
_logger.LogWarning("DoWork. No orders to process");
return;
}
_logger.LogDebug("DoWork for {Count} orders", Orders.Count);
foreach (var Implementer in Implementers)
{
Task.Run(() => WorkerWorkAsync(Implementer, Orders));
}
}
private async Task WorkerWorkAsync(ImplementerViewModel Implementer, List<OrderViewModel> Orders)
{
if (_orderLogic == null || Implementer == null)
{
return;
}
await RunWaitingOrders(Implementer);
await RunOrderInWork(Implementer);
await Task.Run(() =>
{
foreach (var Order in Orders)
{
try
{
_logger.LogDebug("WorkerWorkAsync. Worker {Id} try get order {Order}", Implementer.Id, Order.Id);
// TakeOrderInWork will fail when the worker tries to change status to BeingProcessed when the order is already BeingProcessed
// which would happen when other worker already acquired that order
bool AcquireResult = _orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = Order.Id,
ImplementerId = Implementer.Id
});
if (!AcquireResult)
{
_logger.LogDebug("WorkerWorkAsync. Worker {Id} tried to get order {Order} but it's already acquired by other worker", Implementer.Id, Order.Id);
continue;
}
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 1000) * Order.Count);
_logger.LogDebug("WorkerWorkAsync. Worker {Id} finish order {Order}", Implementer.Id, Order.Id);
_orderLogic.FinishOrder(new OrderBindingModel { Id = Order.Id });
_orderLogic.DeliveryOrder(new OrderBindingModel { Id = Order.Id });
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100));
}
});
}
private async Task RunOrderInWork(ImplementerViewModel Implementer)
{
if (_orderLogic == null || Implementer == null)
return;
try
{
var RunOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = Implementer.Id,
Status = OrderStatus.BeingProcessed
}));
if (RunOrder == null)
{
return;
}
_logger.LogDebug("RunOrderInWork. Worker {Id} back to order {Order}", Implementer.Id, RunOrder.Id);
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 300) * RunOrder.Count);
_logger.LogDebug("RunOrderInWork. Worker {Id} finish order {Order}", Implementer.Id, RunOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel { Id = RunOrder.Id });
_orderLogic.DeliveryOrder(new OrderBindingModel { Id = RunOrder.Id });
Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100));
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
private async Task RunWaitingOrders(ImplementerViewModel Implementer)
{
if (_orderLogic == null || Implementer == null)
return;
var WaitingOrders = await Task.Run(() => _orderLogic.ReadList(new OrderSearchModel
{
ImplementerId = Implementer.Id,
Status = OrderStatus.Waiting
}));
if (WaitingOrders == null || WaitingOrders.Count == 0)
{
return;
}
_logger.LogDebug("RunWaitingOrders for {Count} orders. Implementer: {id}.", WaitingOrders.Count, Implementer.Id);
foreach (var WaitingOrder in WaitingOrders)
{
try
{
_logger.LogInformation("RunWaitingOrders. Order {Order} delivery", WaitingOrder.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = WaitingOrder.Id
});
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, $"Error try deliver waiting order {WaitingOrder.Id}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error while delivering waiting order {WaitingOrder.Id}");
throw;
}
}
}
}
}

View File

@ -0,0 +1,165 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
public void CreateReport(ExcelRepairsInfo 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 RepComp in Info.RepairComponents)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = RepComp.RepairName,
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
foreach (var (Component, Count) in RepComp.Components)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = RowIndex,
Text = Component,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = Count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
RowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = RepComp.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
}
SaveExcel(Info);
}
public void CreateShopRepairsReport(ExcelShopsInfo 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 ShopRep in Info.ShopRepairs)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = ShopRep.ShopName,
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
foreach (var (Repair, Count) in ShopRep.Repairs)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = RowIndex,
Text = Repair,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = Count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
RowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = RowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = RowIndex,
Text = ShopRep.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
RowIndex++;
}
SaveExcel(Info);
}
protected abstract void CreateExcel(IDocumentInfo Info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters ExcelParams);
protected abstract void MergeCells(ExcelMergeParameters ExcelParams);
protected abstract void SaveExcel(IDocumentInfo Info);
}
}

View File

@ -0,0 +1,74 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfOrdersInfo 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.RepairName, 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);
}
public void CreateGroupedOrdersDoc(PdfGroupedOrdersInfo Info)
{
CreatePdf(Info);
CreateParagraph(new PdfParagraph { Text = Info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
CreateTable(new List<string> { "4cm", "3cm", "2cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Дата заказа", "Кол-во", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var groupedOrder in Info.GroupedOrders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { groupedOrder.Date.ToShortDateString(), groupedOrder.OrdersCount.ToString(), groupedOrder.OrdersSum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph { Text = $"Итого: {Info.GroupedOrders.Sum(x => x.OrdersSum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center });
SavePdf(Info);
}
protected abstract void CreatePdf(IDocumentInfo Info);
protected abstract void CreateParagraph(PdfParagraph Paragraph);
protected abstract void CreateTable(List<string> Columns);
protected abstract void CreateRow(PdfRowParameters RowParameters);
protected abstract void SavePdf(IDocumentInfo Info);
}
}

View File

@ -0,0 +1,93 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
namespace AutoWorkshopBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateRepairsDoc(WordRepairsInfo 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 Repair in Info.Repairs)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {
(Repair.RepairName, new WordTextProperties { Size = "24", Bold = true}),
("\t"+Repair.Price.ToString(), new WordTextProperties{Size = "24"})
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(Info);
}
public void CreateShopsDoc(WordShopsInfo Info)
{
CreateWord(Info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (Info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
CreateTable(new List<string> { "3000", "3000", "3000" });
CreateRow(new WordRowParameters
{
Texts = new List<string> { "Название", "Адрес", "Дата открытия" },
TextProperties = new WordTextProperties
{
Size = "24",
Bold = true,
JustificationType = WordJustificationType.Center
}
});
foreach (var Shop in Info.Shops)
{
CreateRow(new WordRowParameters
{
Texts = new List<string> { Shop.ShopName, Shop.Address, Shop.OpeningDate.ToString() },
TextProperties = new WordTextProperties
{
Size = "22",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(Info);
}
protected abstract void CreateWord(IDocumentInfo Info);
protected abstract void CreateParagraph(WordParagraph Paragraph);
protected abstract void SaveWord(IDocumentInfo Info);
protected abstract void CreateTable(List<string> Colums);
protected abstract void CreateRow(WordRowParameters RowParameters);
}
}

View File

@ -0,0 +1,9 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,9 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,8 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,17 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
namespace AutoWorkshopBusinessLogic.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,11 @@
namespace AutoWorkshopBusinessLogic.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,13 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class ExcelRepairsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportRepairComponentViewModel> RepairComponents { get; set; } = new();
}
}

View File

@ -0,0 +1,13 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class ExcelShopsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportShopsViewModel> ShopRepairs { get; set; } = new();
}
}

View File

@ -0,0 +1,9 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public interface IDocumentInfo
{
public string FileName { get; set; }
public string Title { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class PdfGroupedOrdersInfo : IDocumentInfo
{
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<ReportGroupedOrdersViewModel> GroupedOrders { get; set; } = new();
}
}

View File

@ -0,0 +1,17 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class PdfOrdersInfo : IDocumentInfo
{
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,13 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
namespace AutoWorkshopBusinessLogic.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,13 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
namespace AutoWorkshopBusinessLogic.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,9 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordRepairsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<RepairViewModel> Repairs { get; set; } = new();
}
}

View File

@ -0,0 +1,9 @@
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordRowParameters
{
public List<string> Texts { get; set; } = new();
public WordTextProperties TextProperties { get; set; } = new();
}
}

View File

@ -0,0 +1,13 @@
using AutoWorkshopContracts.ViewModels;
namespace AutoWorkshopBusinessLogic.OfficePackage.HelperModels
{
public class WordShopsInfo : IDocumentInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ShopViewModel> Shops { get; set; } = new();
}
}

View File

@ -0,0 +1,13 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
namespace AutoWorkshopBusinessLogic.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,281 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
{
public class SaveToExcel : AbstractSaveToExcel
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
private static void CreateStyles(WorkbookPart WorkbookPart)
{
var sp = WorkbookPart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var Fonts = new Fonts() { Count = 2U, KnownFonts = true };
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);
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);
}
private static uint GetStyleValue(ExcelStyleInfoType StyleInfo)
{
return StyleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBroder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(IDocumentInfo 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());
// Добавляем лист в книгу
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(IDocumentInfo Info)
{
if (_spreadsheetDocument == null)
return;
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Close();
}
}
}

View File

@ -0,0 +1,108 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
{
public class SaveToPdf : AbstractSaveToPdf
{
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(IDocumentInfo 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(IDocumentInfo Info)
{
var Renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
Renderer.RenderDocument();
Renderer.PdfDocument.Save(Info.FileName);
}
}
}

View File

@ -0,0 +1,192 @@
using AutoWorkshopBusinessLogic.OfficePackage.HelperEnums;
using AutoWorkshopBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace AutoWorkshopBusinessLogic.OfficePackage.Implements
{
public class SaveToWord : AbstractSaveToWord
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
private static JustificationValues GetJustificationValues(WordJustificationType Type)
{
return Type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
private static SectionProperties CreateSectionProperties()
{
var Properties = new SectionProperties();
var PageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
Properties.AppendChild(PageSize);
return Properties;
}
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(IDocumentInfo 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(IDocumentInfo Info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Close();
}
private Table? _lastTable;
protected override void CreateTable(List<string> Columns)
{
if (_docBody == null)
return;
_lastTable = new Table();
var TableProp = new TableProperties();
TableProp.AppendChild(new TableLayout { Type = TableLayoutValues.Fixed });
TableProp.AppendChild(new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 4 }
));
TableProp.AppendChild(new TableWidth { Type = TableWidthUnitValues.Auto });
_lastTable.AppendChild(TableProp);
TableGrid TableGrid = new TableGrid();
foreach (var Column in Columns)
{
TableGrid.AppendChild(new GridColumn() { Width = Column });
}
_lastTable.AppendChild(TableGrid);
_docBody.AppendChild(_lastTable);
}
protected override void CreateRow(WordRowParameters RowParameters)
{
if (_docBody == null || _lastTable == null)
return;
TableRow DocRow = new TableRow();
foreach (var Column in RowParameters.Texts)
{
var DocParagraph = new Paragraph();
WordParagraph Paragraph = new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (Column, RowParameters.TextProperties) },
TextProperties = RowParameters.TextProperties
};
DocParagraph.AppendChild(CreateParagraphProperties(Paragraph.TextProperties));
foreach (var Run in Paragraph.Texts)
{
var DocRun = new Run();
var Properties = new RunProperties();
Properties.AppendChild(new FontSize { Val = Run.Item2.Size });
if (Run.Item2.Bold)
{
Properties.AppendChild(new Bold());
}
DocRun.AppendChild(Properties);
DocRun.AppendChild(new Text { Text = Run.Item1, Space = SpaceProcessingModeValues.Preserve });
DocParagraph.AppendChild(DocRun);
}
TableCell docCell = new TableCell();
docCell.AppendChild(DocParagraph);
DocRow.AppendChild(docCell);
}
_lastTable.AppendChild(DocRow);
}
}
}

View File

@ -0,0 +1,49 @@
using AutoWorkshopContracts.ViewModels;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
namespace AutoWorkshopClientApp
{
public static class ApiClient
{
private static readonly HttpClient _client = new();
public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration Configuration)
{
_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);
}
}
}
}

View File

@ -0,0 +1,18 @@
<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="..\AutoWorkshopContracts\AutoWorkshopContracts.csproj" />
<ProjectReference Include="..\AutoWorkshopRestApi\AutoWorkshopRestApi.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,160 @@
using AutoWorkshopClientApp.Models;
using AutoWorkshopContracts.BindingModels;
using AutoWorkshopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace AutoWorkshopClientApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> Logger)
{
_logger = Logger;
}
public IActionResult Index()
{
if (ApiClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(ApiClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={ApiClient.Client.Id}"));
}
[HttpGet]
public IActionResult Privacy()
{
if (ApiClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(ApiClient.Client);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (ApiClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
ApiClient.PostRequest("api/client/updatedata", new ClientBindingModel
{
Id = ApiClient.Client.Id,
ClientFIO = fio,
Email = login,
Password = password
});
ApiClient.Client.ClientFIO = fio;
ApiClient.Client.Email = login;
ApiClient.Client.Password = password;
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
});
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
ApiClient.Client = ApiClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (ApiClient.Client == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
ApiClient.PostRequest("api/client/register", new ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Repairs = ApiClient.GetRequest<List<RepairViewModel>>("api/main/getrepairlist");
return View();
}
[HttpPost]
public void Create(int repair, int count)
{
if (ApiClient.Client == null)
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
if (count <= 0)
throw new Exception("Количество и сумма должны быть больше 0");
ApiClient.PostRequest("api/main/createorder", new OrderBindingModel
{
ClientId = ApiClient.Client.Id,
RepairId = repair,
Count = count,
Sum = Calc(count, repair)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int repair)
{
RepairViewModel? Repair = ApiClient.GetRequest<RepairViewModel>($"api/main/getrepair?repairId={repair}");
return count * (Repair?.Price ?? 1);
}
}
}

View File

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

View File

@ -0,0 +1,24 @@
using AutoWorkshopClientApp;
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();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:32797",
"sslPort": 44371
}
},
"profiles": {
"AutoWorkshopClientApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7145;http://localhost:5218",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,56 @@
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Ремонт:</div>
<div class="col-8">
<select id="repair" name="repair" class="form-control" asp-items="@(new SelectList(@ViewBag.Repairs,"Id", "RepairName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8">
<input type="text" name="count" id="count" />
</div>
</div>
<div class="row">
<div class="col-4">Сумма:</div>
<div class="col-8">
<input type="text" id="sum" name="sum" readonly />
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Создать" class="btn btn-primary" />
</div>
</div>
</form>
<script>
$('#repair').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var repair = $('#repair').val();
if (count && repair) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, repair: repair },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@ -0,0 +1,20 @@
@{
ViewData["Title"] = "Enter";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</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="Вход" class="btn btnprimary" /></div>
</div>
</form>

View File

@ -0,0 +1,69 @@
@using AutoWorkshopContracts.ViewModels
@model List<OrderViewModel>
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Create">Создать заказ</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Ремонт
</th>
<th>
Дата создания
</th>
<th>
Количество
</th>
<th>
Сумма
</th>
<th>
Статус
</th>
</tr>
</thead>
<tbody>
@foreach (var Item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => Item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => Item.RepairName)
</td>
<td>
@Html.DisplayFor(modelItem => Item.DateCreate)
</td>
<td>
@Html.DisplayFor(modelItem => Item.Count)
</td>
<td>
@Html.DisplayFor(modelItem => Item.Sum)
</td>
<td>
@Html.DisplayFor(modelItem => Item.Status)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,34 @@
@using AutoWorkshopContracts.ViewModels
@model ClientViewModel
@{
ViewData["Title"] = "Privacy Policy";
}
<div class="text-center">
<h2 class="display-4">Личные данные</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8">
<input type="text" name="login" value="@Model.Email"/>
</div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8">
<input type="password" name="password" value="@Model.Password"/>
</div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8">
<input type="text" name="fio" value="@Model.ClientFIO"/>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Сохранить" class="btn btn-primary" />
</div>
</div>
</form>

View File

@ -0,0 +1,28 @@
@{
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="fio" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Регистрация"
class="btn btn-primary" />
</div>
</div>
</form>

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,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - AutoWorkshopClientApp</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>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bgwhite border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" aspaction="Index">Магазин ремонтов</a>
<button class="navbar-toggler" type="button" datatoggle="collapse" data-target=".navbar-collapse" ariacontrols="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Index">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Register">Регистрация</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 - Магазин ремонтов - <a asp-area="" aspcontroller="Home" asp-action="Privacy">Личные данные</a>
</div>
</footer>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,49 @@
/* 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 AutoWorkshopClientApp
@using AutoWorkshopClientApp.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,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IPAddress": "http://localhost:5224"
}

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

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