6 Commits

Author SHA1 Message Date
6a3247660b done 2024-05-01 21:20:46 +04:00
90728871ce add RestApi 2024-05-01 20:47:30 +04:00
b748f3cc7a первый этап, добавили контракты и тд по клиенту 2024-05-01 20:37:47 +04:00
e49e1fbcb0 исправила orderstorage 2024-05-01 19:51:53 +04:00
93e910c83c done 2024-04-25 23:20:52 +04:00
d892eff496 done! 2024-03-29 21:44:42 +04:00
115 changed files with 5825 additions and 295 deletions

View File

@@ -13,7 +13,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MotorPlantBusinessLogic", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MotorPlantView", "..\MotorPlantView\MotorPlantView.csproj", "{76FE3E67-6BFC-4C12-AD2F-2267F8986605}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantFileImplement", "..\MotorPlantFileImplement\MotorPlantFileImplement.csproj", "{44BB8347-D6F7-4AD3-BC7D-E565CA02E0F8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MotorPlantFileImplement", "..\MotorPlantFileImplement\MotorPlantFileImplement.csproj", "{44BB8347-D6F7-4AD3-BC7D-E565CA02E0F8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MotorPlantDatabaseImplement", "MotorPlantDatabaseImplement\MotorPlantDatabaseImplement.csproj", "{4E5A0E78-08F9-4807-866C-4C7D50693C96}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantRestApi", "MotorPlantRestApi\MotorPlantRestApi.csproj", "{29E5B36D-7602-4EE5-96BB-A43FF9A49780}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantClientApi", "MotorPlantClientApi\MotorPlantClientApi.csproj", "{6F7A6389-1E4D-4F35-AE10-143EAA601F62}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -45,6 +51,18 @@ Global
{44BB8347-D6F7-4AD3-BC7D-E565CA02E0F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44BB8347-D6F7-4AD3-BC7D-E565CA02E0F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44BB8347-D6F7-4AD3-BC7D-E565CA02E0F8}.Release|Any CPU.Build.0 = Release|Any CPU
{4E5A0E78-08F9-4807-866C-4C7D50693C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E5A0E78-08F9-4807-866C-4C7D50693C96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E5A0E78-08F9-4807-866C-4C7D50693C96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E5A0E78-08F9-4807-866C-4C7D50693C96}.Release|Any CPU.Build.0 = Release|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.Build.0 = Release|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@ClientRestApi_HostAddress = http://localhost:5227
GET {{ClientRestApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace ClientRestApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@@ -0,0 +1,25 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:25213",
"sslPort": 44395
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5227",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7097;http://localhost:5227",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,13 @@
namespace ClientRestApi
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

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

View File

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

View File

@@ -0,0 +1,47 @@
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using MotorPlantContracts.ViewModels;
namespace MotorPlantClientApp
{
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,151 @@
using Microsoft.AspNetCore.Mvc;
using MotorPlantClientApp.Models;
using System.Diagnostics;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantContracts.VeiwModels;
namespace MotorPlantClientApp.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("<22><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD>");
}
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("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
APIClient.Client =
APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
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("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD>");
}
APIClient.PostRequest("api/client/register", new
ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Engines =
APIClient.GetRequest<List<EngineViewModel>>("api/main/getEnginelist");
return View();
}
[HttpPost]
public void Create(int Engine, int count)
{
if (APIClient.Client == null)
{
throw new Exception("<22><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
if (count <= 0)
{
throw new Exception("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0");
}
APIClient.PostRequest("api/main/createorder", new
OrderBindingModel
{
ClientId = APIClient.Client.Id,
EngineId = Engine,
Count = count,
Sum = Calc(count, Engine)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int Engine)
{
var _Engine =
APIClient.GetRequest<EngineViewModel>($"api/main/getEngine?Engineid={Engine}"
);
return Math.Round(count * (_Engine?.Price ?? 1), 2);
}
}
}

View File

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

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MotorPlantContracts\MotorPlantContracts.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@MotorPlantClientApi_HostAddress = http://localhost:5126
GET {{MotorPlantClientApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,31 @@
using MotorPlantClientApp;
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,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:44719",
"sslPort": 44341
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7006;http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,50 @@
@{
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="engine" name="engine" class="form-control" asp-items="@(new SelectList(@ViewBag.Engines,"Id", "EngineName"))"></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>
$('#engine').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var engine = $('#engine').val();
if (count && engine) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, engine: engine },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@@ -0,0 +1,21 @@
@{
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 btn-primary" /></div>
</div>
</form>

View File

@@ -0,0 +1,75 @@
@using MotorPlantContracts.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.EngineName)
</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,28 @@
@using MotorPlantContracts.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,25 @@
@{
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,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MotorPlantClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/MotorPlantClientApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MotorPlantClientApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" 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 - MotorPlantClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@@ -0,0 +1,48 @@
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,88 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using MotorPlantDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantDatabaseImplement.Implements
{
public class ClientStorage : IClientStorage
{
public List<ClientViewModel> GetFullList()
{
using var context = new MotorPlantDatabase();
return context.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) &&
string.IsNullOrEmpty(model.Password) &&
string.IsNullOrEmpty(model.ClientFIO))
{
return new();
}
using var context = new MotorPlantDatabase();
return context.Clients
.Where(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO.Contains(model.ClientFIO) &&
string.IsNullOrEmpty(model.Email) || x.ClientFIO.Contains(model.Email) &&
string.IsNullOrEmpty(model.Password) || x.ClientFIO.Contains(model.Password)))
.Select(x => x.GetViewModel)
.ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email) && string.IsNullOrEmpty(model.Password) && !model.Id.HasValue)
{
return null;
}
using var context = new MotorPlantDatabase();
return context.Clients.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && !string.IsNullOrEmpty(model.Password) && x.Password == model.Password) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
using var context = new MotorPlantDatabase();
context.Clients.Add(newClient);
context.SaveChanges();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
using var context = new MotorPlantDatabase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
context.SaveChanges();
return client.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
using var context = new MotorPlantDatabase();
var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Clients.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@@ -0,0 +1,84 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.VeiwModels;
using MotorPlantDatabaseImplement.Models;
namespace MotorPlantDatabaseImplement.Implements
{
public class ComponentStorage : IComponentStorage
{
public List<ComponentViewModel> GetFullList()
{
using var context = new MotorPlantDatabase();
return context.Components
.Select(x => x.GetViewModel)
.ToList();
}
public List<ComponentViewModel> GetFilteredList(ComponentSearchModel
model)
{
if (string.IsNullOrEmpty(model.ComponentName))
{
return new();
}
using var context = new MotorPlantDatabase();
return context.Components
.Where(x => x.ComponentName.Contains(model.ComponentName))
.Select(x => x.GetViewModel)
.ToList();
}
public ComponentViewModel? GetElement(ComponentSearchModel model)
{
if (string.IsNullOrEmpty(model.ComponentName) && !model.Id.HasValue)
{
return null;
}
using var context = new MotorPlantDatabase();
return context.Components
.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ComponentName) && x.ComponentName ==
model.ComponentName) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ComponentViewModel? Insert(ComponentBindingModel model)
{
var newComponent = Component.Create(model);
if (newComponent == null)
{
return null;
}
using var context = new MotorPlantDatabase();
context.Components.Add(newComponent);
context.SaveChanges();
return newComponent.GetViewModel;
}
public ComponentViewModel? Update(ComponentBindingModel model)
{
using var context = new MotorPlantDatabase();
var component = context.Components.FirstOrDefault(x => x.Id ==
model.Id);
if (component == null)
{
return null;
}
component.Update(model);
context.SaveChanges();
return component.GetViewModel;
}
public ComponentViewModel? Delete(ComponentBindingModel model)
{
using var context = new MotorPlantDatabase();
var element = context.Components.FirstOrDefault(rec => rec.Id ==
model.Id);
if (element != null)
{
context.Components.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@@ -0,0 +1,105 @@
using Microsoft.EntityFrameworkCore;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.VeiwModels;
using MotorPlantDatabaseImplement.Models;
namespace MotorPlantDatabaseImplement.Implements
{
public class EngineStorage : IEngineStorage
{
public List<EngineViewModel> GetFullList()
{
using var context = new MotorPlantDatabase();
return context.Engines
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<EngineViewModel> GetFilteredList(EngineSearchModel model)
{
if (string.IsNullOrEmpty(model.EngineName))
{
return new();
}
using var context = new MotorPlantDatabase();
return context.Engines
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.Where(x => x.EngineName.Contains(model.EngineName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public EngineViewModel? GetElement(EngineSearchModel model)
{
if (string.IsNullOrEmpty(model.EngineName) &&
!model.Id.HasValue)
{
return null;
}
using var context = new MotorPlantDatabase();
return context.Engines
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.EngineName) &&
x.EngineName == model.EngineName) ||
(model.Id.HasValue && x.Id ==
model.Id))
?.GetViewModel;
}
public EngineViewModel? Insert(EngineBindingModel model)
{
using var context = new MotorPlantDatabase();
var newEngine = Engine.Create(context, model);
if (newEngine == null)
{
return null;
}
context.Engines.Add(newEngine);
context.SaveChanges();
return newEngine.GetViewModel;
}
public EngineViewModel? Update(EngineBindingModel model)
{
using var context = new MotorPlantDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var engine = context.Engines.FirstOrDefault(rec =>
rec.Id == model.Id);
if (engine == null)
{
return null;
}
engine.Update(model);
context.SaveChanges();
engine.UpdateComponents(context, model);
transaction.Commit();
return engine.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public EngineViewModel? Delete(EngineBindingModel model)
{
using var context = new MotorPlantDatabase();
var element = context.Engines
.Include(x => x.Components)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Engines.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@@ -0,0 +1,86 @@
using Microsoft.EntityFrameworkCore;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.VeiwModels;
using MotorPlantDatabaseImplement.Models;
namespace MotorPlantDatabaseImplement.Implements
{
public class OrderStorage : IOrderStorage
{
public OrderViewModel? Delete(OrderBindingModel model)
{
using var context = new MotorPlantDatabase();
var element = context.Orders.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Orders.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return null;
}
using var context = new MotorPlantDatabase();
return context.Orders.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.DateFrom.HasValue)
{
return new();
}
using var context = new MotorPlantDatabase();
if (model.DateFrom.HasValue)
{
return context.Orders
.Include(x => x.Engine)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
}
return context.Orders
.Include(x => x.Engine)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
public List<OrderViewModel> GetFullList()
{
using var context = new MotorPlantDatabase();
return context.Orders.Select(x => x.GetViewModel).ToList();
}
public OrderViewModel? Insert(OrderBindingModel model)
{
var newOrder = Order.Create(model);
if (newOrder == null)
{
return null;
}
using var context = new MotorPlantDatabase();
context.Orders.Add(newOrder);
context.SaveChanges();
return newOrder.GetViewModel;
}
public OrderViewModel? Update(OrderBindingModel model)
{
using var context = new MotorPlantDatabase();
var order = context.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order == null)
{
return null;
}
order.Update(model);
context.SaveChanges();
return order.GetViewModel;
}
}
}

View File

@@ -0,0 +1,214 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MotorPlantDatabaseImplement;
#nullable disable
namespace MotorPlantDatabaseImplement.Migrations
{
[DbContext(typeof(MotorPlantDatabase))]
[Migration("20240501163500_Second")]
partial class Second
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("EngineName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Engines");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("EngineId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("EngineId");
b.ToTable("EngineComponents");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("EngineId")
.HasColumnType("int");
b.Property<string>("EngineName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EngineId");
b.ToTable("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component")
.WithMany("EngineComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany("Components")
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Client", null)
.WithMany("Orders")
.HasForeignKey("ClientId");
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany("Orders")
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("EngineComponents");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,66 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MotorPlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class Second : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ClientId",
table: "Orders",
type: "int",
nullable: true);
migrationBuilder.CreateTable(
name: "Clients",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ClientFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Clients", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.AddForeignKey(
name: "FK_Orders_Clients_ClientId",
table: "Orders",
column: "ClientId",
principalTable: "Clients",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Clients_ClientId",
table: "Orders");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropIndex(
name: "IX_Orders_ClientId",
table: "Orders");
migrationBuilder.DropColumn(
name: "ClientId",
table: "Orders");
}
}
}

View File

@@ -0,0 +1,211 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MotorPlantDatabaseImplement;
#nullable disable
namespace MotorPlantDatabaseImplement.Migrations
{
[DbContext(typeof(MotorPlantDatabase))]
partial class MotorPlantDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("EngineName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Engines");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("EngineId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("EngineId");
b.ToTable("EngineComponents");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("EngineId")
.HasColumnType("int");
b.Property<string>("EngineName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("EngineId");
b.ToTable("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.EngineComponent", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Component", "Component")
.WithMany("EngineComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany("Components")
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("MotorPlantDatabaseImplement.Models.Client", null)
.WithMany("Orders")
.HasForeignKey("ClientId");
b.HasOne("MotorPlantDatabaseImplement.Models.Engine", "Engine")
.WithMany("Orders")
.HasForeignKey("EngineId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Engine");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("EngineComponents");
});
modelBuilder.Entity("MotorPlantDatabaseImplement.Models.Engine", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,67 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantDatabaseImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
[Required]
public string ClientFIO { get; set; } = string.Empty;
[Required]
public string Email { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public static Client Create(ClientViewModel model)
{
return new Client
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
}
}

View File

@@ -0,0 +1,56 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.VeiwModels;
using MotorPlantDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MotorPlantDatabaseImplement.Models
{
public class Component : IComponentModel
{
public int Id { get; private set; }
[Required]
public string ComponentName { get; private set; } = string.Empty;
[Required]
public double Cost { get; set; }
[ForeignKey("ComponentId")]
public virtual List<EngineComponent> EngineComponents { get; set; } = new();
public static Component? Create(ComponentBindingModel model)
{
if (model == null)
{
return null;
}
return new Component()
{
Id = model.Id,
ComponentName = model.ComponentName,
Cost = model.Cost
};
}
public static Component Create(ComponentViewModel model)
{
return new Component
{
Id = model.Id,
ComponentName = model.ComponentName,
Cost = model.Cost
};
}
public void Update(ComponentBindingModel model)
{
if (model == null)
{
return;
}
ComponentName = model.ComponentName;
Cost = model.Cost;
}
public ComponentViewModel GetViewModel => new()
{
Id = Id,
ComponentName = ComponentName,
Cost = Cost
};
}
}

View File

@@ -0,0 +1,92 @@
using MotorPlantDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using MotorPlantContracts.VeiwModels;
using MotorPlantContracts.BindingModels;
namespace MotorPlantDatabaseImplement.Models
{
public class Engine : IEngineModel
{
public int Id { get; set; }
[Required]
public string EngineName { get; set; } = string.Empty;
[Required]
public double Price { get; set; }
private Dictionary<int, (IComponentModel, int)>? _engineComponents = null;
[NotMapped]
public Dictionary<int, (IComponentModel, int)> EngineComponents
{
get
{
if (_engineComponents == null)
{
_engineComponents = Components
.ToDictionary(recPC => recPC.ComponentId, recPC =>
(recPC.Component as IComponentModel, recPC.Count));
}
return _engineComponents;
}
}
[ForeignKey("EngineId")]
public virtual List<EngineComponent> Components { get; set; } = new();
[ForeignKey("EngineId")]
public virtual List<Order> Orders { get; set; } = new();
public static Engine Create(MotorPlantDatabase context, EngineBindingModel model)
{
return new Engine()
{
Id = model.Id,
EngineName = model.EngineName,
Price = model.Price,
Components = model.EngineComponents.Select(x => new EngineComponent
{
Component = context.Components.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(EngineBindingModel model)
{
EngineName = model.EngineName;
Price = model.Price;
}
public EngineViewModel GetViewModel => new()
{
Id = Id,
EngineName = EngineName,
Price = Price,
EngineComponents = EngineComponents
};
public void UpdateComponents(MotorPlantDatabase context, EngineBindingModel model)
{
var engineComponents = context.EngineComponents.Where(rec => rec.EngineId == model.Id).ToList();
if (engineComponents != null && engineComponents.Count > 0)
{ // удалили те, которых нет в модели
context.EngineComponents.RemoveRange(engineComponents.Where(rec
=> !model.EngineComponents.ContainsKey(rec.ComponentId)));
context.SaveChanges();
// обновили количество у существующих записей
foreach (var updateComponent in engineComponents)
{
updateComponent.Count =
model.EngineComponents[updateComponent.ComponentId].Item2;
model.EngineComponents.Remove(updateComponent.ComponentId);
}
context.SaveChanges();
}
var engine = context.Engines.First(x => x.Id == Id);
foreach (var pc in model.EngineComponents)
{
context.EngineComponents.Add(new EngineComponent
{
Engine = engine,
Component = context.Components.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_engineComponents = null;
}
}
}

View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace MotorPlantDatabaseImplement.Models
{
public class EngineComponent
{
public int Id { get; set; }
[Required]
public int EngineId { get; set; }
[Required]
public int ComponentId { get; set; }
[Required]
public int Count { get; set; }
public virtual Component Component { get; set; } = new();
public virtual Engine Engine { get; set; } = new();
}
}

View File

@@ -0,0 +1,68 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.VeiwModels;
using MotorPlantDataModels.Enums;
using MotorPlantDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace MotorPlantDatabaseImplement.Models
{
public class Order : IOrderModel
{
public int Id { get; private set; }
public int EngineId { get; private set; }
public string EngineName { get; private set; } = string.Empty;
[Required]
public int Count { get; private set; }
[Required]
public double Sum { get; private set; }
[Required]
public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
[Required]
public DateTime DateCreate { get; private set; } = DateTime.Now;
public DateTime? DateImplement { get; private set; }
public virtual Engine Engine { get; set; }
public static Order? Create(OrderBindingModel? model)
{
if (model == null)
{
return null;
}
return new Order()
{
Id = model.Id,
EngineId = model.EngineId,
EngineName = model.EngineName,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
DateCreate = model.DateCreate,
DateImplement = model.DateImplement
};
}
public void Update(OrderBindingModel? model)
{
if (model == null)
{
return;
}
EngineId = model.EngineId;
EngineName = model.EngineName;
Count = model.Count;
Sum = model.Sum;
Status = model.Status;
DateCreate = model.DateCreate;
DateImplement = model.DateImplement;
}
public OrderViewModel GetViewModel => new()
{
Id = Id,
EngineId = EngineId,
EngineName = EngineName,
Count = Count,
Sum = Sum,
Status = Status,
DateCreate = DateCreate,
DateImplement = DateImplement
};
}
}

View File

@@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore;
using MotorPlantDatabaseImplement.Models;
namespace MotorPlantDatabaseImplement
{
public class MotorPlantDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseSqlServer(@"Data Source=WIN-QKNE49D1RUQ\SQLEXPRESS;Initial Catalog=MotorPlantDatabaseeses;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
public virtual DbSet<Component> Components { set; get; }
public virtual DbSet<Engine> Engines { set; get; }
public virtual DbSet<EngineComponent> EngineComponents { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
}
}

View File

@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MotorPlantContracts\MotorPlantContracts.csproj" />
<ProjectReference Include="..\..\MotorPlantDataModels\MotorPlantDataModels.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,64 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace MotorPlantRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ClientController : Controller
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController>
logger)
{
_logger = logger;
_logic = logic;
}
[HttpGet]
public ClientViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ClientSearchModel
{
Email = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
throw;
}
}
[HttpPost]
public void Register(ClientBindingModel model)
{
try
{
_logic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
throw;
}
}
[HttpPost]
public void UpdateData(ClientBindingModel model)
{
try
{
_logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
}
}

View File

@@ -0,0 +1,85 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantContracts.SearchModels;
using Microsoft.AspNetCore.Mvc;
using MotorPlantContracts.VeiwModels;
namespace MotorPlantRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class MainController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IEngineLogic _Engine;
public MainController(ILogger<MainController> logger, IOrderLogic order,
IEngineLogic Engine)
{
_logger = logger;
_order = order;
_Engine = Engine;
}
[HttpGet]
public List<EngineViewModel>? GetEngineList()
{
try
{
return _Engine.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка мороженного");
throw;
}
}
[HttpGet]
public EngineViewModel? GetEngine(int EngineId)
{
try
{
return _Engine.ReadElement(new EngineSearchModel
{
Id =
EngineId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения продукта по id={Id}",
EngineId);
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetOrders(int clientId)
{
try
{
return _order.ReadList(new OrderSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка заказов клиента id ={ Id}", clientId);
throw;
}
}
[HttpPost]
public void CreateOrder(OrderBindingModel model)
{
try
{
_order.CreateOrder(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа");
throw;
}
}
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.17" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MotorPlantBusinessLogic\MotorPlantBusinessLogic.csproj" />
<ProjectReference Include="..\MotorPlantDatabaseImplement\MotorPlantDatabaseImplement.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
@MotorPlantRestApi_HostAddress = http://localhost:5167
GET {{MotorPlantRestApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@@ -0,0 +1,43 @@
using MotorPlantBusinessLogic.BusinessLogic;
using MotorPlantBusinessLogic.BusinessLogics;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantContracts.StoragesContracts;
using MotorPlantDatabaseImplement.Implements;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config");
// Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IEngineStorage, EngineStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IEngineLogic, EngineLogic>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at
https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "EngineCompanyRestApi",
Version
= "v1"
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
"EngineCompanyRestApi v1"));
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59420",
"sslPort": 44364
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5167",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7267;http://localhost:5167",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/MotorPlantRestApi.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
<root>
<level value="TRACE" />
<appender-ref ref="RollingFile" />
</root>
</log4net>

View File

@@ -7,6 +7,8 @@ namespace MotorPlantListImplement
public List<Component> Components { get; set; }
public List<Order> Orders { get; set; }
public List<Engine> Engines { get; set; }
public List<Client> Clients { get; set; }
private DataListSingleton()
{
Components = new List<Component>();

View File

@@ -0,0 +1,99 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using MotorPlantListImplement.Models;
namespace MotorPlantListImplement.Implements
{
public class ClientStorage : IClientStorage
{
private readonly DataListSingleton _source;
public ClientStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ClientViewModel> GetFullList()
{
var result = new List<ClientViewModel>();
foreach (var client in _source.Clients)
{
result.Add(client.GetViewModel);
}
return result;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel
model)
{
var result = new List<ClientViewModel>();
if (string.IsNullOrEmpty(model.ClientFIO) && string.IsNullOrEmpty(model.Email) && string.IsNullOrEmpty(model.Password))
{
return result;
}
foreach (var client in _source.Clients)
{
if (client.ClientFIO.Contains(model.ClientFIO))
{
result.Add(client.GetViewModel);
}
}
return result;
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
foreach (var client in _source.Clients)
{
if ((string.IsNullOrEmpty(model.ClientFIO) || client.ClientFIO == model.ClientFIO) &&
(!model.Id.HasValue || client.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || client.Email == model.Email) &&
(string.IsNullOrEmpty(model.Password) || client.Password == model.Password))
{
return client.GetViewModel;
}
}
return null;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
model.Id = 1;
foreach (var client in _source.Clients)
{
if (model.Id <= client.Id)
{
model.Id = client.Id + 1;
}
}
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
_source.Clients.Add(newClient);
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
foreach (var client in _source.Clients)
{
if (client.Id == model.Id)
{
client.Update(model);
return client.GetViewModel;
}
}
return null;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
for (int i = 0; i < _source.Clients.Count; ++i)
{
if (_source.Clients[i].Id == model.Id)
{
var element = _source.Clients[i];
_source.Clients.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
}
}

View File

@@ -43,20 +43,35 @@ namespace MotorPlantListImplement.Implements
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
var result = new List<OrderViewModel>();
if (!model.Id.HasValue)
if (model == null || !model.Id.HasValue)
{
return result;
}
if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
{
return result;
}
foreach (var order in _source.Orders)
{
if (model.Id.HasValue && order.Id == model.Id)
if (order.Id == model.Id || (model.DateFrom <= order.DateCreate && order.DateCreate <= model.DateTo))
{
result.Add(order.GetViewModel);
result.Add(AttachEngineName(order.GetViewModel));
}
}
return result;
}
private OrderViewModel AttachEngineName(OrderViewModel model)
{
foreach (var Engine in _source.Engines)
{
if (Engine.Id == model.EngineId)
{
model.EngineName = Engine.EngineName;
return model;
}
}
return model;
}
public List<OrderViewModel> GetFullList()
{
var result = new List<OrderViewModel>();

View File

@@ -0,0 +1,52 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantListImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
}
}

View File

@@ -0,0 +1,121 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace MotorPlantBusinessLogic.BusinessLogic
{
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage
componentStorage)
{
_logger = logger;
_clientStorage = componentStorage;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. ClientId:{Id}", 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);
var element = _clientStorage.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(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)
{
return;
}
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);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email,
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким лоигном уже есть");
}
}
}
}

View File

@@ -0,0 +1,83 @@
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
using MotorPlantBusinessLogic.OfficePackage;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
namespace MotorPlantBusinessLogic
{
public class ReportLogic : IReportLogic
{
private readonly IComponentStorage _componentStorage;
private readonly IEngineStorage _EngineStorage;
private readonly IOrderStorage _orderStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IEngineStorage EngineStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
{
_EngineStorage = EngineStorage;
_componentStorage = componentStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
public List<ReportEngineComponentViewModel> GetEngineComponents()
{
return _EngineStorage.GetFullList().Select(x => new ReportEngineComponentViewModel
{
EngineName = x.EngineName,
Components = x.EngineComponents.Select(x => (x.Value.Item1.ComponentName, x.Value.Item2)).ToList(),
TotalCount = x.EngineComponents.Select(x => x.Value.Item2).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,
EngineName = x.EngineName,
Sum = x.Sum,
Status = x.Status.ToString(),
})
.ToList();
}
public void SaveEnginesToWordFile(ReportBindingModel model)
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список двигателей",
Engines = _EngineStorage.GetFullList()
});
}
public void SaveEngineComponentToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список компонентов",
EngineComponents = GetEngineComponents()
});
}
public void SaveOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список заказов",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Orders = GetOrders(model)
});
}
}
}

View File

@@ -7,11 +7,20 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PDFsharp-MigraDoc-GDI" Version="1.50.5147" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MotorPlantContracts\MotorPlantContracts.csproj" />
<ProjectReference Include="..\MotorPlantContracts\MotorPlantContracts.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,77 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
public void CreateReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var pc in info.EngineComponents)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = pc.EngineName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var Engine in pc.Components)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = Engine.Item1,
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = Engine.Item2.ToString(),
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = pc.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
protected abstract void CreateExcel(ExcelInfo info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters
excelParams);
protected abstract void MergeCells(ExcelMergeParameters excelParams);
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@@ -0,0 +1,52 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfInfo 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", "4cm" });
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.EngineName, order.Sum.ToString(), order.Status },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Right
});
SavePdf(info);
}
protected abstract void CreatePdf(PdfInfo info);
protected abstract void CreateParagraph(PdfParagraph paragraph);
protected abstract void CreateTable(List<string> columns);
protected abstract void CreateRow(PdfRowParameters rowParameters);
protected abstract void SavePdf(PdfInfo info);
}
}

View File

@@ -0,0 +1,49 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateDoc(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new
WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var component in info.Engines)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)>
{
(component.EngineName, new WordTextProperties { Size = "24", Bold = true}),
("\t" + component.Price.ToString(), new WordTextProperties { Size = "24"}),
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(info);
}
protected abstract void CreateWord(WordInfo info);
protected abstract void CreateParagraph(WordParagraph paragraph);
protected abstract void SaveWord(WordInfo info);
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,12 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
namespace MotorPlantBusinessLogic.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,15 @@
using MotorPlantContracts.ViewModels;
namespace MotorPlantBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportEngineComponentViewModel> EngineComponents
{
get;
set;
} = new();
}
}

View File

@@ -0,0 +1,9 @@
namespace MotorPlantBusinessLogic.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,12 @@
using MotorPlantContracts.ViewModels;
namespace MotorPlantBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfo
{
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,10 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
namespace MotorPlantBusinessLogic.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,10 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
namespace MotorPlantBusinessLogic.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,10 @@
using MotorPlantContracts.VeiwModels;
namespace MotorPlantBusinessLogic.OfficePackage.HelperModels
{
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<EngineViewModel> Engines { get; set; } = new();
}
}

View File

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

View File

@@ -0,0 +1,10 @@
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
namespace MotorPlantBusinessLogic.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,331 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.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(ExcelInfo 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>();
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(ExcelInfo info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Dispose();
}
}
}

View File

@@ -0,0 +1,97 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.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.Right => 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(PdfInfo 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(PdfInfo info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@@ -0,0 +1,97 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using MotorPlantBusinessLogic.OfficePackage.HelperEnums;
using MotorPlantBusinessLogic.OfficePackage.HelperModels;
namespace MotorPlantBusinessLogic.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(WordInfo 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(WordInfo info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Dispose();
}
}
}

View File

@@ -0,0 +1,12 @@
using MotorPlantDataModels.Models;
namespace MotorPlantContracts.BindingModels
{
public class ClientBindingModel : IClientModel
{
public int Id { get; set; }
public string ClientFIO { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
}

View File

@@ -7,6 +7,7 @@ namespace MotorPlantContracts.BindingModels
{
public int Id { get; set; }
public int EngineId { get; set; }
public int ClientId { get; set; }
public string EngineName { get; set; } = string.Empty;
public int Count { get; set; }
public double Sum { get; set; }

View File

@@ -0,0 +1,9 @@
namespace MotorPlantContracts.BindingModels
{
public class ReportBindingModel
{
public string FileName { get; set; } = string.Empty;
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantContracts.SearchModels;
namespace MotorPlantContracts.BusinessLogicsContracts
{
public interface IClientLogic
{
List<ClientViewModel>? ReadList(ClientSearchModel? model);
ClientViewModel? ReadElement(ClientSearchModel model);
bool Create(ClientBindingModel model);
bool Update(ClientBindingModel model);
bool Delete(ClientBindingModel model);
}
}

View File

@@ -0,0 +1,13 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
namespace MotorPlantContracts.BusinessLogicsContracts
{
public interface IReportLogic
{
List<ReportEngineComponentViewModel> GetEngineComponents();
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
void SaveEnginesToWordFile(ReportBindingModel model);
void SaveEngineComponentToExcelFile(ReportBindingModel model);
void SaveOrdersToPdfFile(ReportBindingModel model);
}
}

View File

@@ -6,6 +6,15 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MotorPlantDataModels\MotorPlantDataModels.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,10 @@
namespace MotorPlantContracts.SearchModels
{
public class ClientSearchModel
{
public int? Id { get; set; }
public string? ClientFIO { get; set; }
public string? Email { get; set; }
public string? Password { get; set; }
}
}

View File

@@ -3,5 +3,8 @@
public class OrderSearchModel
{
public int? Id { get; set; }
public int? ClientId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.ViewModels;
namespace MotorPlantContracts.StoragesContracts
{
public interface IClientStorage
{
List<ClientViewModel> GetFullList();
List<ClientViewModel> GetFilteredList(ClientSearchModel model);
ClientViewModel? GetElement(ClientSearchModel model);
ClientViewModel? Insert(ClientBindingModel model);
ClientViewModel? Update(ClientBindingModel model);
ClientViewModel? Delete(ClientBindingModel model);
}
}

View File

@@ -0,0 +1,16 @@
using MotorPlantDataModels.Models;
using System.ComponentModel;
namespace MotorPlantContracts.ViewModels
{
public class ClientViewModel : IClientModel
{
public int Id { get; set; }
[DisplayName("ФИО клиента")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Логин (эл. почта)")]
public string Email { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
}
}

View File

@@ -5,29 +5,24 @@ namespace MotorPlantContracts.VeiwModels
{
public class OrderViewModel : IOrderModel
{
[DisplayName("Номер")]
public int Id { get; set; }
public int EngineId { get; set; }
[DisplayName("Изделие")]
public string EngineName { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
}
}
[DisplayName("Номер")]
public int Id { get; set; }
public int EngineId { get; set; }
public int ClientId { get; set; }
[DisplayName("Клиент")]
public string ClientFIO { get; set; } = string.Empty;
[DisplayName("Двигатель")]
public string EngineName { get; set; } = string.Empty;
[DisplayName("Количество")]
public int Count { get; set; }
[DisplayName("Сумма")]
public double Sum { get; set; }
[DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Дата создания")]
public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace MotorPlantContracts.ViewModels
{
public class ReportEngineComponentViewModel
{
public string EngineName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<(string Component, int Count)> Components { get; set; } = new();
}
}

View File

@@ -0,0 +1,11 @@
namespace MotorPlantContracts.ViewModels
{
public class ReportOrdersViewModel
{
public int Id { get; set; }
public DateTime DateCreate { get; set; }
public string EngineName { get; set; } = string.Empty;
public double Sum { get; set; }
public string Status { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantDataModels.Models
{
public interface IClientModel : IId
{
string ClientFIO { get; }
string Email { get; }
string Password { get; }
}
}

View File

@@ -5,5 +5,13 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
</ItemGroup>
</Project>

View File

@@ -8,9 +8,13 @@ namespace MotorPlantFileImplement
private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml";
private readonly string EngineFileName = "Engine.xml";
private readonly string ClientFileName = "Client.xml";
public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; }
public List<Engine> Engines { get; private set; }
public List<Client> Clients { get; private set; }
public static DataFileSingleton GetInstance()
{
@@ -23,6 +27,8 @@ namespace MotorPlantFileImplement
public void SaveComponents() => SaveData(Components, ComponentFileName, "Components", x => x.GetXElement);
public void SaveEngines() => SaveData(Engines, EngineFileName, "Engines", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;

View File

@@ -0,0 +1,82 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using MotorPlantFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MotorPlantFileImplement.Implements
{
public class ClientStorage : IClientStorage
{
private readonly DataFileSingleton source;
public ClientStorage()
{
source = DataFileSingleton.GetInstance();
}
public List<ClientViewModel> GetFullList()
{
return source.Clients
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email))
{
return new();
}
return source.Clients.Where(x => x.Email.Contains(model.Email)).Select(x => x.GetViewModel).ToList();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue)
{
return null;
}
return source.Clients
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) ||
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ClientViewModel? Insert(ClientBindingModel model)
{
model.Id = source.Clients.Count > 0 ? source.Clients.Max(x => x.Id) + 1 : 1;
var newClient = Client.Create(model);
if (newClient == null)
{
return null;
}
source.Clients.Add(newClient);
source.SaveClients();
return newClient.GetViewModel;
}
public ClientViewModel? Update(ClientBindingModel model)
{
var ingredient = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (ingredient == null)
{
return null;
}
ingredient.Update(model);
source.SaveClients();
return ingredient.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
var element = source.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
source.Clients.Remove(element);
source.SaveClients();
return element.GetViewModel;
}
return null;
}
}
}

View File

@@ -12,23 +12,32 @@ namespace MotorPlantFileImplement.Implements
{
source = DataFileSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList() => source.Orders.Select(x => AttachEngineName(x.GetViewModel)).ToList();
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
}
return source.Orders.Where(x => x.Id == model.Id).Select(x => AttachEngineName(x.GetViewModel)).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
return new();
return null;
}
return AttachEngineName(source.Orders.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel);
return GetViewModel(source.Orders.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id));
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue)
{
if (!model.Id.HasValue && !model.DateFrom.HasValue || !model.DateTo.HasValue)
{
return new();
}
return source.Orders.Where(x => x.Id == model.Id).Select(x => GetViewModel(x)).ToList();
}
return source.Orders
.Where(x => x.Id == model.Id || (model.DateTo >= x.DateCreate && model.DateFrom <= x.DateCreate))
.Select(x => GetViewModel(x))
.ToList();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => GetViewModel(x)).ToList();
}
public OrderViewModel? Insert(OrderBindingModel model)
{
@@ -40,7 +49,7 @@ namespace MotorPlantFileImplement.Implements
}
source.Orders.Add(newOrder);
source.SaveOrders();
return AttachEngineName(newOrder.GetViewModel);
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
@@ -51,31 +60,25 @@ namespace MotorPlantFileImplement.Implements
}
order.Update(model);
source.SaveOrders();
return AttachEngineName(order.GetViewModel);
return GetViewModel(order);
}
public OrderViewModel? Delete(OrderBindingModel model)
{
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (order != null)
{
source.Orders.Remove(order);
source.SaveOrders();
return AttachEngineName(order.GetViewModel);
}
return null;
}
private OrderViewModel? AttachEngineName(OrderViewModel? model)
{
if (model == null)
if (order == null)
{
return null;
}
var engine = source.Engines.FirstOrDefault(x => x.Id == model.EngineId);
if (engine != null)
{
model.EngineName = engine.EngineName;
}
return model;
order.Update(model);
source.SaveOrders();
return GetViewModel(order);
}
private OrderViewModel GetViewModel(Order order)
{
var viewModel = order.GetViewModel;
var engine = source.Engines.FirstOrDefault(x => x.Id == order.EngineId);
viewModel.EngineName = engine?.EngineName;
return viewModel;
}
}
}
}

View File

@@ -0,0 +1,73 @@
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace MotorPlantFileImplement.Models
{
public class Client : IClientModel
{
public int Id { get; private set; }
public string ClientFIO { get; private set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{
return null;
}
return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public static Client? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Client()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ClientFIO = element.Element("ClientFIO")!.Value,
Email = element.Element("Email")!.Value,
Password = element.Element("Password")!.Value
};
}
public void Update(ClientBindingModel model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
}
public ClientViewModel GetViewModel => new()
{
Id = Id,
ClientFIO = ClientFIO,
Email = Email,
Password = Password
};
public XElement GetXElement => new("Client",
new XAttribute("Id", Id),
new XElement("ClientFIO", ClientFIO),
new XElement("Email", Email.ToString()),
new XElement("Password", Password.ToString())
);
}
}

74
MotorPlantView/FormClients.Designer.cs generated Normal file
View File

@@ -0,0 +1,74 @@
namespace MotorPlantView.Forms
{
partial class FormClients
{
/// <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()
{
DataGridView = new DataGridView();
DeleteButton = new Button();
((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit();
SuspendLayout();
//
// DataGridView
//
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Location = new Point(12, 34);
DataGridView.Name = "DataGridView";
DataGridView.RowTemplate.Height = 25;
DataGridView.Size = new Size(776, 404);
DataGridView.TabIndex = 0;
//
// DeleteButton
//
DeleteButton.Location = new Point(12, 5);
DeleteButton.Name = "DeleteButton";
DeleteButton.Size = new Size(123, 23);
DeleteButton.TabIndex = 1;
DeleteButton.Text = "Удалить";
DeleteButton.UseVisualStyleBackColor = true;
DeleteButton.Click += DeleteButton_Click;
//
// ClientsForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(DeleteButton);
Controls.Add(DataGridView);
Name = "ClientsForm";
Text = "Клиенты";
Load += ClientsForm_Load;
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView DataGridView;
private Button DeleteButton;
}
}

View File

@@ -0,0 +1,74 @@
using Microsoft.Extensions.Logging;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using System.Windows.Forms;
namespace MotorPlantView.Forms
{
public partial class FormClients : Form
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public FormClients(ILogger<FormClients> logger, IClientLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
DataGridView.DataSource = list;
DataGridView.Columns["Id"].Visible = false;
DataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка клиентов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки клиентов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ClientsForm_Load(object sender, EventArgs e)
{
LoadData();
}
private void DeleteButton_Click(object sender, EventArgs e)
{
if (DataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id =
Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление клиента");
try
{
if (!_logic.Delete(new ClientBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления компонента");
MessageBox.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantView.Forms;
namespace MotorPlantView
{
public partial class FormComponents : Form

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