PIbd-22_Gerimovich.I.M._Furniture_Assembly_LabWork5base #8

Closed
Gerimovich_Ilya wants to merge 5 commits from lab5base into lab4base
39 changed files with 1188 additions and 459 deletions
Showing only changes of commit b724bcb977 - Show all commits

View File

@ -15,6 +15,7 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
public class ClientLogic : IClientLogic
{
private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
@ -23,27 +24,21 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
_clientStorage = clientStorage;
}
public bool Create(ClientBindingModel model)
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
_logger.LogInformation("ReadList. Email:{Email}. Id:{Id}", model?.Email, model?.Id);
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_clientStorage.Delete(model) == null)
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("Delete operation failed");
return false;
_logger.LogWarning("ReadList return null list");
return null;
}
return true;
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
@ -52,38 +47,64 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Email: {Email} Id:{ Id}", model.Email, model.Id);
_logger.LogInformation("ReadList. Email:{Email}. Id:{Id}", model.Email, 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);
_logger.LogInformation("ReadElement find .Id:{Id}", element.Id);
return element;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
public bool Create(ClientBindingModel model)
{
_logger.LogInformation("ReadList. Email: {Email}. Id:{ Id}", model?.Email, model?.Id);
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("ReadList return null list");
return null;
_logger.LogWarning("Insert operation failed");
return false;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
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;
}
@ -99,24 +120,27 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет ФИО пользователя",
nameof(model.ClientFIO));
throw new ArgumentNullException("Отсутствие ФИО в учётной записи", nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет почтового адреса пользователя",
nameof(model.Email));
throw new ArgumentNullException("Отсутствие эл. почты в учётной записи (логина)", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля пользователя",
nameof(model.Password));
throw new ArgumentNullException("Отсутствие пароля в учётной записи", nameof(model.Password));
}
_logger.LogInformation("Component. ClientFIO:{ClientFIO}. Email:{ Email}. Id: { Id}", model.ClientFIO, model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel { Email = model.Email });
_logger.LogInformation("Client. ClientFIO:{ClientFIO}. Email:{Email}. Id:{Id} ", model.ClientFIO, model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Пользователь с таким логином уже есть");
throw new InvalidOperationException("Аккаунт с таким логином уже есть");
}
}
}

View File

@ -15,21 +15,23 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
public class OrderLogic : IOrderLogic
{
private readonly IOrderStorage _orderStorage;
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if(list == null)
if (list == null)
{
_logger.LogWarning("ReadList return null list");
@ -40,11 +42,12 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if(model.Status != OrderStatus.Неизвестен)
if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Insert operation failed, incorrect order status");
return false;
@ -52,7 +55,7 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
model.Status = OrderStatus.Принят;
if(_orderStorage.Insert(model) == null)
if (_orderStorage.Insert(model) == null)
{
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed");
@ -76,62 +79,61 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
{
return StatusUpdate(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
// Проверка на наличие товаров в заказе
if(model.Count <= 0)
if (model.Count <= 0)
{
throw new ArgumentNullException("В заказе не может быть 0 изделий", nameof(model.Count));
}
// Проверка на наличие нормальной суммарной стоимости чека
if(model.Sum <= 0)
if (model.Sum <= 0)
{
throw new ArgumentNullException("Суммарная стоимость заказа должна быть больше 0", nameof(model.Sum));
}
// Проверка корректности id у изделий
if(model.FurnitureId < 0)
if (model.FurnitureId < 0)
{
throw new ArgumentNullException("Некорректный id у изделия", nameof(model.FurnitureId));
}
// Проверка корректности дат
if(model.DateCreate > model.DateImplement)
if (model.DateCreate > model.DateImplement)
{
throw new InvalidOperationException("Дата создания должна быть более ранней, нежели дата завершения");
}
if (model.ClientId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор у клиента", nameof(model.ClientId));
}
_logger.LogInformation("Order. OrderId:{Id}, Sum:{Sum}. FurnitureId:{Id}", model.Id, model.Sum, model.FurnitureId);
_logger.LogInformation("Order. OrderId:{Id}. Sum:{Sum}. ClientId:{ClientId}. FurnitureId:{Id}", model.Id, model.Sum, model.ClientId, model.FurnitureId);
}
public bool StatusUpdate(OrderBindingModel model, OrderStatus newOrderStatus)
{
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if(viewModel == null)
if (viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
if(viewModel.Status + 1 != newOrderStatus)
if (viewModel.Status + 1 != newOrderStatus)
{
_logger.LogWarning("Status update operation failed. Status " + newOrderStatus.ToString() + "incorrect");
_logger.LogWarning("Status update operation failed. New status " + newOrderStatus.ToString() + "incorrect");
return false;
}
model.Status = newOrderStatus;
if(model.Status == OrderStatus.Выдан)
if (model.Status == OrderStatus.Выдан)
{
model.DateImplement = DateTime.Now;
}
@ -142,7 +144,7 @@ namespace FurnitureAssemblyBusinessLogic.BussinessLogic
CheckModel(model, false);
if(_orderStorage.Update(model) == null)
if (_orderStorage.Update(model) == null)
{
model.Status--;

View File

@ -1,11 +1,10 @@
using System;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperEnums;
using FurnitureAssemblyBusinessLogic.OfficePackage.HelperModels;
namespace FurnitureAssemblyBusinessLogic.OfficePackage
{
@ -85,6 +84,7 @@ namespace FurnitureAssemblyBusinessLogic.OfficePackage
SaveExcel(info);
}
protected abstract void CreateExcel(ExcelInfo info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams);
@ -92,6 +92,5 @@ namespace FurnitureAssemblyBusinessLogic.OfficePackage
protected abstract void MergeCells(ExcelMergeParameters excelParams);
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@ -8,18 +8,21 @@ namespace FurnitureAssemblyClientApp
public 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"));
_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);
@ -29,16 +32,21 @@ namespace FurnitureAssemblyClientApp
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

@ -21,9 +21,9 @@ namespace FurnitureAssemblyClientApp.Controllers
{
return Redirect("~/Home/Enter");
}
return
View(APIClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={APIClient.Client.Id}"));
return View(APIClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={APIClient.Client.Id}"));
}
[HttpGet]
public IActionResult Privacy()
{
@ -33,37 +33,42 @@ namespace FurnitureAssemblyClientApp.Controllers
}
return View(APIClient.Client);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
throw new Exception("Вы как сюда попали? Суда вход только авторизованным. Кыш-кыш");
}
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/updatedata", new
ClientBindingModel
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 });
return View(new ErrorViewModel
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
});
}
[HttpGet]
@ -75,17 +80,18 @@ namespace FurnitureAssemblyClientApp.Controllers
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password))
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
APIClient.Client =
APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
APIClient.Client = APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
@ -94,41 +100,48 @@ namespace FurnitureAssemblyClientApp.Controllers
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/register", new
ClientBindingModel
APIClient.PostRequest("api/client/register", new ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Furnitures = APIClient.GetRequest<List<FurnitureViewModel>>("api/main/getfurniturelist");
return View();
}
[HttpPost]
public void Create(int furniture, int count)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным. Кыш-кыш");
}
if (count <= 0)
{
throw new Exception("Количество и сумма должны быть больше 0");
}
APIClient.PostRequest("api/main/createorder", new OrderBindingModel
{
ClientId = APIClient.Client.Id,
@ -136,14 +149,16 @@ namespace FurnitureAssemblyClientApp.Controllers
Count = count,
Sum = Calc(count, furniture)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int furniture)
{
var prod = APIClient.GetRequest<FurnitureViewModel>($"api/main/getfurniture?furnitureId={furniture}"
);
return count * (prod?.Price ?? 1);
var furnitures = APIClient.GetRequest<FurnitureViewModel>($"api/main/getfurniture?furnitureId={furniture}");
return count * (furnitures?.Price ?? 1);
}
}
}
}

View File

@ -6,6 +6,10 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Remove="Views\Home\_Layout.cshtml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
@ -14,4 +18,16 @@
<ProjectReference Include="..\FurnitureAssemblyContracts\FurnitureAssemblyContracts.csproj" />
</ItemGroup>
<ItemGroup>
<UpToDateCheckInput Remove="Views\Home\_Layout.cshtml" />
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="Views\Home\_Layout.cshtml" />
</ItemGroup>
<ItemGroup>
<None Include="Views\Home\_Layout.cshtml" />
</ItemGroup>
</Project>

View File

@ -6,4 +6,4 @@ namespace FurnitureAssemblyClientApp.Models
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
}

View File

@ -1,55 +1,54 @@
@{
ViewData["Title"] = "Create";
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Изделие:</div>
<div class="col-8">
<select id="furniture" name="furniture" class="form-control" asp-items="@(new SelectList(@ViewBag.Furnitures,"Id", "FurnitureName"))"></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>
<div class="row">
<div class="col-4">Мебель:</div>
<div class="col-8">
<select id="furniture" name="furniture" class="form-control" asp-items="@(new SelectList(@ViewBag.Furnitures,"Id", "FurnitureName"))"></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>
$('#furniture').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var furniture = $('#furniture').val();
if (count && furniture) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, furniture: furniture },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>
$('#furniture').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var furniture = $('#furniture').val();
if (count && furniture) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, furniture: furniture },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

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

View File

@ -1,57 +1,69 @@
@using FurnitureAssemblyContracts.ViewModels
@model List<OrderViewModel>
@{
ViewData["Title"] = "Home Page";
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
<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.FurnitureName)
</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>
}
@{
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.FurnitureName)
</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

@ -1,38 +1,35 @@
@using FurnitureAssemblyContracts.ViewModels
@model ClientViewModel
@{
ViewData["Title"] = "Privacy Policy";
ViewData["Title"] = "Privacy Policy";
}
<div class="text-center">
<h2 class="display-4">Личные данные</h2>
<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>
<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

@ -1,25 +1,26 @@
@{
ViewData["Title"] = "Register";
@{
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
<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>
<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,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"] - FurnitureAssemblyClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bgwhite border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" aspaction="Index">Сборка мебели</a>
<button class="navbar-toggler" type="button" datatoggle="collapse" data-target=".navbar-collapse" ariacontrols="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Index">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - Сборка Мебели - <a asp-area="" aspcontroller="Home" asp-action="Privacy">Личные данные</a>
</div>
</footer>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@ -7,31 +7,23 @@
<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="~/FurnitureAssemblyClientApp.styles.css" asp-append-version="true" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Мебельный магазин</a>
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">FurnitureAssemblyClientApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse">
<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" asparea="" asp-controller="Home" asp-action="Index">Заказы</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Register">Регистрация</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>

View File

@ -2,47 +2,48 @@
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;
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
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;
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@ -9,7 +9,6 @@ namespace FurnitureAssemblyContracts.SearchModels
// Для поиска сущности "Заказ"
public class OrderSearchModel
{
// для поиска по идентификатору
public int? Id { get; set; }
public DateTime? DateFrom { get; set; }

View File

@ -12,10 +12,15 @@ namespace FurnitureAssemblyContracts.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

@ -16,13 +16,17 @@ namespace FurnitureAssemblyDatabaseImplement
{
optionsBuilder.UseSqlServer(@"Data Source=WIN-N21FHIN3LLR\SQLEXPRESS;Initial Catalog=FurnitureAssemblyDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
}
base.OnConfiguring(optionsBuilder);
}
public virtual DbSet<WorkPiece> WorkPieces { set; get; }
public virtual DbSet<Furniture> Furnitures { set; get; }
public virtual DbSet<FurnitureWorkPiece> FurnitureWorkPieces { set; get; }
public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; }
}
}

View File

@ -0,0 +1,214 @@
// <auto-generated />
using System;
using FurnitureAssemblyDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
[DbContext(typeof(FurnitureAssemblyDatabase))]
[Migration("20240521203342_lab52")]
partial class lab52
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FurnitureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Furnitures");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("WorkPieceId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.HasIndex("WorkPieceId");
b.ToTable("FurnitureWorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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>("FurnitureId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FurnitureId");
b.ToTable("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("WorkPieceName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("WorkPieces")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", "WorkPiece")
.WithMany("FurnitureWorkPieces")
.HasForeignKey("WorkPieceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
b.Navigation("WorkPiece");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Orders");
b.Navigation("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Navigation("FurnitureWorkPieces");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,50 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class lab52 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ClientId",
table: "Orders",
type: "int",
nullable: false,
defaultValue: 0);
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",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Orders_Clients_ClientId",
table: "Orders");
migrationBuilder.DropIndex(
name: "IX_Orders_ClientId",
table: "Orders");
migrationBuilder.DropColumn(
name: "ClientId",
table: "Orders");
}
}
}

View File

@ -0,0 +1,214 @@
// <auto-generated />
using System;
using FurnitureAssemblyDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
[DbContext(typeof(FurnitureAssemblyDatabase))]
[Migration("20240521214733_labFivethree")]
partial class labFivethree
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.17")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FurnitureName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Furnitures");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("FurnitureId")
.HasColumnType("int");
b.Property<int>("WorkPieceId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("FurnitureId");
b.HasIndex("WorkPieceId");
b.ToTable("FurnitureWorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.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>("FurnitureId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FurnitureId");
b.ToTable("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("WorkPieceName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.FurnitureWorkPiece", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("WorkPieces")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", "WorkPiece")
.WithMany("FurnitureWorkPieces")
.HasForeignKey("WorkPieceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Furniture");
b.Navigation("WorkPiece");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Orders");
b.Navigation("WorkPieces");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.WorkPiece", b =>
{
b.Navigation("FurnitureWorkPieces");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace FurnitureAssemblyDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class labFivethree : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -101,6 +101,9 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
@ -121,6 +124,8 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("FurnitureId");
b.ToTable("Orders");
@ -167,15 +172,28 @@ namespace FurnitureAssemblyDatabaseImplement.Migrations
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Order", b =>
{
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("FurnitureAssemblyDatabaseImplement.Models.Furniture", "Furniture")
.WithMany("Orders")
.HasForeignKey("FurnitureId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Furniture");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("FurnitureAssemblyDatabaseImplement.Models.Furniture", b =>
{
b.Navigation("Orders");

View File

@ -24,6 +24,7 @@ namespace FurnitureAssemblyDatabaseImplement.Models
[Required]
public string Password { get; private set; } = string.Empty;
// Для реализации связи многие-ко-многим с заказами (клиенты могу сделать одинаковый заказ)
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();

View File

@ -5,6 +5,7 @@ using FurnitureAssemblyDataModels.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;
@ -18,8 +19,6 @@ namespace FurnitureAssemblyDatabaseImplement.Models
[Required]
public int FurnitureId { get; private set; }
[Required]
public int ClientId { get; private set; }
[Required]
public int Count { get; private set; }
@ -35,11 +34,13 @@ namespace FurnitureAssemblyDatabaseImplement.Models
public DateTime? DateImplement { get; private set; }
[Required]
public int ClientId { get; private set; }
// Для передачи названия изделия
public virtual Furniture Furniture { get; set; }
public virtual Furniture Furniture { get; set; } = new();
// Для передачи имени клиента
public virtual Client Client { get; set; }
public virtual Client Client { get; set; } = new();
public static Order? Create(OrderBindingModel model)
{

View File

@ -17,6 +17,7 @@ namespace FurnitureAssemblyFileImplement
private readonly string OrderFileName = "Order.xml";
private readonly string FurnitureFileName = "Furniture.xml";
private readonly string ClientFileName = "Client.xml";
public List<WorkPiece> WorkPieces { get; private set; }
@ -24,6 +25,7 @@ namespace FurnitureAssemblyFileImplement
public List<Order> Orders { get; private set; }
public List<Furniture> Furnitures { get; private set; }
public List<Client> Clients { get; private set; }
public static DataFileSingleton GetInstance()
@ -41,6 +43,7 @@ namespace FurnitureAssemblyFileImplement
public void SaveFurnitures() => SaveData(Furnitures, FurnitureFileName, "Furnitures", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);

View File

@ -3,7 +3,6 @@ using FurnitureAssemblyContracts.SearchModels;
using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyContracts.ViewModels;
using FurnitureAssemblyFileImplement.Models;
using FurnitureAssemblyFileImplement;
using System;
using System.Collections.Generic;
using System.Linq;
@ -15,21 +14,11 @@ namespace FurnitureAssemblyFileImplement.Implements
public class ClientStorage : IClientStorage
{
private readonly DataFileSingleton source;
public ClientStorage()
{
source = DataFileSingleton.GetInstance();
}
public ClientViewModel? Delete(ClientBindingModel model)
{
var client = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client != null)
{
source.Clients.Remove(client);
source.SaveClients();
return client.GetViewModel;
}
return null;
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
@ -38,55 +27,73 @@ namespace FurnitureAssemblyFileImplement.Implements
return null;
}
return source.Clients
.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.Email) && x.Email ==
model.Email) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email) || string.IsNullOrEmpty(model.Password))
if (string.IsNullOrEmpty(model.Email))
{
return new();
}
return source.Clients
.Where(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))
.Select(x => x.GetViewModel)
.ToList();
.Where(x => x.Email.Contains(model.Email))
.Select(x => x.GetViewModel)
.ToList();
}
public List<ClientViewModel> GetFullList()
{
return source.Clients
.Select(x => x.GetViewModel)
.ToList();
return source.Clients.Select(x => x.GetViewModel).ToList();
}
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 client = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null)
{
return null;
}
client.Update(model);
source.SaveClients();
return client.GetViewModel;
return client?.GetViewModel;
}
public ClientViewModel? Delete(ClientBindingModel model)
{
var client = source.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client != null)
{
source.Clients.Remove(client);
source.SaveClients();
return client?.GetViewModel;
}
return null;
}
}
}

View File

@ -20,22 +20,6 @@ namespace FurnitureAssemblyFileImplement.Implements
source = DataFileSingleton.GetInstance();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => GetViewModel(x)).ToList();
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue)
{
return source.Orders.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => GetViewModel(x)).ToList();
}
return source.Orders.Where(x => x.Id == model.Id).Select(x => GetViewModel(x)).ToList();
}
public OrderViewModel? GetElement(OrderSearchModel model)
{
if (!model.Id.HasValue)
@ -43,7 +27,26 @@ namespace FurnitureAssemblyFileImplement.Implements
return null;
}
return source.Orders.FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
return source.Orders
.FirstOrDefault(x =>
(model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{
if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue && !model.ClientId.HasValue)
{
return new();
}
return source.Orders
.Where(x => x.Id == model.Id || model.DateFrom <= x.DateCreate && x.DateCreate <= model.DateTo || x.ClientId == model.ClientId)
.Select(x => GetViewModel(x)).ToList();
}
public List<OrderViewModel> GetFullList()
{
return source.Orders.Select(x => GetViewModel(x)).ToList();
}
private OrderViewModel GetViewModel(Order order)
@ -52,7 +55,17 @@ namespace FurnitureAssemblyFileImplement.Implements
var furniture = source.Furnitures.FirstOrDefault(x => x.Id == order.FurnitureId);
viewModel.FurnitureName = furniture?.FurnitureName;
var client = source.Clients.FirstOrDefault(x => x.Id == order.ClientId);
if (furniture != null)
{
viewModel.FurnitureName = furniture.FurnitureName;
}
if (client != null)
{
viewModel.ClientFIO = client.ClientFIO;
}
return viewModel;
}
@ -91,14 +104,14 @@ namespace FurnitureAssemblyFileImplement.Implements
public OrderViewModel? Delete(OrderBindingModel model)
{
var element = source.Orders.FirstOrDefault(x => x.Id == model.Id);
var order = source.Orders.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
if (order != null)
{
source.Orders.Remove(element);
source.Orders.Remove(order);
source.SaveOrders();
return GetViewModel(element);
return GetViewModel(order);
}
return null;

View File

@ -26,6 +26,7 @@ namespace FurnitureAssemblyFileImplement.Models
{
return null;
}
return new Client()
{
Id = model.Id,
@ -41,10 +42,11 @@ namespace FurnitureAssemblyFileImplement.Models
{
return null;
}
return new Client()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ClientFIO = element.Element("ClientFIO")!.Value,
ClientFIO = element.Element("FIO")!.Value,
Email = element.Element("Email")!.Value,
Password = element.Element("Password")!.Value
};
@ -56,6 +58,7 @@ namespace FurnitureAssemblyFileImplement.Models
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;
@ -69,11 +72,10 @@ namespace FurnitureAssemblyFileImplement.Models
Password = Password
};
public XElement GetXElement => new("Client",
new XAttribute("Id", Id),
new XElement("ClientFIO", ClientFIO),
new XElement("Email", Email),
new XElement("Password", Password)
);
public XElement GetXElement => new("Order",
new XAttribute("Id", Id),
new XElement("FIO", ClientFIO),
new XElement("Email", Email),
new XElement("Password", Password));
}
}

View File

@ -17,6 +17,8 @@ namespace FurnitureAssemblyFileImplement.Models
public int FurnitureId { get; private set; }
public int ClientId { get; private set; }
public int Count { get; private set; }
public double Sum { get; private set; }
@ -38,6 +40,7 @@ namespace FurnitureAssemblyFileImplement.Models
{
Id = model.Id,
FurnitureId = model.FurnitureId,
ClientId = model.ClientId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@ -57,6 +60,7 @@ namespace FurnitureAssemblyFileImplement.Models
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
FurnitureId = Convert.ToInt32(element.Element("FurnitureId")!.Value),
ClientId = Convert.ToInt32(element.Attribute("Id")!.Value),
Count = Convert.ToInt32(element.Element("Count")!.Value),
Sum = Convert.ToDouble(element.Element("Sum")!.Value),
Status = (OrderStatus)Enum.Parse(typeof(OrderStatus), element.Element("Status")!.Value),
@ -81,6 +85,7 @@ namespace FurnitureAssemblyFileImplement.Models
{
Id = Id,
FurnitureId = FurnitureId,
ClientId = ClientId,
Count = Count,
Sum = Sum,
Status = Status,
@ -91,6 +96,7 @@ namespace FurnitureAssemblyFileImplement.Models
public XElement GetXElement => new("Order",
new XAttribute("Id", Id),
new XElement("FurnitureId", FurnitureId.ToString()),
new XElement("ClientId", ClientId.ToString()),
new XElement("Count", Count.ToString()),
new XElement("Sum", Sum.ToString()),
new XElement("Status", Status.ToString()),

View File

@ -10,12 +10,13 @@ namespace FurnitureAssemblyListImplement
public class DataListSingleton
{
private static DataListSingleton? _instance;
public List<Order> Orders { get; set; }
public List<WorkPiece> WorkPiece { get; set; }
public List<Furniture> Furnitures { get; set; }
public List<WorkPiece> WorkPiece { get; set; }
public List<Client> Clients { get; set; }
public List<Order> Orders { get; set; }
public List<Client> Clients { get; set; }
public DataListSingleton()
{
@ -23,12 +24,11 @@ namespace FurnitureAssemblyListImplement
Furnitures = new List<Furniture>();
Orders = new List<Order>();
Clients = new List<Client>();
}
public static DataListSingleton GetInstance()
{
if(_instance == null)
if (_instance == null)
{
_instance = new DataListSingleton();
}

View File

@ -20,6 +20,96 @@ namespace FurnitureAssemblyListImplement.Implements
_source = DataListSingleton.GetInstance();
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue)
{
return null;
}
foreach (var client in _source.Clients)
{
if ((!string.IsNullOrEmpty(model.Email) && client.Email == model.Email) ||
(model.Id.HasValue && client.Id == model.Id))
{
return client.GetViewModel;
}
}
return null;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
var result = new List<ClientViewModel>();
if (string.IsNullOrEmpty(model.Email))
{
return result;
}
foreach (var client in _source.Clients)
{
if (client.Email.Contains(model.Email))
{
result.Add(client.GetViewModel);
}
}
return result;
}
public List<ClientViewModel> GetFullList()
{
var result = new List<ClientViewModel>();
foreach (var client in _source.Clients)
{
result.Add(client.GetViewModel);
}
return result;
}
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)
@ -31,83 +121,7 @@ namespace FurnitureAssemblyListImplement.Implements
return element.GetViewModel;
}
}
return null;
}
public ClientViewModel? GetElement(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue)
{
return null;
}
foreach (var client in _source.Clients)
{
if ((!string.IsNullOrEmpty(model.Email) && client.Email == model.Email)
|| (model.Id.HasValue && client.Id == model.Id))
{
return client.GetViewModel;
}
}
return null;
}
public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{
var result = new List<ClientViewModel>();
if (string.IsNullOrEmpty(model.Email))
{
return result;
}
foreach (var client in _source.Clients)
{
if (client.Email.Equals(model.Email) && client.Password.Equals(model.Password))
{
result.Add(client.GetViewModel);
}
}
return result;
}
public List<ClientViewModel> GetFullList()
{
var result = new List<ClientViewModel>();
foreach (var client in _source.Clients)
{
result.Add(client.GetViewModel);
}
return result;
}
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;
}
}

View File

@ -11,7 +11,6 @@ using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Implements
{
// Класс, реализующий интерфейс хранилища заказов
public class OrderStorage : IOrderStorage
{
private readonly DataListSingleton _source;
@ -25,7 +24,7 @@ namespace FurnitureAssemblyListImplement.Implements
{
var result = new List<OrderViewModel>();
foreach(var order in _source.Orders)
foreach (var order in _source.Orders)
{
result.Add(GetViewModel(order));
}
@ -37,24 +36,30 @@ namespace FurnitureAssemblyListImplement.Implements
{
var result = new List<OrderViewModel>();
if(!model.Id.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue)
if (!model.Id.HasValue)
{
return result;
}
if (model.ClientId.HasValue)
{
foreach (var order in _source.Orders)
{
if (order.DateCreate >= model.DateFrom && order.DateCreate <= model.DateTo)
if (order.ClientId == model.ClientId)
{
result.Add(GetViewModel(order));
}
}
return result;
}
foreach (var order in _source.Orders)
if (model.DateFrom.HasValue && model.DateTo.HasValue)
{
if( order.Id == model.Id)
foreach (var order in _source.Orders)
{
result.Add(GetViewModel(order));
if (order.Id == model.Id || model.DateFrom <= order.DateCreate && order.DateCreate <= model.DateTo)
{
result.Add(GetViewModel(order));
}
}
}
@ -83,7 +88,7 @@ namespace FurnitureAssemblyListImplement.Implements
{
var viewModel = order.GetViewModel;
foreach(var furniture in _source.Furnitures)
foreach (var furniture in _source.Furnitures)
{
if (furniture.Id == order.FurnitureId)
{
@ -93,6 +98,15 @@ namespace FurnitureAssemblyListImplement.Implements
}
}
foreach (var client in _source.Clients)
{
if (client.Id == order.ClientId)
{
viewModel.ClientFIO = client.ClientFIO;
break;
}
}
return viewModel;
}
@ -100,9 +114,9 @@ namespace FurnitureAssemblyListImplement.Implements
{
model.Id = 1;
foreach(var order in _source.Orders)
foreach (var order in _source.Orders)
{
if(model.Id <= order.Id)
if (model.Id <= order.Id)
{
model.Id = order.Id + 1;
}
@ -110,7 +124,7 @@ namespace FurnitureAssemblyListImplement.Implements
var newOrder = Order.Create(model);
if(newOrder == null)
if (newOrder == null)
{
return null;
}
@ -119,11 +133,12 @@ namespace FurnitureAssemblyListImplement.Implements
return GetViewModel(newOrder);
}
public OrderViewModel? Update(OrderBindingModel model)
{
foreach(var order in _source.Orders)
foreach (var order in _source.Orders)
{
if(order.Id == model.Id)
if (order.Id == model.Id)
{
order.Update(model);
@ -136,7 +151,7 @@ namespace FurnitureAssemblyListImplement.Implements
public OrderViewModel? Delete(OrderBindingModel model)
{
for(int i = 0; i < _source.Orders.Count; i++)
for (int i = 0; i < _source.Orders.Count; i++)
{
if (_source.Orders[i].Id == model.Id)
{

View File

@ -25,6 +25,7 @@ namespace FurnitureAssemblyListImplement.Models
{
return null;
}
return new Client()
{
Id = model.Id,
@ -33,12 +34,14 @@ namespace FurnitureAssemblyListImplement.Models
Password = model.Password
};
}
public void Update(ClientBindingModel? model)
{
if (model == null)
{
return;
}
ClientFIO = model.ClientFIO;
Email = model.Email;
Password = model.Password;

View File

@ -5,17 +5,18 @@ using FurnitureAssemblyDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace FurnitureAssemblyListImplement.Models
{
// Класс, реализующий интерфейс модели заказа
public class Order : IOrderModel
{
// Методы set сделали приватными, чтобы исключить неразрешённые манипуляции
public int Id { get; private set; }
public int ClientId { get; private set; }
public int FurnitureId { get; private set; }
public int Count { get; private set; }
@ -30,7 +31,7 @@ namespace FurnitureAssemblyListImplement.Models
public static Order? Create(OrderBindingModel? model)
{
if(model == null)
if (model == null)
{
return null;
}
@ -39,6 +40,7 @@ namespace FurnitureAssemblyListImplement.Models
{
Id = model.Id,
FurnitureId = model.FurnitureId,
ClientId = model.ClientId,
Count = model.Count,
Sum = model.Sum,
Status = model.Status,
@ -47,10 +49,9 @@ namespace FurnitureAssemblyListImplement.Models
};
}
// Метод изменения существующего объекта
public void Update(OrderBindingModel? model)
{
if(model == null)
if (model == null)
{
return;
}
@ -58,11 +59,11 @@ namespace FurnitureAssemblyListImplement.Models
DateImplement = model.DateImplement;
}
// Метод для создания объекта класса ViewModel на основе данных объекта класса-компонента
public OrderViewModel GetViewModel => new()
{
Id = Id,
FurnitureId = FurnitureId,
ClientId = ClientId,
Count = Count,
Sum = Sum,
Status = Status,

View File

@ -11,12 +11,13 @@ namespace FurnitureAssemblyRestApi.Controllers
public class ClientController : Controller
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger)
{
_logger = logger;
_logic = logic;
_logger = logger;
}
[HttpGet]
@ -36,6 +37,7 @@ namespace FurnitureAssemblyRestApi.Controllers
throw;
}
}
[HttpPost]
public void Register(ClientBindingModel model)
{
@ -49,6 +51,7 @@ namespace FurnitureAssemblyRestApi.Controllers
throw;
}
}
[HttpPost]
public void UpdateData(ClientBindingModel model)
{

View File

@ -11,14 +11,18 @@ namespace FurnitureAssemblyRestApi.Controllers
public class MainController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IFurnitureLogic _furniture;
public MainController(ILogger<MainController> logger, IOrderLogic order, IFurnitureLogic furniture)
{
_logger = logger;
_order = order;
_furniture = furniture;
}
[HttpGet]
public List<FurnitureViewModel>? GetFurnitureList()
{
@ -28,10 +32,11 @@ namespace FurnitureAssemblyRestApi.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка мебели");
_logger.LogError(ex, "Ошибка получения списка изделий");
throw;
}
}
[HttpGet]
public FurnitureViewModel? GetFurniture(int furnitureId)
{
@ -44,11 +49,11 @@ namespace FurnitureAssemblyRestApi.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения мебели по id={Id}",
furnitureId);
_logger.LogError(ex, "Ошибка получения изделия по id={Id}", furnitureId);
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetOrders(int clientId)
{
@ -61,10 +66,11 @@ namespace FurnitureAssemblyRestApi.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка заказов клиента id ={ Id}", clientId);
_logger.LogError(ex, "Ошибка получения списка заказов клиента id = {Id}", clientId);
throw;
}
}
[HttpPost]
public void CreateOrder(OrderBindingModel model)
{
@ -77,6 +83,7 @@ namespace FurnitureAssemblyRestApi.Controllers
_logger.LogError(ex, "Ошибка создания заказа");
throw;
}
}
}
}

View File

@ -4,35 +4,40 @@ using FurnitureAssemblyContracts.StoragesContracts;
using FurnitureAssemblyDatabaseImplement.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<IFurnitureStorage, FurnitureStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IFurnitureLogic, FurnitureLogic>();
builder.Services.AddControllers();
builder.Services.AddControllers();
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 = "FurnitureAssemblyRestApi", Version = "v1"
});
c.SwaggerDoc("v1", new OpenApiInfo { Title = "FurnitureAssemblyRestApi", 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", "FurnitureAssemblyRestApi v1"));
}

View File

@ -195,6 +195,7 @@
this.clientsToolStripMenuItem.Name = "clientsToolStripMenuItem";
this.clientsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.clientsToolStripMenuItem.Text = "Клиенты";
this.clientsToolStripMenuItem.Click += new System.EventHandler(this.ClientsToolStripMenuItem_Click);
//
// FormMain
//