This commit is contained in:
Игорь Гордеев 2024-05-12 19:04:40 +04:00
parent 49f7b0b792
commit eaa284a400
63 changed files with 1823 additions and 934 deletions

View File

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

View File

@ -12,7 +12,7 @@ namespace SushiBarBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
static readonly object _locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{ {
_logger = logger; _logger = logger;
@ -20,7 +20,8 @@ namespace SushiBarBusinessLogic.BusinessLogics
} }
public List<OrderViewModel>? ReadList(OrderSearchModel? model) public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{ {
_logger.LogInformation("Order. OrderID:{Id}", model?.Id); _logger.LogInformation("ReadList. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}",
model?.ClientId, model?.Status, model?.ImplementerId, model?.DateFrom, model?.DateTo, model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model); var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null) if (list == null)
{ {
@ -30,24 +31,38 @@ namespace SushiBarBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count:{Count}", list.Count); _logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list; return list;
} }
public bool CreateOrder(OrderBindingModel model) public bool CreateOrder(OrderBindingModel model)
{ {
CheckModel(model); CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) if (model.Status != OrderStatus.Неизвестен)
{
_logger.LogWarning("Insert operation failed. Order status incorrect.");
return false; return false;
}
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) if (_orderStorage.Insert(model) == null)
{ {
model.Status = OrderStatus.Неизвестен;
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Insert operation failed");
return false; return false;
} }
return true; return true;
} }
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (_locker)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true) private void CheckModel(OrderBindingModel model, bool withParams = true)
{ {
if (model == null) if (model == null)
@ -58,62 +73,79 @@ namespace SushiBarBusinessLogic.BusinessLogics
{ {
return; return;
} }
if (model.SushiId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор у суши", nameof(model.SushiId));
}
if (model.Count <= 0) if (model.Count <= 0)
{ {
throw new ArgumentNullException("Количество суши в заказе должно быть больше 0", nameof(model.Count)); throw new ArgumentException("Колличество пиццы в заказе не может быть меньше 1", nameof(model.Count));
} }
if (model.Sum <= 0) if (model.Sum <= 0)
{ {
throw new ArgumentNullException("Сумма заказа должна быть больше 0", nameof(model.Sum)); throw new ArgumentException("Стоимость заказа на может быть меньше 1", nameof(model.Sum));
} }
_logger.LogInformation("Order. OrderID:{Id}. Sum:{ Sum}. SushiId: { SushiId}", model.Id, model.Sum, model.SushiId); if (model.DateImplement.HasValue && model.DateImplement < model.DateCreate)
{
throw new ArithmeticException($"Дата выдачи заказа {model.DateImplement} не может быть раньше даты его создания {model.DateCreate}");
}
_logger.LogInformation("Sushi. SushiId:{SushiId}.Count:{Count}.Sum:{Sum}Id:{Id}",
model.SushiId, model.Count, model.Sum, model.Id);
} }
public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus) private bool ChangeStatus(OrderBindingModel model, OrderStatus requiredStatus)
{ {
var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (viewModel == null)
{
throw new ArgumentNullException(nameof(model));
}
if (viewModel.Status + 1 != newStatus)
{
_logger.LogWarning("Status update to " + newStatus.ToString() + " operation failed. Order status incorrect.");
return false;
}
model.Status = newStatus;
if (model.Status == OrderStatus.Готов) model.DateImplement = DateTime.Now;
else
{
model.DateImplement = viewModel.DateImplement;
}
CheckModel(model, false); CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel()
{
Id = model.Id
});
if (element == null)
{
throw new InvalidOperationException(nameof(element));
}
model.DateCreate = element.DateCreate;
model.SushiId = element.SushiId;
model.DateImplement = element.DateImplement;
model.ClientId = element.ClientId;
if (!model.ImplementerId.HasValue)
{
model.ImplementerId = element.ImplementerId;
}
model.Status = element.Status;
model.Count = element.Count;
model.Sum = element.Sum;
if (requiredStatus - model.Status == 1)
{
model.Status = requiredStatus;
if (model.Status == OrderStatus.Готов)
{
model.DateImplement = DateTime.Now;
}
if (_orderStorage.Update(model) == null) if (_orderStorage.Update(model) == null)
{ {
model.Status--;
_logger.LogWarning("Update operation failed"); _logger.LogWarning("Update operation failed");
return false; return false;
} }
return true; return true;
} }
_logger.LogWarning("Changing status operation faled: Current-{Status}:required-{requiredStatus}.", model.Status, requiredStatus);
throw new InvalidOperationException($"Невозможно приствоить статус {requiredStatus} заказу с текущим статусом {model.Status}");
public bool TakeOrderInWork(OrderBindingModel model)
{
return StatusUpdate(model, OrderStatus.Выполняется);
} }
public bool DeliveryOrder(OrderBindingModel model) public OrderViewModel? ReadElement(OrderSearchModel model)
{ {
return StatusUpdate(model, OrderStatus.Выдан); if (model == null)
}
public bool FinishOrder(OrderBindingModel model)
{ {
return StatusUpdate(model, OrderStatus.Готов); throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ClientId:{ClientId}.Status:{Status}.ImplementerId:{ImplementerId}.DateFrom:{DateFrom}.DateTo:{DateTo}OrderId:{Id}",
model.ClientId, model.Status, model.ImplementerId, model.DateFrom, model.DateTo, model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
} }
} }
} }

View File

@ -0,0 +1,139 @@
using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModels;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят });
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id
});
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
});
}
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Выполняется
}));
if (runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@ -1,20 +1,21 @@
using Newtonsoft.Json; using System.Net.Http.Headers;
using SushiBarContracts.ViewModels;
using System.Net.Http.Headers;
using System.Text; using System.Text;
using SushiBarContracts.ViewModels;
using Newtonsoft.Json;
namespace SushiBarClientApp namespace SushiBarClientApp
{ {
public static class APIClient public class APIClient
{ {
private static readonly HttpClient _client = new(); private static readonly HttpClient _client = new();
public static ClientViewModel? Client { get; set; } = null; public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration configuration) public static void Connect(IConfiguration configuration)
{ {
_client.BaseAddress = new Uri(configuration["IPAddress"]); _client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear(); _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) public static T? GetRequest<T>(string requestUrl)
{ {
@ -42,4 +43,5 @@ namespace SushiBarClientApp
} }
} }
} }
} }

View File

@ -20,7 +20,8 @@ namespace SushiBarClientApp.Controllers
{ {
return Redirect("~/Home/Enter"); 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] [HttpGet]
public IActionResult Privacy() public IActionResult Privacy()

View File

@ -8,7 +8,7 @@ APIClient.Connect(builder.Configuration);
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
{ {
app.UseExceptionHandler("/Home/Error"); 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. // The default HSTS value is 30 days. You may want to change this for sushiion scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts(); app.UseHsts();
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();

View File

@ -1,22 +1,21 @@
{ {
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:22876",
"sslPort": 44352
}
},
"profiles": { "profiles": {
"http": { "SushiBarClientApp": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,
"applicationUrl": "https://localhost:7121;http://localhost:5109",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
}, }
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5222"
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7084;http://localhost:5222"
}, },
"IIS Express": { "IIS Express": {
"commandName": "IISExpress", "commandName": "IISExpress",
@ -25,14 +24,5 @@
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
} }
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:41478",
"sslPort": 44302
}
} }
} }

View File

@ -6,12 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -6,35 +6,25 @@
</div> </div>
<form method="post"> <form method="post">
<div class="row"> <div class="row">
<div class="col-4">Суши:</div> <div class="col-4">Изделие:</div>
<div class="col-8"> <div class="col-8">
<select id="sushi" name="sushi" class="form-control"> <select id="sushi" name="sushi" class="form-control" asp-items="@(new SelectList(@ViewBag.Sushis,"Id", "SushiName"))"></select>
@foreach (var sushi in ViewBag.Sushis)
{
<option value="@sushi.Id">@sushi.SushiName</option>
}
</select>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Количество:</div> <div class="col-4">Количество:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="count" id="count" /></div>
<input type="text" name="count" id="count" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Сумма:</div> <div class="col-4">Сумма:</div>
<div class="col-8"> <div class="col-8"><input type="text" id="sum" name="sum" readonly /></div>
<input type="text" id="sum" name="sum" readonly />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
<input type="submit" value="Создать" class="btn btn-primary" />
</div>
</div> </div>
</form> </form>
<script> <script>
$('#sushi').on('change', function () { $('#sushi').on('change', function () {
check(); check();
@ -42,6 +32,7 @@
$('#count').on('change', function () { $('#count').on('change', function () {
check(); check();
}); });
function check() { function check() {
var count = $('#count').val(); var count = $('#count').val();
var sushi = $('#sushi').val(); var sushi = $('#sushi').val();
@ -51,8 +42,7 @@
url: "/Home/Calc", url: "/Home/Calc",
data: { count: count, sushi: sushi }, data: { count: count, sushi: sushi },
success: function (result) { success: function (result) {
var roundedResult = parseFloat(result).toFixed(2); $("#sum").val(result);
$("#sum").val(roundedResult);
} }
}); });
}; };

View File

@ -1,6 +1,7 @@
@{ @{
ViewData["Title"] = "Enter"; ViewData["Title"] = "Enter";
} }
<div class="text-center"> <div class="text-center">
<h2 class="display-4">Вход в приложение</h2> <h2 class="display-4">Вход в приложение</h2>
</div> </div>
@ -15,6 +16,6 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btnprimary" /></div> <div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
</div> </div>
</form> </form>

View File

@ -1,11 +1,16 @@
@using SushiBarContracts.ViewModels @using SushiBarContracts.ViewModels
@model List<OrderViewModel> @model List<OrderViewModel>
@{ @{
ViewData["Title"] = "Home Page"; ViewData["Title"] = "Home Page";
} }
<div class="text-center"> <div class="text-center">
<h1 class="display-4">Заказы</h1> <h1 class="display-4">Заказы</h1>
</div> </div>
<div class="text-center"> <div class="text-center">
@{ @{
if (Model == null) if (Model == null)
@ -13,6 +18,7 @@
<h3 class="display-4">Авторизируйтесь</h3> <h3 class="display-4">Авторизируйтесь</h3>
return; return;
} }
<p> <p>
<a asp-action="Create">Создать заказ</a> <a asp-action="Create">Создать заказ</a>
</p> </p>
@ -44,28 +50,22 @@
{ {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.Id)
item.Id)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.SushiName)
item.SushiName)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.DateCreate)
item.DateCreate)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.Count)
item.Count)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.Sum)
item.Sum)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => @Html.DisplayFor(modelItem => item.Status)
item.Status)
</td> </td>
</tr> </tr>
} }

View File

@ -1,5 +1,6 @@
@using SushiBarContracts.ViewModels @using SushiBarContracts.ViewModels
@model ClientViewModel @model ClientViewModel
@{ @{
ViewData["Title"] = "Privacy Policy"; ViewData["Title"] = "Privacy Policy";
} }
@ -9,29 +10,18 @@
<form method="post"> <form method="post">
<div class="row"> <div class="row">
<div class="col-4">Логин:</div> <div class="col-4">Логин:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="login" value="@Model.Email" /></div>
<input type="text" name="login"
value="@Model.Email" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Пароль:</div> <div class="col-4">Пароль:</div>
<div class="col-8"> <div class="col-8"><input type="password" name="password" value="@Model.Password" /></div>
<input type="password" name="password"
value="@Model.Password" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">ФИО:</div> <div class="col-4">ФИО:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="fio" value="@Model.ClientFIO" /></div>
<input type="text" name="fio"
value="@Model.ClientFIO" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
<input type="submit" value="Сохранить" class="btn btn-primary" />
</div>
</div> </div>
</form> </form>

View File

@ -1,6 +1,7 @@
@{ @{
ViewData["Title"] = "Register"; ViewData["Title"] = "Register";
} }
<div class="text-center"> <div class="text-center">
<h2 class="display-4">Регистрация</h2> <h2 class="display-4">Регистрация</h2>
</div> </div>
@ -19,9 +20,6 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
<input type="submit" value="Регистрация"
class="btn btn-primary" />
</div>
</div> </div>
</form> </form>

View File

@ -5,32 +5,33 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - SushiBarClientApp</title> <title>@ViewData["Title"] - SushiBarClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/SushiBarClientApp.styles.css" asp-append-version="true" />
<script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
</head> </head>
<body> <body>
<header> <header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bgwhite border-bottom box-shadow mb-3"> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container"> <div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" aspaction="Index">Суши бар</a> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Суши-Бар</a>
<button class="navbar-toggler" type="button" datatoggle="collapse" data-target=".navbar-collapse" ariacontrols="navbarSupportedContent" <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation"> aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse"> <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1"> <ul class="navbar-nav flex-grow-1">
<li class="nav-item"> <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">Заказы</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li> </li>
<li class="nav-item"> <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="Register">Регистрация</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -42,12 +43,15 @@
@RenderBody() @RenderBody()
</main> </main>
</div> </div>
<footer class="border-top footer text-muted"> <footer class="border-top footer text-muted">
<div class="container"> <div class="container">
&copy; 2020 - Суши бар - <a asp-area="" aspcontroller="Home" asp-action="Privacy">Личные данные</a> &copy; 2024 - SushiBarClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div> </div>
</footer> </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> <script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false) @await RenderSectionAsync("Scripts", required: false)
</body> </body>
</html> </html>

View File

@ -1,4 +1,4 @@
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification /* 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. */ for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand { a.navbar-brand {

View File

@ -6,6 +6,5 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"IPAddress": "http://localhost:5037/"
"IPAddress": "http://localhost:5262/"
} }

View File

@ -8,10 +8,6 @@ html {
} }
} }
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
html { html {
position: relative; position: relative;
min-height: 100%; min-height: 100%;

View File

@ -1,4 +1,4 @@
// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification // 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. // for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code. // Write your JavaScript code.

View File

@ -1,23 +1,12 @@
The MIT License (MIT) Copyright (c) .NET Foundation. All rights reserved.
Copyright (c) .NET Foundation and Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use
these files except in compliance with the License. You may obtain a copy of the
License at
All rights reserved. http://www.apache.org/licenses/LICENSE-2.0
Permission is hereby granted, free of charge, to any person obtaining a copy Unless required by applicable law or agreed to in writing, software distributed
of this software and associated documentation files (the "Software"), to deal under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
in the Software without restriction, including without limitation the rights CONDITIONS OF ANY KIND, either express or implied. See the License for the
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell specific language governing permissions and limitations under the License.
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,10 +1,7 @@
/** // Unobtrusive validation support library for jQuery and jQuery Validate
* @license // Copyright (c) .NET Foundation. All rights reserved.
* Unobtrusive validation support library for jQuery and jQuery Validate // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
* Copyright (c) .NET Foundation. All rights reserved. // @version v3.2.11
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
* @version v4.0.0
*/
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */ /*global document: false, jQuery: false */

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,13 @@
Copyright JS Foundation and other contributors, https://js.foundation/
Copyright OpenJS Foundation and other contributors, https://openjsf.org/ This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -19,3 +27,10 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from
the terms above.

View File

@ -1,15 +1,15 @@
/*! /*!
* jQuery JavaScript Library v3.6.0 * jQuery JavaScript Library v3.5.1
* https://jquery.com/ * https://jquery.com/
* *
* Includes Sizzle.js * Includes Sizzle.js
* https://sizzlejs.com/ * https://sizzlejs.com/
* *
* Copyright OpenJS Foundation and other contributors * Copyright JS Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* https://jquery.org/license * https://jquery.org/license
* *
* Date: 2021-03-02T17:08Z * Date: 2020-05-04T22:49Z
*/ */
( function( global, factory ) { ( function( global, factory ) {
@ -80,11 +80,7 @@ var isFunction = function isFunction( obj ) {
// In some browsers, typeof returns "function" for HTML <object> elements // In some browsers, typeof returns "function" for HTML <object> elements
// (i.e., `typeof document.createElement( "object" ) === "function"`). // (i.e., `typeof document.createElement( "object" ) === "function"`).
// We don't want to classify *any* DOM node as a function. // We don't want to classify *any* DOM node as a function.
// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 return typeof obj === "function" && typeof obj.nodeType !== "number";
// Plus for old WebKit, typeof returns "function" for HTML collections
// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
return typeof obj === "function" && typeof obj.nodeType !== "number" &&
typeof obj.item !== "function";
}; };
@ -151,7 +147,7 @@ function toType( obj ) {
var var
version = "3.6.0", version = "3.5.1",
// Define a local copy of jQuery // Define a local copy of jQuery
jQuery = function( selector, context ) { jQuery = function( selector, context ) {
@ -522,14 +518,14 @@ function isArrayLike( obj ) {
} }
var Sizzle = var Sizzle =
/*! /*!
* Sizzle CSS Selector Engine v2.3.6 * Sizzle CSS Selector Engine v2.3.5
* https://sizzlejs.com/ * https://sizzlejs.com/
* *
* Copyright JS Foundation and other contributors * Copyright JS Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* https://js.foundation/ * https://js.foundation/
* *
* Date: 2021-02-16 * Date: 2020-03-14
*/ */
( function( window ) { ( function( window ) {
var i, var i,
@ -1112,8 +1108,8 @@ support = Sizzle.support = {};
* @returns {Boolean} True iff elem is a non-HTML XML node * @returns {Boolean} True iff elem is a non-HTML XML node
*/ */
isXML = Sizzle.isXML = function( elem ) { isXML = Sizzle.isXML = function( elem ) {
var namespace = elem && elem.namespaceURI, var namespace = elem.namespaceURI,
docElem = elem && ( elem.ownerDocument || elem ).documentElement; docElem = ( elem.ownerDocument || elem ).documentElement;
// Support: IE <=8 // Support: IE <=8
// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
@ -3030,7 +3026,7 @@ function nodeName( elem, name ) {
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
} };
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
@ -4001,8 +3997,8 @@ jQuery.extend( {
resolveContexts = Array( i ), resolveContexts = Array( i ),
resolveValues = slice.call( arguments ), resolveValues = slice.call( arguments ),
// the primary Deferred // the master Deferred
primary = jQuery.Deferred(), master = jQuery.Deferred(),
// subordinate callback factory // subordinate callback factory
updateFunc = function( i ) { updateFunc = function( i ) {
@ -4010,30 +4006,30 @@ jQuery.extend( {
resolveContexts[ i ] = this; resolveContexts[ i ] = this;
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
if ( !( --remaining ) ) { if ( !( --remaining ) ) {
primary.resolveWith( resolveContexts, resolveValues ); master.resolveWith( resolveContexts, resolveValues );
} }
}; };
}; };
// Single- and empty arguments are adopted like Promise.resolve // Single- and empty arguments are adopted like Promise.resolve
if ( remaining <= 1 ) { if ( remaining <= 1 ) {
adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
!remaining ); !remaining );
// Use .then() to unwrap secondary thenables (cf. gh-3000) // Use .then() to unwrap secondary thenables (cf. gh-3000)
if ( primary.state() === "pending" || if ( master.state() === "pending" ||
isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
return primary.then(); return master.then();
} }
} }
// Multiple arguments are aggregated like Promise.all array elements // Multiple arguments are aggregated like Promise.all array elements
while ( i-- ) { while ( i-- ) {
adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
} }
return primary.promise(); return master.promise();
} }
} ); } );
@ -5093,7 +5089,10 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
} }
var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; var
rkeyEvent = /^key/,
rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
function returnTrue() { function returnTrue() {
return true; return true;
@ -5657,13 +5656,7 @@ function leverageNative( el, type, expectSync ) {
// Cancel the outer synthetic event // Cancel the outer synthetic event
event.stopImmediatePropagation(); event.stopImmediatePropagation();
event.preventDefault(); event.preventDefault();
return result.value;
// Support: Chrome 86+
// In Chrome, if an element having a focusout handler is blurred by
// clicking outside of it, it invokes the handler synchronously. If
// that handler calls `.remove()` on the element, the data is cleared,
// leaving `result` undefined. We need to guard against this.
return result && result.value;
} }
// If this is an inner synthetic event for an event with a bubbling surrogate // If this is an inner synthetic event for an event with a bubbling surrogate
@ -5828,7 +5821,34 @@ jQuery.each( {
targetTouches: true, targetTouches: true,
toElement: true, toElement: true,
touches: true, touches: true,
which: true
which: function( event ) {
var button = event.button;
// Add which for key events
if ( event.which == null && rkeyEvent.test( event.type ) ) {
return event.charCode != null ? event.charCode : event.keyCode;
}
// Add which for click: 1 === left; 2 === middle; 3 === right
if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
if ( button & 1 ) {
return 1;
}
if ( button & 2 ) {
return 3;
}
if ( button & 4 ) {
return 2;
}
return 0;
}
return event.which;
}
}, jQuery.event.addProp ); }, jQuery.event.addProp );
jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
@ -5854,12 +5874,6 @@ jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateTyp
return true; return true;
}, },
// Suppress native focus or blur as it's already being fired
// in leverageNative.
_default: function() {
return true;
},
delegateType: delegateType delegateType: delegateType
}; };
} ); } );
@ -6527,10 +6541,6 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
// set in CSS while `offset*` properties report correct values. // set in CSS while `offset*` properties report correct values.
// Behavior in IE 9 is more subtle than in newer versions & it passes // Behavior in IE 9 is more subtle than in newer versions & it passes
// some versions of this test; make sure not to make it pass there! // some versions of this test; make sure not to make it pass there!
//
// Support: Firefox 70+
// Only Firefox includes border widths
// in computed dimensions. (gh-4529)
reliableTrDimensions: function() { reliableTrDimensions: function() {
var table, tr, trChild, trStyle; var table, tr, trChild, trStyle;
if ( reliableTrDimensionsVal == null ) { if ( reliableTrDimensionsVal == null ) {
@ -6538,32 +6548,17 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
tr = document.createElement( "tr" ); tr = document.createElement( "tr" );
trChild = document.createElement( "div" ); trChild = document.createElement( "div" );
table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; table.style.cssText = "position:absolute;left:-11111px";
tr.style.cssText = "border:1px solid";
// Support: Chrome 86+
// Height set through cssText does not get applied.
// Computed height then comes back as 0.
tr.style.height = "1px"; tr.style.height = "1px";
trChild.style.height = "9px"; trChild.style.height = "9px";
// Support: Android 8 Chrome 86+
// In our bodyBackground.html iframe,
// display for all div elements is set to "inline",
// which causes a problem only in Android 8 Chrome 86.
// Ensuring the div is display: block
// gets around this issue.
trChild.style.display = "block";
documentElement documentElement
.appendChild( table ) .appendChild( table )
.appendChild( tr ) .appendChild( tr )
.appendChild( trChild ); .appendChild( trChild );
trStyle = window.getComputedStyle( tr ); trStyle = window.getComputedStyle( tr );
reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
parseInt( trStyle.borderTopWidth, 10 ) +
parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
documentElement.removeChild( table ); documentElement.removeChild( table );
} }
@ -7766,7 +7761,6 @@ jQuery.fn.extend( {
anim.stop( true ); anim.stop( true );
} }
}; };
doAnimation.finish = doAnimation; doAnimation.finish = doAnimation;
return empty || optall.queue === false ? return empty || optall.queue === false ?
@ -8713,7 +8707,9 @@ jQuery.extend( jQuery.event, {
special.bindType || type; special.bindType || type;
// jQuery handler // jQuery handler
handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && handle = (
dataPriv.get( cur, "events" ) || Object.create( null )
)[ event.type ] &&
dataPriv.get( cur, "handle" ); dataPriv.get( cur, "handle" );
if ( handle ) { if ( handle ) {
handle.apply( cur, data ); handle.apply( cur, data );
@ -8860,7 +8856,7 @@ var rquery = ( /\?/ );
// Cross-browser xml parsing // Cross-browser xml parsing
jQuery.parseXML = function( data ) { jQuery.parseXML = function( data ) {
var xml, parserErrorElem; var xml;
if ( !data || typeof data !== "string" ) { if ( !data || typeof data !== "string" ) {
return null; return null;
} }
@ -8869,17 +8865,12 @@ jQuery.parseXML = function( data ) {
// IE throws on parseFromString with invalid input. // IE throws on parseFromString with invalid input.
try { try {
xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
} catch ( e ) {} } catch ( e ) {
xml = undefined;
}
parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
if ( !xml || parserErrorElem ) { jQuery.error( "Invalid XML: " + data );
jQuery.error( "Invalid XML: " + (
parserErrorElem ?
jQuery.map( parserErrorElem.childNodes, function( el ) {
return el.textContent;
} ).join( "\n" ) :
data
) );
} }
return xml; return xml;
}; };
@ -8980,14 +8971,16 @@ jQuery.fn.extend( {
// Can add propHook for "elements" to filter or add form elements // Can add propHook for "elements" to filter or add form elements
var elements = jQuery.prop( this, "elements" ); var elements = jQuery.prop( this, "elements" );
return elements ? jQuery.makeArray( elements ) : this; return elements ? jQuery.makeArray( elements ) : this;
} ).filter( function() { } )
.filter( function() {
var type = this.type; var type = this.type;
// Use .is( ":disabled" ) so that fieldset[disabled] works // Use .is( ":disabled" ) so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) && return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !rcheckableType.test( type ) ); ( this.checked || !rcheckableType.test( type ) );
} ).map( function( _i, elem ) { } )
.map( function( _i, elem ) {
var val = jQuery( this ).val(); var val = jQuery( this ).val();
if ( val == null ) { if ( val == null ) {
@ -9040,7 +9033,6 @@ var
// Anchor tag for parsing the document origin // Anchor tag for parsing the document origin
originAnchor = document.createElement( "a" ); originAnchor = document.createElement( "a" );
originAnchor.href = location.href; originAnchor.href = location.href;
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
@ -9735,10 +9727,8 @@ jQuery.extend( {
response = ajaxHandleResponses( s, jqXHR, responses ); response = ajaxHandleResponses( s, jqXHR, responses );
} }
// Use a noop converter for missing script but not if jsonp // Use a noop converter for missing script
if ( !isSuccess && if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
jQuery.inArray( "script", s.dataTypes ) > -1 &&
jQuery.inArray( "json", s.dataTypes ) < 0 ) {
s.converters[ "text script" ] = function() {}; s.converters[ "text script" ] = function() {};
} }
@ -10476,6 +10466,12 @@ jQuery.offset = {
options.using.call( elem, props ); options.using.call( elem, props );
} else { } else {
if ( typeof props.top === "number" ) {
props.top += "px";
}
if ( typeof props.left === "number" ) {
props.left += "px";
}
curElem.css( props ); curElem.css( props );
} }
} }
@ -10644,11 +10640,8 @@ jQuery.each( [ "top", "left" ], function( _i, prop ) {
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
padding: "inner" + name, function( defaultExtra, funcName ) {
content: type,
"": "outer" + name
}, function( defaultExtra, funcName ) {
// Margin is only for outerHeight, outerWidth // Margin is only for outerHeight, outerWidth
jQuery.fn[ funcName ] = function( margin, value ) { jQuery.fn[ funcName ] = function( margin, value ) {
@ -10733,8 +10726,7 @@ jQuery.fn.extend( {
} }
} ); } );
jQuery.each( jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
( "blur focus focusin focusout resize scroll click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup contextmenu" ).split( " " ), "change select submit keydown keypress keyup contextmenu" ).split( " " ),
function( _i, name ) { function( _i, name ) {
@ -10745,8 +10737,7 @@ jQuery.each(
this.on( name, null, data, fn ) : this.on( name, null, data, fn ) :
this.trigger( name ); this.trigger( name );
}; };
} } );
);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,18 @@
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.BindingModels
{
public class ImplementerBindingModel : IImplementerModel
{
public int Id { get; set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
}
}

View File

@ -15,5 +15,7 @@ namespace SushiBarContracts.BindingModels
public int ClientId { get; set; } public int ClientId { get; set; }
public string ClientFIO { get; set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
} }
} }

View File

@ -0,0 +1,20 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IImplementerLogic
{
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
ImplementerViewModel? ReadElement(ImplementerSearchModel model);
bool Create(ImplementerBindingModel model);
bool Update(ImplementerBindingModel model);
bool Delete(ImplementerBindingModel model);
}
}

View File

@ -11,5 +11,6 @@ namespace SushiBarContracts.BusinessLogicsContracts
bool TakeOrderInWork(OrderBindingModel model); bool TakeOrderInWork(OrderBindingModel model);
bool FinishOrder(OrderBindingModel model); bool FinishOrder(OrderBindingModel model);
bool DeliveryOrder(OrderBindingModel model); bool DeliveryOrder(OrderBindingModel model);
OrderViewModel? ReadElement(OrderSearchModel model);
} }
} }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.BusinessLogicsContracts
{
public interface IWorkProcess
{
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.SearchModels
{
public class ImplementerSearchModel
{
public int? Id { get; set; }
public string? ImplementerFIO { get; set; }
public string? Password { get; set; }
}
}

View File

@ -1,12 +1,16 @@
 
using SushiBarDataModels.Enums;
namespace SushiBarContracts.SearchModels namespace SushiBarContracts.SearchModels
{ {
public class OrderSearchModel public class OrderSearchModel
{ {
public int? Id { get; set; } public int? Id { get; set; }
public DateTime? DateTo { get; set; }
public DateTime? DateFrom { get; set; }
public int? ClientId { get; set; } public int? ClientId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public OrderStatus? Status { get; set; }
public int? ImplementerId { get; set; }
} }
} }

View File

@ -0,0 +1,21 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.StoragesContracts
{
public interface IImplementerStorage
{
List<ImplementerViewModel> GetFullList();
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
ImplementerViewModel? GetElement(ImplementerSearchModel model);
ImplementerViewModel? Insert(ImplementerBindingModel model);
ImplementerViewModel? Update(ImplementerBindingModel model);
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

@ -0,0 +1,27 @@
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarContracts.ViewModels
{
public class ImplementerViewModel : IImplementerModel
{
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж работы")]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
public int Qualification { get; set; }
}
}

View File

@ -11,7 +11,11 @@ namespace SushiBarContracts.ViewModels
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("Имя клиента")] [DisplayName("Имя клиента")]
public string ClientFIO { get; set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")]
public string? ImplementerFIO { get; set; } = null;
public int SushiId { get; set; } public int SushiId { get; set; }
[DisplayName("Суши")] [DisplayName("Суши")]
public string SushiName { get; set; } = string.Empty; public string SushiName { get; set; } = string.Empty;

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarDataModels.Models
{
public interface IImplementerModel : IId
{
string ImplementerFIO { get; }
string Password { get; }
int WorkExperience { get; }
int Qualification { get; }
}
}

View File

@ -0,0 +1,84 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarDatabaseImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
public List<ImplementerViewModel> GetFullList()
{
using var context = new SushiBarDatabase();
return context.Implementers.Select(x => x.GetViewModel).ToList();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
return new();
}
using var context = new SushiBarDatabase();
return context.Implementers.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO)).Select(x => x.GetViewModel).ToList();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (string.IsNullOrEmpty(model.ImplementerFIO) && !model.Id.HasValue)
{
return null;
}
using var context = new SushiBarDatabase();
return context.Implementers.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.ImplementerFIO) && x.ImplementerFIO == model.ImplementerFIO && (!string.IsNullOrEmpty(model.Password) ? x.Password == model.Password : true)) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
var newImplementer = Implementer.Create(model);
if (newImplementer == null)
{
return null;
}
using var context = new SushiBarDatabase();
context.Implementers.Add(newImplementer);
context.SaveChanges();
return newImplementer.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
using var context = new SushiBarDatabase();
var implementer = context.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (implementer == null)
{
return null;
}
implementer.Update(model);
context.SaveChanges();
return implementer.GetViewModel;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
using var context = new SushiBarDatabase();
var implementer = context.Implementers.FirstOrDefault(rec => rec.Id == model.Id);
if (implementer != null)
{
context.Implementers.Remove(implementer);
context.SaveChanges();
return implementer.GetViewModel;
}
return null;
}
}
}

View File

@ -40,74 +40,46 @@ namespace SushiBarDatabaseImplement.Implements
public List<OrderViewModel> GetFilteredList(OrderSearchModel model) public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{ {
using var context = new SushiBarDatabase(); using var context = new SushiBarDatabase();
if (!model.Id.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue) if ((!model.DateFrom.HasValue || !model.DateTo.HasValue) && !model.ClientId.HasValue && !model.Status.HasValue)
{ {
return context.Orders
.Include(x => x.Sushi)
.Include(x => x.Client)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
}
else if (model.Id.HasValue)
{
return context.Orders
.Include(x => x.Sushi)
.Include(x => x.Client)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
}
else if (model.ClientId.HasValue)
{
return context.Orders
.Include(x => x.Sushi)
.Include(x => x.Client)
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
return new(); return new();
} }
return context.Orders.Include(x => x.Sushi).Include(x => x.Client).Include(x => x.Implementer).Where(x =>
(model.DateFrom.HasValue && model.DateTo.HasValue && x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo) ||
(model.ClientId.HasValue && x.ClientId == model.ClientId) ||
(model.Status.HasValue && x.Status == model.Status))
.Select(x => x.GetViewModel).ToList();
}
public List<OrderViewModel> GetFullList() public List<OrderViewModel> GetFullList()
{ {
using var context = new SushiBarDatabase(); using var context = new SushiBarDatabase();
return context.Orders return context.Orders.Include(x => x.Sushi).Include(x => x.Client).Include(y => y.Implementer).Select(x => x.GetViewModel).ToList();
.Include(x => x.Sushi)
.Include(x => x.Client)
.Select(x => x.GetViewModel)
.ToList();
} }
public OrderViewModel? Insert(OrderBindingModel model) public OrderViewModel? Insert(OrderBindingModel model)
{ {
var newOrder = Order.Create(model); using var context = new SushiBarDatabase();
if (model == null)
return null;
var newOrder = Order.Create(context, model);
if (newOrder == null) if (newOrder == null)
{ {
return null; return null;
} }
using var context = new SushiBarDatabase();
context.Orders.Add(newOrder); context.Orders.Add(newOrder);
context.SaveChanges(); context.SaveChanges();
return context.Orders return newOrder.GetViewModel;
.Include(x => x.Sushi)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == newOrder.Id)
?.GetViewModel;
} }
public OrderViewModel? Update(OrderBindingModel model) public OrderViewModel? Update(OrderBindingModel model)
{ {
using var context = new SushiBarDatabase(); using var context = new SushiBarDatabase();
var order = context.Orders var order = context.Orders.FirstOrDefault(x => x.Id == model.Id);
.Include(x => x.Sushi)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == model.Id);
if (order == null) if (order == null)
{ {
return null; return null;
} }
order.Update(model); order.Update(context, model);
context.SaveChanges(); context.SaveChanges();
return order.GetViewModel; return order.GetViewModel;
} }

View File

@ -1,171 +0,0 @@
// <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 SushiBarDatabaseImplement;
#nullable disable
namespace SushiBarDatabaseImplement.Migrations
{
[DbContext(typeof(SushiBarDatabase))]
[Migration("20240403125318_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Ingredient", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Cost")
.HasColumnType("float");
b.Property<string>("IngredientName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Ingredients");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.Property<int>("SushiId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("SushiId");
b.ToTable("Orders");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<double>("Price")
.HasColumnType("float");
b.Property<string>("SushiName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("ListSushi");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiIngredient", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("IngredientId")
.HasColumnType("int");
b.Property<int>("SushiId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("IngredientId");
b.HasIndex("SushiId");
b.ToTable("SushiIngredients");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Order", b =>
{
b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi")
.WithMany("Orders")
.HasForeignKey("SushiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Sushi");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.SushiIngredient", b =>
{
b.HasOne("SushiBarDatabaseImplement.Models.Ingredient", "Ingredient")
.WithMany("SushiIngredients")
.HasForeignKey("IngredientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi")
.WithMany("Ingredients")
.HasForeignKey("SushiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Ingredient");
b.Navigation("Sushi");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Ingredient", b =>
{
b.Navigation("SushiIngredients");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Sushi", b =>
{
b.Navigation("Ingredients");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

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

@ -12,8 +12,8 @@ using SushiBarDatabaseImplement;
namespace SushiBarDatabaseImplement.Migrations namespace SushiBarDatabaseImplement.Migrations
{ {
[DbContext(typeof(SushiBarDatabase))] [DbContext(typeof(SushiBarDatabase))]
[Migration("20240501085423_Add_client")] [Migration("20240512150027_6Lab")]
partial class Add_client partial class _6Lab
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -25,6 +25,33 @@ namespace SushiBarDatabaseImplement.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -90,6 +117,9 @@ namespace SushiBarDatabaseImplement.Migrations
b.Property<DateTime?>("DateImplement") b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status") b.Property<int>("Status")
.HasColumnType("int"); .HasColumnType("int");
@ -103,6 +133,8 @@ namespace SushiBarDatabaseImplement.Migrations
b.HasIndex("ClientId"); b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("SushiId"); b.HasIndex("SushiId");
b.ToTable("Orders"); b.ToTable("Orders");
@ -162,6 +194,10 @@ namespace SushiBarDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("SushiBarDataModels.Models.Implementer", "Implementer")
.WithMany("Order")
.HasForeignKey("ImplementerId");
b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi")
.WithMany("Orders") .WithMany("Orders")
.HasForeignKey("SushiId") .HasForeignKey("SushiId")
@ -170,6 +206,8 @@ namespace SushiBarDatabaseImplement.Migrations
b.Navigation("Client"); b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Sushi"); b.Navigation("Sushi");
}); });
@ -192,6 +230,11 @@ namespace SushiBarDatabaseImplement.Migrations
b.Navigation("Sushi"); b.Navigation("Sushi");
}); });
modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b =>
{
b.Navigation("Order");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("Orders");

View File

@ -6,11 +6,42 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace SushiBarDatabaseImplement.Migrations namespace SushiBarDatabaseImplement.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class InitialCreate : Migration public partial class _6Lab : Migration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
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.CreateTable(
name: "Implementers",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
WorkExperience = table.Column<int>(type: "int", nullable: false),
Qualification = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Implementers", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Ingredients", name: "Ingredients",
columns: table => new columns: table => new
@ -47,14 +78,27 @@ namespace SushiBarDatabaseImplement.Migrations
.Annotation("SqlServer:Identity", "1, 1"), .Annotation("SqlServer:Identity", "1, 1"),
SushiId = table.Column<int>(type: "int", nullable: false), SushiId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false), Count = table.Column<int>(type: "int", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: false),
Sum = table.Column<double>(type: "float", nullable: false), Sum = table.Column<double>(type: "float", nullable: false),
Status = table.Column<int>(type: "int", nullable: false), Status = table.Column<int>(type: "int", nullable: false),
DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false), DateCreate = table.Column<DateTime>(type: "datetime2", nullable: false),
DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true) DateImplement = table.Column<DateTime>(type: "datetime2", nullable: true),
ImplementerId = table.Column<int>(type: "int", nullable: true)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_Orders", x => x.Id); table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Orders_Implementers_ImplementerId",
column: x => x.ImplementerId,
principalTable: "Implementers",
principalColumn: "Id");
table.ForeignKey( table.ForeignKey(
name: "FK_Orders_ListSushi_SushiId", name: "FK_Orders_ListSushi_SushiId",
column: x => x.SushiId, column: x => x.SushiId,
@ -90,6 +134,16 @@ namespace SushiBarDatabaseImplement.Migrations
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId",
table: "Orders",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_Orders_ImplementerId",
table: "Orders",
column: "ImplementerId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Orders_SushiId", name: "IX_Orders_SushiId",
table: "Orders", table: "Orders",
@ -115,6 +169,12 @@ namespace SushiBarDatabaseImplement.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "SushiIngredients"); name: "SushiIngredients");
migrationBuilder.DropTable(
name: "Clients");
migrationBuilder.DropTable(
name: "Implementers");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Ingredients"); name: "Ingredients");

View File

@ -22,6 +22,33 @@ namespace SushiBarDatabaseImplement.Migrations
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -87,6 +114,9 @@ namespace SushiBarDatabaseImplement.Migrations
b.Property<DateTime?>("DateImplement") b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status") b.Property<int>("Status")
.HasColumnType("int"); .HasColumnType("int");
@ -100,6 +130,8 @@ namespace SushiBarDatabaseImplement.Migrations
b.HasIndex("ClientId"); b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("SushiId"); b.HasIndex("SushiId");
b.ToTable("Orders"); b.ToTable("Orders");
@ -159,6 +191,10 @@ namespace SushiBarDatabaseImplement.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("SushiBarDataModels.Models.Implementer", "Implementer")
.WithMany("Order")
.HasForeignKey("ImplementerId");
b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi") b.HasOne("SushiBarDatabaseImplement.Models.Sushi", "Sushi")
.WithMany("Orders") .WithMany("Orders")
.HasForeignKey("SushiId") .HasForeignKey("SushiId")
@ -167,6 +203,8 @@ namespace SushiBarDatabaseImplement.Migrations
b.Navigation("Client"); b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Sushi"); b.Navigation("Sushi");
}); });
@ -189,6 +227,11 @@ namespace SushiBarDatabaseImplement.Migrations
b.Navigation("Sushi"); b.Navigation("Sushi");
}); });
modelBuilder.Entity("SushiBarDataModels.Models.Implementer", b =>
{
b.Navigation("Order");
});
modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b => modelBuilder.Entity("SushiBarDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("Orders");

View File

@ -0,0 +1,70 @@
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 SushiBarContracts.BindingModels;
using SushiBarDatabaseImplement.Models;
using SushiBarContracts.ViewModels;
namespace SushiBarDataModels.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; set; }
[Required]
public string ImplementerFIO { get; set; } = string.Empty;
[Required]
public string Password { get; set; } = string.Empty;
[Required]
public int WorkExperience { get; set; }
[Required]
public int Qualification { get; set; }
[ForeignKey("ImplementerId")]
public virtual List<Order> Order { get; set; } = new();
public static Implementer? Create(ImplementerBindingModel? model)
{
if (model == null)
{
return null;
}
return new Implementer()
{
Id = model.Id,
ImplementerFIO = model.ImplementerFIO,
Password = model.Password,
WorkExperience = model.WorkExperience,
Qualification = model.Qualification
};
}
public void Update(ImplementerBindingModel model)
{
if (model == null)
{
return;
}
ImplementerFIO = model.ImplementerFIO;
Password = model.Password;
WorkExperience = model.WorkExperience;
Qualification = model.Qualification;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
ImplementerFIO = ImplementerFIO,
Password = Password,
WorkExperience = WorkExperience,
Qualification = Qualification
};
}
}

View File

@ -24,7 +24,11 @@ namespace SushiBarDatabaseImplement.Models
public int Id { get; set; } public int Id { get; set; }
public virtual Client? Client { get; set; } public virtual Client? Client { get; set; }
public Sushi? Sushi { get; set; } public Sushi? Sushi { get; set; }
public static Order? Create(OrderBindingModel? model) public int? ImplementerId { get; private set; }
public virtual Implementer? Implementer { get; set; } = new();
public static Order? Create(SushiBarDatabase context, OrderBindingModel? model)
{ {
if (model == null) if (model == null)
{ {
@ -39,11 +43,13 @@ namespace SushiBarDatabaseImplement.Models
Status = model.Status, Status = model.Status,
DateCreate = model.DateCreate, DateCreate = model.DateCreate,
DateImplement = model.DateImplement, DateImplement = model.DateImplement,
ClientId = model.ClientId ClientId = model.ClientId,
ImplementerId = model.ImplementerId,
Implementer = model.ImplementerId.HasValue ? context.Implementers.First(x => x.Id == model.ImplementerId) : null,
}; };
} }
public void Update(OrderBindingModel? model) public void Update(SushiBarDatabase context, OrderBindingModel? model)
{ {
if (model == null) if (model == null)
{ {
@ -51,6 +57,8 @@ namespace SushiBarDatabaseImplement.Models
} }
Status = model.Status; Status = model.Status;
DateImplement = model.DateImplement; DateImplement = model.DateImplement;
ImplementerId = model.ImplementerId;
Implementer = model.ImplementerId.HasValue ? context.Implementers.First(x => x.Id == model.ImplementerId) : null;
} }
public OrderViewModel GetViewModel => new() public OrderViewModel GetViewModel => new()
@ -65,6 +73,8 @@ namespace SushiBarDatabaseImplement.Models
DateImplement = DateImplement, DateImplement = DateImplement,
ClientId = ClientId, ClientId = ClientId,
ClientFIO = Client.ClientFIO, ClientFIO = Client.ClientFIO,
ImplementerId = ImplementerId,
ImplementerFIO = Implementer != null ? Implementer.ImplementerFIO : null,
}; };
} }
} }

View File

@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using SushiBarDatabaseImplement.Models; using SushiBarDatabaseImplement.Models;
using SushiBarDataModels.Models;
namespace SushiBarDatabaseImplement namespace SushiBarDatabaseImplement
{ {
@ -21,5 +22,6 @@ namespace SushiBarDatabaseImplement
public virtual DbSet<SushiIngredient> SushiIngredients { set; get; } public virtual DbSet<SushiIngredient> SushiIngredients { set; get; }
public virtual DbSet<Order> Orders { set; get; } public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Client> Clients { set; get; } public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; }
} }
} }

View File

@ -10,10 +10,12 @@ namespace SushiBarFileImplement
private readonly string OrderFileName = "Order.xml"; private readonly string OrderFileName = "Order.xml";
private readonly string SushiFileName = "Sushi.xml"; private readonly string SushiFileName = "Sushi.xml";
private readonly string ClientFileName = "Client.xml"; private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml";
public List<Ingredient> Ingredients { get; private set; } public List<Ingredient> Ingredients { get; private set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<Sushi> ListSushi { get; private set; } public List<Sushi> ListSushi { get; private set; }
public List<Client> Clients { get; private set; } public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; }
public static DataFileSingleton GetInstance() public static DataFileSingleton GetInstance()
{ {
@ -29,12 +31,15 @@ namespace SushiBarFileImplement
"ListSushi", x => x.GetXElement); "ListSushi", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
private DataFileSingleton() private DataFileSingleton()
{ {
Ingredients = LoadData(IngredientFileName, "Ingredient", x => Ingredient.Create(x)!)!; Ingredients = LoadData(IngredientFileName, "Ingredient", x => Ingredient.Create(x)!)!;
ListSushi = LoadData(SushiFileName, "Sushi", x => Sushi.Create(x)!)!; ListSushi = LoadData(SushiFileName, "Sushi", x => Sushi.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!; Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
} }
private static List<T>? LoadData<T>(string filename, string xmlNodeName, private static List<T>? LoadData<T>(string filename, string xmlNodeName,
Func<XElement, T> selectFunction) Func<XElement, T> selectFunction)

View File

@ -0,0 +1,99 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using SushiBarFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarFileImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataFileSingleton _source;
public ImplementerStorage()
{
_source = DataFileSingleton.GetInstance();
}
public List<ImplementerViewModel> GetFullList()
{
return _source.Implementers.Select(x => x.GetViewModel).ToList();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (model == null)
{
return new();
}
if (model.Id.HasValue)
{
var res = GetElement(model);
return res != null ? new() { res } : new();
}
if (model.ImplementerFIO != null)
{
return _source.Implementers
.Where(x => x.ImplementerFIO.Equals(model.ImplementerFIO))
.Select(x => x.GetViewModel)
.ToList();
}
return new();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
if (model.Id.HasValue)
{
return _source.Implementers.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
}
if (model.ImplementerFIO != null && model.Password != null)
{
return _source.Implementers.FirstOrDefault(x => x.ImplementerFIO.Equals(model.ImplementerFIO) && x.Password.Equals(model.Password))?.GetViewModel;
}
if (model.ImplementerFIO != null)
{
return _source.Implementers.FirstOrDefault(x => x.ImplementerFIO.Equals(model.ImplementerFIO))?.GetViewModel;
}
return null;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = _source.Implementers.Count > 0 ? _source.Implementers.Max(x => x.Id) + 1 : 1;
var res = Implementer.Create(model);
if (res != null)
{
_source.Implementers.Add(res);
_source.SaveImplementers();
}
return res?.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
var res = _source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (res != null)
{
res.Update(model);
_source.SaveImplementers();
}
return res?.GetViewModel;
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
var res = _source.Implementers.FirstOrDefault(x => x.Id == model.Id);
if (res != null)
{
_source.Implementers.Remove(res);
_source.SaveImplementers();
}
return res?.GetViewModel;
}
}
}

View File

@ -0,0 +1,87 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace SushiBarFileImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
public static Implementer? Create(XElement element)
{
if (element == null)
{
return null;
}
return new()
{
ImplementerFIO = element.Element("FIO")!.Value,
Password = element.Element("Password")!.Value,
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
Qualification = Convert.ToInt32(element.Element("Qualification")!.Value),
WorkExperience = Convert.ToInt32(element.Element("WorkExperience")!.Value),
};
}
public static Implementer? Create(ImplementerBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Id = model.Id,
Password = model.Password,
Qualification = model.Qualification,
ImplementerFIO = model.ImplementerFIO,
WorkExperience = model.WorkExperience,
};
}
public void Update(ImplementerBindingModel model)
{
if (model == null)
{
return;
}
Password = model.Password;
Qualification = model.Qualification;
ImplementerFIO = model.ImplementerFIO;
WorkExperience = model.WorkExperience;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
Password = Password,
Qualification = Qualification,
ImplementerFIO = ImplementerFIO,
};
public XElement GetXElement => new("Client",
new XAttribute("Id", Id),
new XElement("Password", Password),
new XElement("FIO", ImplementerFIO),
new XElement("Qualification", Qualification),
new XElement("WorkExperience", WorkExperience)
);
}
}

View File

@ -10,12 +10,14 @@ namespace SushiBarListImplement
public List<Order> Orders { get; set; } public List<Order> Orders { get; set; }
public List<Sushi> ListSushi { get; set; } public List<Sushi> ListSushi { get; set; }
public List<Client> Clients { get; set; } public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; }
private DataListSingleton() private DataListSingleton()
{ {
Ingredients = new List<Ingredient>(); Ingredients = new List<Ingredient>();
Orders = new List<Order>(); Orders = new List<Order>();
ListSushi = new List<Sushi>(); ListSushi = new List<Sushi>();
Clients = new List<Client>(); Clients = new List<Client>();
Implementers = new List<Implementer>();
} }
public static DataListSingleton GetInstance() public static DataListSingleton GetInstance()
{ {

View File

@ -0,0 +1,123 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.SearchModels;
using SushiBarContracts.StoragesContracts;
using SushiBarContracts.ViewModels;
using SushiBarListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarListImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
private readonly DataListSingleton _source;
public ImplementerStorage()
{
_source = DataListSingleton.GetInstance();
}
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
for (int i = 0; i < _source.Implementers.Count; ++i)
{
if (_source.Implementers[i].Id == model.Id)
{
var element = _source.Implementers[i];
_source.Implementers.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
foreach (var x in _source.Implementers)
{
if (model.Id.HasValue && x.Id == model.Id)
{
return x.GetViewModel;
}
if (model.ImplementerFIO != null && model.Password != null && x.ImplementerFIO.Equals(model.ImplementerFIO) && x.Password.Equals(model.Password))
{
return x.GetViewModel;
}
if (model.ImplementerFIO != null && x.ImplementerFIO.Equals(model.ImplementerFIO))
{
return x.GetViewModel;
}
}
return null;
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
if (model == null)
{
return new();
}
if (model.Id.HasValue)
{
var res = GetElement(model);
return res != null ? new() { res } : new();
}
List<ImplementerViewModel> result = new();
if (model.ImplementerFIO != null)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.ImplementerFIO.Equals(model.ImplementerFIO))
{
result.Add(implementer.GetViewModel);
}
}
}
return result;
}
public List<ImplementerViewModel> GetFullList()
{
var result = new List<ImplementerViewModel>();
foreach (var implementer in _source.Implementers)
{
result.Add(implementer.GetViewModel);
}
return result;
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
model.Id = 1;
foreach (var implementer in _source.Implementers)
{
if (model.Id <= implementer.Id)
{
model.Id = implementer.Id + 1;
}
}
var res = Implementer.Create(model);
if (res != null)
{
_source.Implementers.Add(res);
}
return res?.GetViewModel;
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
foreach (var implementer in _source.Implementers)
{
if (implementer.Id == model.Id)
{
implementer.Update(model);
return implementer.GetViewModel;
}
}
return null;
}
}
}

View File

@ -0,0 +1,60 @@
using SushiBarContracts.BindingModels;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarListImplement.Models
{
public class Implementer : IImplementerModel
{
public int Id { get; private set; }
public string ImplementerFIO { get; private set; } = string.Empty;
public string Password { get; private set; } = string.Empty;
public int WorkExperience { get; private set; }
public int Qualification { get; private set; }
public static Implementer? Create(ImplementerBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
Id = model.Id,
Password = model.Password,
Qualification = model.Qualification,
ImplementerFIO = model.ImplementerFIO,
WorkExperience = model.WorkExperience,
};
}
public void Update(ImplementerBindingModel model)
{
if (model == null)
{
return;
}
Password = model.Password;
Qualification = model.Qualification;
ImplementerFIO = model.ImplementerFIO;
WorkExperience = model.WorkExperience;
}
public ImplementerViewModel GetViewModel => new()
{
Id = Id,
Password = Password,
Qualification = Qualification,
ImplementerFIO = ImplementerFIO,
};
}
}

View File

@ -4,6 +4,7 @@ using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel; using SushiBarContracts.SearchModel;
using SushiBarContracts.ViewModels; using SushiBarContracts.ViewModels;
namespace SushiBarRestApi.Controllers namespace SushiBarRestApi.Controllers
{ {
[Route("api/[controller]/[action]")] [Route("api/[controller]/[action]")]
@ -61,5 +62,7 @@ namespace SushiBarRestApi.Controllers
throw; throw;
} }
} }
} }
} }

View File

@ -0,0 +1,107 @@
using Microsoft.AspNetCore.Mvc;
using SushiBarContracts.BindingModels;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Enums;
namespace SushiBarRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ImplementerController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IImplementerLogic _logic;
public ImplementerController(IOrderLogic order, IImplementerLogic logic, ILogger<ImplementerController> logger)
{
_logger = logger;
_order = order;
_logic = logic;
}
[HttpGet]
public ImplementerViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ImplementerSearchModel
{
ImplementerFIO = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка авторизации сотрудника");
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetNewOrders()
{
try
{
return _order.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения новых заказов");
throw;
}
}
[HttpGet]
public OrderViewModel? GetImplementerOrder(int implementerId)
{
try
{
return _order.ReadElement(new OrderSearchModel
{
ImplementerId = implementerId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения текущего заказа исполнителя");
throw;
}
}
[HttpPost]
public void TakeOrderInWork(OrderBindingModel model)
{
try
{
_order.TakeOrderInWork(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка перевода заказа с №{Id} в работу", model.Id);
throw;
}
}
[HttpPost]
public void FinishOrder(OrderBindingModel model)
{
try
{
_order.FinishOrder(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа с №{Id}", model.Id);
throw;
}
}
}
}

View File

@ -1,9 +1,7 @@
using DocumentFormat.OpenXml.Office2010.Excel; using DocumentFormat.OpenXml.Office2010.Excel;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SushiBarContracts.BindingModel;
using SushiBarContracts.BindingModels; using SushiBarContracts.BindingModels;
using SushiBarContracts.BusinessLogicsContracts; using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModel;
using SushiBarContracts.SearchModels; using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels; using SushiBarContracts.ViewModels;
@ -42,12 +40,13 @@ namespace SushiBarRestApi.Controllers
{ {
return _sushi.ReadElement(new SushiSearchModel return _sushi.ReadElement(new SushiSearchModel
{ {
Id = sushiId Id =
sushiId
}); });
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка получения суши по id={Id}", sushiId); _logger.LogError(ex, "Ошибка получения продукта по id={Id}", sushiId);
throw; throw;
} }
} }
@ -63,7 +62,7 @@ namespace SushiBarRestApi.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка получения списка заказов клиента id = {Id} ", clientId); _logger.LogError(ex, "Ошибка получения списка заказов id ={ Id} ", clientId);
throw; throw;
} }
} }

View File

@ -1,20 +1,23 @@
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.StoragesContracts;
using SushiBarDatabaseImplement.Implements;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using SushiBarBusinessLogic; using SushiBarBusinessLogic;
using SushiBarBusinessLogic.BusinessLogics; using SushiBarBusinessLogic.BusinessLogics;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.StoragesContracts;
using SushiBarDatabaseImplement.Implements;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config");
// Add services to the container. // Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<ISushiStorage, SushiStorage>(); builder.Services.AddTransient<ISushiStorage, SushiStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<ISushiLogic, SushiLogic>(); builder.Services.AddTransient<ISushiLogic, SushiLogic>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
@ -22,17 +25,18 @@ builder.Services.AddSwaggerGen(c =>
{ {
c.SwaggerDoc("v1", new OpenApiInfo c.SwaggerDoc("v1", new OpenApiInfo
{ {
Title = "SushiBarRestApi", Title = "AbstractShopRestApi",
Version = "v1" Version
= "v1"
}); });
}); });
builder.Services.AddApplicationInsightsTelemetry();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "SushiBarRestApi v1")); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
"AbstractShopRestApi v1"));
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseAuthorization(); app.UseAuthorization();

View File

@ -1,30 +1,20 @@
{ {
"$schema": "http://json.schemastore.org/launchsettings.json", "$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": { "iisSettings": {
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:2876", "applicationUrl": "http://localhost:5419",
"sslPort": 44332 "sslPort": 44379
} }
}, },
"profiles": { "profiles": {
"http": { "SushiBarRestApi": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "http://localhost:5262", "applicationUrl": "https://localhost:7100;http://localhost:5037",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7106;http://localhost:5262",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }

View File

@ -1,3 +0,0 @@
{
"dependencies": {}
}

View File

@ -1,3 +0,0 @@
{
"dependencies": {}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
@ -7,11 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

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

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="logs/SushiBarRestApi.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>
</configuration>