вроде работает ( ̄^ ̄)ゞ

This commit is contained in:
анна 2024-05-31 00:43:24 +04:00
parent c02fbb98de
commit 2a53eaeef3
138 changed files with 2090 additions and 200 deletions

View File

@ -7,13 +7,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniversityContracts", "Univ
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniversityDataModels", "UniversityDataModels\UniversityDataModels.csproj", "{1E730A79-7DD7-4460-BA94-B054DBA816D4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityBusinessLogics", "UniversityBusinessLogics\UniversityBusinessLogics.csproj", "{D99D794C-7670-4490-9B08-F6CE66314A12}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniversityBusinessLogics", "UniversityBusinessLogics\UniversityBusinessLogics.csproj", "{D99D794C-7670-4490-9B08-F6CE66314A12}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityClientApp", "UniversityClientApp\UniversityClientApp.csproj", "{E23605B5-BA9E-46A9-9A9C-B1ADE5F878EC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniversityDatabaseImplement", "UniversityDatabaseImplement\UniversityDatabaseImplement.csproj", "{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityEmpoyeeApp", "UniversityEmpoyeeApp\UniversityEmpoyeeApp.csproj", "{8B5945B5-28E5-4417-965A-A3771F639436}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityClientApp", "UniversityClientApp\UniversityClientApp.csproj", "{4D04B10F-82E7-4B80-ABAE-E883947E259B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityDatabaseImplement", "UniversityDatabaseImplement\UniversityDatabaseImplement.csproj", "{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversityEmployeeApp", "UniversityEmployeeApp\UniversityEmployeeApp.csproj", "{282D28E9-5839-43B7-9C68-50FA53712B90}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -33,18 +33,18 @@ Global
{D99D794C-7670-4490-9B08-F6CE66314A12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D99D794C-7670-4490-9B08-F6CE66314A12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D99D794C-7670-4490-9B08-F6CE66314A12}.Release|Any CPU.Build.0 = Release|Any CPU
{E23605B5-BA9E-46A9-9A9C-B1ADE5F878EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E23605B5-BA9E-46A9-9A9C-B1ADE5F878EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E23605B5-BA9E-46A9-9A9C-B1ADE5F878EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E23605B5-BA9E-46A9-9A9C-B1ADE5F878EC}.Release|Any CPU.Build.0 = Release|Any CPU
{8B5945B5-28E5-4417-965A-A3771F639436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B5945B5-28E5-4417-965A-A3771F639436}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B5945B5-28E5-4417-965A-A3771F639436}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B5945B5-28E5-4417-965A-A3771F639436}.Release|Any CPU.Build.0 = Release|Any CPU
{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCD0EA34-EC7D-4A7A-AF3E-EFC8D5FB34F3}.Release|Any CPU.Build.0 = Release|Any CPU
{4D04B10F-82E7-4B80-ABAE-E883947E259B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D04B10F-82E7-4B80-ABAE-E883947E259B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D04B10F-82E7-4B80-ABAE-E883947E259B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D04B10F-82E7-4B80-ABAE-E883947E259B}.Release|Any CPU.Build.0 = Release|Any CPU
{282D28E9-5839-43B7-9C68-50FA53712B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{282D28E9-5839-43B7-9C68-50FA53712B90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{282D28E9-5839-43B7-9C68-50FA53712B90}.Release|Any CPU.ActiveCfg = Release|Any CPU
{282D28E9-5839-43B7-9C68-50FA53712B90}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,5 +1,4 @@
using BankContracts.ViewModels;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -9,6 +8,7 @@ using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.SearchModels;
using UniversityContracts.StoragesContracts;
using Microsoft.Extensions.Logging;
using UniversityContracts.ViewModels;
namespace UniversityBusinessLogics.BusinessLogic
{

View File

@ -1,5 +1,4 @@
using BankContracts.ViewModels;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.SearchModels;
namespace UniversityClientApp.Controllers
{
public class AuthorizationController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IClientLogic _clientLogic;
public AuthorizationController(ILogger<HomeController> logger, IClientLogic clientLogic)
{
_clientLogic = clientLogic;
_logger = logger;
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(ClientBindingModel model)
{
if (string.IsNullOrEmpty(model.PhoneNumber) ||
string.IsNullOrEmpty(model.FirstName) ||
string.IsNullOrEmpty(model.MiddleName) ||
string.IsNullOrEmpty(model.LastName) ||
string.IsNullOrEmpty(model.Password))
{
throw new Exception("Все поля должны быть заполнены");
}
_clientLogic.Create(model);
_logger.LogInformation("Зарегистрирован клиент");
Response.Redirect("Enter");
}
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(ClientSearchModel model)
{
if (string.IsNullOrEmpty(model.PhoneNumber) || string.IsNullOrEmpty(model.Password))
{
throw new Exception("Все поля должны быть заполнены");
}
var result = _clientLogic.ReadElement(model);
HttpContext.Session.SetString(SessionKeys.ClientPhoneNumber, model.PhoneNumber);
HttpContext.Session.SetString(SessionKeys.ClientPassword, model.Password);
_logger.LogInformation("Был осуществел вход за клиента {@client} и добавлены его данные в сессию", result);
Response.Redirect("../../Home/Index");
}
}
}

View File

@ -0,0 +1,213 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using UniversityClientApp.Filter;
using UniversityClientApp.Models;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.ViewModels;
using UniversityDataModels.ProxyModels;
namespace UniversityClientApp.Controllers
{
[AuthorizationFilter]
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IClientLogic _clientLogic;
private readonly IPurchaseLogic _purchaseLogic;
private readonly IOperationLogic _carLogic;
private readonly IReportLogic _reportLogic;
private readonly IPaymentLogic _paymentLogic;
private ClientViewModel? _client;
public HomeController(ILogger<HomeController> logger,
IClientLogic clientLogic, IPurchaseLogic purchaseLogic, IOperationLogic carLogic,
IReportLogic reportLogic, IPaymentLogic paymentLogic)
{
_reportLogic = reportLogic;
_clientLogic = clientLogic;
_logger = logger;
_purchaseLogic = purchaseLogic;
_carLogic = carLogic;
_paymentLogic = paymentLogic;
}
public IActionResult Index()
{
return View();
}
private ClientViewModel Client
{
get
{
if (_client == null)
{
try
{
_client = _clientLogic.ReadElement(new()
{
PhoneNumber = HttpContext.Session.GetString(SessionKeys.ClientPhoneNumber),
Password = HttpContext.Session.GetString(SessionKeys.ClientPassword),
});
}
catch (Exception e)
{
_logger.LogError(e, "Не удалось получить пользователя, хотя был пройден фильтр авторизации");
throw;
}
}
return _client;
}
}
public IActionResult Privacy()
{
return View(Client);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public IActionResult Purchases()
{
return View(_purchaseLogic.ReadList(new() { ClientId = Client.Id }));
}
public FileResult ReportOperationsInWord(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате word");
_logger.LogInformation("Получено {count} обследований для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SaveOperationsToWord(new()
{
Ids = ids,
Stream = mstream,
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportWord.docx");
}
public FileResult ReportOperationsInExcel(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате excel");
_logger.LogInformation("Получено {count} операций для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SaveOperationsToExcel(new()
{
Ids = ids,
Stream = mstream
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportExcel.xlsx");
}
public IActionResult PurchasesReport()
{
return View(_purchaseLogic.ReadList(new() { ClientId = Client.Id }));
}
public IActionResult Payment()
{
ViewBag.Purchases = _purchaseLogic.ReadList(new() { ClientId = Client.Id });
return View();
}
public List<OperationViewModel> GetOperations(int purchase)
{
return _carLogic.ReadList(new() { PurchasesIds = new() { purchase } }); ;
}
[HttpGet]
public IActionResult Purchase(int? id)
{
return View(Tuple.Create(
id.HasValue ? _purchaseLogic.ReadElement(new() { Id = id }) : null,
_carLogic.ReadList()));
}
[HttpPost]
public void Purchase(DateTime datePurchase, List<int> carsIds, List<int> countOperations)
{
var isOperationUpdate = Request.RouteValues.TryGetValue("id", out var identValue);
isOperationUpdate &= int.TryParse((string?)identValue, out var id);
_logger.LogInformation("При изменении операции были получены данные:{idUpdated}, {datePurchase}", identValue, datePurchase);
PurchaseBindingModel model = new()
{
DatePurchase = DateOnly.FromDateTime(datePurchase),
OperationsModel = carsIds.Zip(countOperations).ToDictionary(
x => x.First,
x => new OperationByPurchaseModel() { OperationId = x.First, CountOperations = x.Second }
),
};
if (isOperationUpdate)
{
model.Id = id;
_purchaseLogic.Update(model);
Response.Redirect("../Purchases");
}
else
{
model.ClientId = Client.Id;
_purchaseLogic.Create(model);
Response.Redirect("Purchases");
}
}
public IActionResult RemovePurchase(int id)
{
_purchaseLogic.Delete(new() { Id = id });
return Redirect("~/Home/Purchases");
}
[HttpPost]
public Tuple<double, double> CalcPrice(int purchase, int car)
{
_paymentLogic.GetPaymentInfo(new() { OperationId = car, PurchaseId = purchase },
out var fullPrice, out var paidPrice);
return Tuple.Create(paidPrice, fullPrice - paidPrice);
}
[HttpPost]
public void Payment(double resultSum, int purchase, int car)
{
_logger.LogInformation("Получены данные: {resultSum}; {purchase} {car}", resultSum, purchase, car);
_paymentLogic.Create(new()
{
PaidPrice = resultSum,
Date = DateOnly.FromDateTime(DateTime.Now),
OperationByPurchaseId = _purchaseLogic.ReadElement(new() { Id = purchase }).OperationsModel[car].Id,
});
Response.Redirect("/Home/Payment");
}
public IActionResult ReportFromPurchases(string? getReport, string? sendToMail, DateTime startDate, DateTime endDate)
{
_logger.LogInformation("Попытка получить отчет: {@getReport}; {@sendToMail} Период: {0}---{1}", getReport, sendToMail, startDate, endDate);
if (startDate > endDate)
{
throw new Exception("Дата начала больше даты конца периода");
}
if (getReport != null)
{
return View(_purchaseLogic.ReadList(new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
}));
}
if (sendToMail != null)
{
_reportLogic.SendCostsToEmail(
option: new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
},
email: Client.Email
);
}
return View();
}
}
}

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using UniversityContracts.BusinessLogicContracts;
namespace UniversityClientApp.Filter
{
public class AuthorizationFilter : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var logger = context.HttpContext.RequestServices.GetService<ILogger<AuthorizationFilter>>();
var logic = context.HttpContext.RequestServices.GetService<IClientLogic>();
try
{
var client = logic?.ReadElement(new()
{
PhoneNumber = context.HttpContext.Session.GetString(SessionKeys.ClientPhoneNumber),
Password = context.HttpContext.Session.GetString(SessionKeys.ClientPassword),
});
logger?.LogInformation("Авторизован пользователь: {@client}", client);
}
catch (Exception e)
{
logger?.LogInformation(e, "Пользователь не авторизован, либо авторизация не удалась");
context.Result = new RedirectToActionResult("Enter", "Authorization", new());
}
}
}
}

View File

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

View File

@ -1,28 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace UniversityClientApp.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}

View File

@ -1,20 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace UniversityClientApp.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

View File

@ -1,15 +1,13 @@
using Serilog;
using UiversityDatabaseImplement.Implements;
using UniversityBusinessLogics.BusinessLogic;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.StoragesContracts;
using Serilog;
using UniversityDatabaseImplement.Implements;
using UiversityDatabaseImplement.Implements;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityBusinessLogics.OfficePackage;
using UniversityContracts.BindingModels;
var builder = WebApplication.CreateBuilder(args);
@ -82,3 +80,4 @@ app.MapControllerRoute(
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

View File

@ -3,8 +3,8 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59336",
"sslPort": 44306
"applicationUrl": "http://localhost:52370",
"sslPort": 44343
}
},
"profiles": {
@ -12,7 +12,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7141;http://localhost:5196",
"applicationUrl": "https://localhost:7086;http://localhost:5054",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -1,9 +1,8 @@
namespace UniversityClientApp
{
public class SessionKeys
public static class SessionKeys
{
public const string ClientLogic = "AuthenticationClientLogic";
public const string ClientPhoneNumber = "AuthenticationClientPhoneNumber";
public const string ClientPassword = "AuthenticationClientPassword";
}
}

View File

@ -12,12 +12,12 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,26 @@
@{
ViewData["Title"] = "Клиент-вход";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Номер телефона:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="PhoneNumber" placeholder="Номер телефона">
</div>
</div>
<div class="row mb-3">
<div class="col-2">Пароль:</div>
<div class="col-sm-10">
<input type="password" class="form-control" name="Password" placeholder="Пароль">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Войти" class="btn btn-primary" />
</div>
<div class="text-center">
<a class="align-content-center" asp-controller="Authorization" asp-action="Register">Зарегистрироваться.</a>
</div>
</form>

View File

@ -0,0 +1,50 @@
@{
ViewData["Title"] = "Регистрация";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Номер телефона:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="PhoneNumber" placeholder="Номер телефона">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Почта:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="Email" placeholder="Почта">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Фамилия:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="LastName" placeholder="Фамилия">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Имя:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="FirstName" placeholder="Имя">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Отчество:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="MiddleName" placeholder="Отчество">
</div>
</div>
<div class="row mb-3">
<div class="col-2">Пароль:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="Password" placeholder="Пароль">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Зарегистрироваться" class="btn btn-primary" />
</div>
<div class="text-center">
<a class="align-content-center" asp-controller="Authorization" asp-action="Enter">Елси вы зарегестрированы-войдите.</a>
</div>
</form>

View File

@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Добро пожаловать в «Банк «Вы банкрот». Клиент»</h1>
<img src="https://argumenti.ru/images/arhnews/587918.jpg" alt="Logo" />
</div>

View File

@ -0,0 +1,77 @@
@{
ViewData["Title"] = "Оплата операции";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Сделки:</div>
<div class="col-sm-10">
<select id="purchase" name="purchase" class="form-control" asp-items="@(new SelectList(@ViewBag.Purchases, "Id", "Id"))"></select>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Операции:</div>
<div class="col-sm-10">
<select id="car" name="car" class="form-control"></select>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Внесенная сумма:</div>
<div class="col-sm-10">
<input type="number" class="form-control" name ="paidSum" id="paidSum" placeholder="Внесенная сумма" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Сумма к оплате:</div>
<div class="col-sm-10">
<input type="number" class="form-control" name="resultSum" id="resultSum" placeholder="Сумма к оплате">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Оплатить" class="btn btn-primary" id="submit" />
</div>
</form>
@section Scripts
{
<script>
$('#purchase').on('change', updateInspections);
$('#car').on('change', check);
updateInspections();
function updateInspections() {
$.get({
url: "/Home/GetOperations",
data: { purchase: $('#purchase').val() },
success: function(data) {
$('#car').empty();
$.each(data, function(i, car)
{
$('#car').append( new Option(car.mark +" "+ car.model, car.id) );
});
$('#car').val(data[0].id).change();
}
});
}
function check() {
var paidSum = $('#paidSum').val();
var purchase = $('#purchase').val();
var car = $('#car').val();
if (true) {
$.ajax({
method: "POST",
url: "/Home/CalcPrice",
data: { paidSum: paidSum, purchase: purchase, car: car },
success: function (result) {
console.log(result);
$("#paidSum").val(result.item1);
$("#resultSum").val(result.item2);
}
});
};
}
</script>
}

View File

@ -0,0 +1,48 @@
@using UniversityContracts.ViewModels;
@model ClientViewModel
@{
ViewData["Title"] = "Личные данные клиента";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Номер телефона:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_phoneNumber" placeholder="Номер телефона" value="@Model.PhoneNumber" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">почта:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_email" placeholder="почта" value="@Model.Email" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Фамилия:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_first_name" placeholder="Фамилия" value="@Model.LastName" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Имя:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_middle_name" placeholder="Имя" value="@Model.FirstName" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Отчество:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_last_name" placeholder="Отчество" value="@Model.MiddleName" readonly>
</div>
</div>
<div class="row mb-3">
<div class="col-2">Пароль:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="password" placeholder="Пароль" value="@Model.Password" readonly>
</div>
</div>
</form>

View File

@ -0,0 +1,110 @@
@using UniversityContracts.ViewModels
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model Tuple<UniversityContracts.ViewModels.PurchaseViewModel?, List<OperationViewModel>>
@{
ViewData["Title"] = Model.Item1 == null ? "Создание сделки" : "Изменение сделки";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form id="formId" name="formId">
<div class="row mb-2">
<div class="col-2">Дата сделки:</div>
<div class="col-sm-10">
<input type="date" class="form-control" name="datePurchase" id="datePurchase" placeholder="Дата сделки">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Создать" class="btn btn-primary" id="submit"/>
</div>
<table class="table">
<thead>
<tr>
<th>Включить в сделку</th>
<th>Кол-во операций</th>
<th>Логин сотрудника</th>
<th>Вид</th>
<th>Тип</th>
<th>Стоимость</th>
</tr>
</thead>
<tbody>
@foreach (var car in Model.Item2)
{
<tr>
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="cars" id="@car.Id">
</div>
</td>
<td>
<input type="number" class="custom-control-input" name="countOperations" id="date-@car.Id">
</td>
<td>@Html.DisplayFor(modelItem => car.EmployeePhoneNumber)</td>
<td>@Html.DisplayFor(modelItem => car.Mark)</td>
<td>@Html.DisplayFor(modelItem => car.Model)</td>
<td>@Html.DisplayFor(modelItem => car.Price)</td>
</tr>
}
</tbody>
</table>
</form>
@section Scripts
{
@if (Model.Item1 != null)
{
@foreach (var car in Model.Item1.OperationsModel)
{
<script>
$("#@car.Key").attr('checked', true);
$("#date-@car.Key").val("@car.Value.CountOperations");
</script>
}
<script>
$("#submit").val("Изменить");
$("#name").attr('readonly', true);
$("#datePurchase").attr('readonly', true);
$("#datePurchase").val("@Html.Raw(Model.Item1.DatePurchase.ToString("yyyy-MM-dd"))");
</script>
}
<script>
function getInputData() {
const ids = [];
const dates = [];
var res = $("input[name=cars]");
var resDates = $("input[name=countOperations]");
for (var i = 0; i < res.length; i++) {
if (res[i].checked) {
ids.push(res[i].id);
dates.push(resDates[i].value);
}
}
return [ids, dates];
}
const form = document.forms.namedItem("formId");
form.addEventListener("submit", function(event) {
event.preventDefault();
new FormData(form);
});
form.addEventListener("formdata", event => {
let result = getInputData();
$.post({
url: window.location,
data: {
datePurchase: $("#datePurchase").val(),
carsIds: result[0],
countOperations: result[1]
},
success: () => {
window.location.replace("/Home/Purchases");
}
});
});
</script>
}

View File

@ -0,0 +1,33 @@
@using UniversityContracts.ViewModels;
@model List<PurchaseViewModel>
@{
ViewData["Title"] = "Сделки";
}
<h1>@ViewData["Title"]</h1>
<div class="text-center">
<a asp-action="Purchase">Создать сделку</a>
<table class="table">
<thead>
<tr>
<th>Номер телефона клиента</th>
<th>Дата</th>
<th>Изменить</th>
<th>Удалить</th>
</tr>
</thead>
<tbody>
@foreach (var purchase in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => purchase.ClientPhoneNumber)</td>
<td>@Html.Raw(purchase.DatePurchase)</td>
<td><a asp-action="Purchase" asp-route-id="@purchase.Id">Изменить</a></td>
<td><a asp-action="RemovePurchase" asp-route-id="@purchase.Id">Удалить</a></td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -0,0 +1,88 @@
@using UniversityContracts.ViewModels;
@model List<PurchaseViewModel>
@{
ViewData["Title"] = "Отчет по операциям";
}
<h1>@ViewData["Title"]</h1>
<h5>Выбрать сделки, по которым будут включены в отчет операции</h5>
<div class="text-center">
<a id="reportToWord" href="javascript:void(0)" onclick="reportToWord();">Отчет в word</a>
<a id="reportToExcel" href="javascript:void(0)" onclick="reportToExcel();">Отчет в excel</a>
<table class="table">
<thead>
<tr>
<th>Включить в отчет</th>
<th>Сделка</th>
<th>Номер телефона клиента</th>
<th>Дата</th>
</tr>
</thead>
<tbody>
@foreach (var purchase in Model)
{
<tr>
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="isIncludeInReports" id="@purchase.Id" checked>
</div>
</td>
<td>@purchase.Id</td>
<td>@purchase.ClientPhoneNumber</td>
<td>@purchase.DatePurchase</td>
</tr>
}
</tbody>
</table>
</div>
@section Scripts
{
<script>
jQuery.ajaxSettings.traditional = true;
function getIds() {
const ids = [];
var res = $("input[name=isIncludeInReports]");
for (var i = 0; i < res.length; i++) {
if (res[i].checked) {
ids.push(res[i].id);
}
}
return ids;
}
function downloadFile(data, textStatus, request) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = request.getResponseHeader("content-disposition").split(";")[1].split("=")[1];
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
}
function reportToWord() {
$.get({
url: '/Home/ReportOperationsInWord',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
function reportToExcel() {
$.get({
url: '/Home/ReportOperationsInExcel',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
</script>
}

View File

@ -0,0 +1,58 @@
@model List<UniversityContracts.ViewModels.PurchaseViewModel>?
@{
ViewData["Title"] = "Список сделок с затратами";
}
<h1>@ViewData["Title"]</h1>
<form method="post">
<div class="align-content-center row mb-3">
<div class="col-sm-auto">
<label for="startDate">С:</label>
</div>
<div class="col-3">
<input name="startDate" id="startDate" class="form-control" type="date"/>
</div>
<div class="col-sm-auto">
<label for="endDate">По:</label>
</div>
<div class="col-3">
<input name="endDate" id="endDate" class="form-control" type="date" value="@DateTime.Today.ToString("yyyy-MM-dd")" />
</div>
<div class="col-2">
<input type="submit" name="getReport" class="btn btn-primary" value="Сформировать отчет"/>
</div>
<div class="col-3">
<input type="submit" name="sendToMail" class="btn btn-primary" value="Отправить на почту" />
</div>
</div>
</form>
<div class="text-center">
<table class="table">
<thead>
<tr>
<th>Дата сделки</th>
<th>Сделка</th>
<th>Затрата</th>
<th>Сумма затраты</th>
</tr>
</thead>
<tbody id="fillReportPurchase">
@if (Model != null) {
foreach (var purchase in Model)
{
foreach (var cost in purchase.CostViewModels)
{
<tr>
<td>@purchase.DatePurchase</td>
<td>@purchase.Id</td>
<td>@cost.NameOfCost</td>
<td>@(cost.Price * cost.PurchaseModels[purchase.Id].Count)</td>
</tr>
}
}
}
</tbody>
</table>
</div>

View File

@ -1,5 +1,4 @@
@page
@model ErrorModel
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
@ -16,7 +15,7 @@
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Банк клиент</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/AutocenterClientApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Банк клиент</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Authorization" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Authorization" asp-action="Register">Регистрация</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Purchases">Сделки</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="PurchasesReport">Получить список операций</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Payment">Оплата</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="ReportFromPurchases">Получить отчет по сделкам</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2023 - Банк клиент - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -1,3 +1,3 @@
@using UniversityClientApp
@namespace UniversityClientApp.Pages
@using UniversityClientApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,42 +1,9 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/log_.log",
"rollingInterval": "Day",
"outputTemplate": "[{Timestamp:HH:mm:ss.fff}] {Level:u4}: {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Destructure": [
{
"Name": "ToMaximumDepth",
"Args": { "maximumDestructuringDepth": 3 }
},
{
"Name": "ToMaximumStringLength",
"Args": { "maximumStringLength": 100 }
},
{
"Name": "ToMaximumCollectionCount",
"Args": { "maximumCollectionCount": 10 }
}
],
"Properties": {
"Application": "University"
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
},
"AllowedHosts": "*"
}

View File

@ -1,11 +1,11 @@
using BankContracts.ViewModels;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UniversityContracts.BindingModels;
using UniversityContracts.SearchModels;
using UniversityContracts.ViewModels;
namespace UniversityContracts.BusinessLogicContracts
{

View File

@ -1,5 +1,4 @@
using BankContracts.ViewModels;
using UniversityContracts.BindingModels;
using UniversityContracts.BindingModels;
using UniversityContracts.SearchModels;
using UniversityContracts.ViewModels;

View File

@ -1,5 +1,4 @@
using BankContracts.ViewModels;
using UniversityContracts.BindingModels;
using UniversityContracts.BindingModels;
using UniversityContracts.SearchModels;
using UniversityContracts.ViewModels;

View File

@ -5,10 +5,9 @@ using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UniversityContracts.ViewModels;
using UniversityDataModels.ProxyModels;
namespace BankContracts.ViewModels
namespace UniversityContracts.ViewModels
{
public class PaymentViewModel : IPaymentModel
{

View File

@ -5,7 +5,6 @@ using UniversityContracts.ViewModels;
using UniversityDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using BankContracts.ViewModels;
namespace UniversityDatabaseImplement.Implements
{

View File

@ -5,7 +5,7 @@ using UniversityContracts.StoragesContracts;
using UniversityContracts.ViewModels;
using UniversityDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using BankContracts.ViewModels;
namespace UniversityDatabaseImplement.Implements
{

View File

@ -3,7 +3,6 @@ using UniversityContracts.ViewModels;
using UniversityDataModels;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using BankContracts.ViewModels;
namespace UniversityDatabaseImplement.Models
{

View File

@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.SearchModels;
namespace UniversityEmployeeApp.Controllers
{
public class AuthorizationController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IEmployeeLogic _employeeLogic;
public AuthorizationController(ILogger<HomeController> logger, IEmployeeLogic employeeLogic)
{
_employeeLogic = employeeLogic;
_logger = logger;
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(EmployeeBindingModel model)
{
if (string.IsNullOrEmpty(model.PhoneNumber) ||
string.IsNullOrEmpty(model.FirstName) ||
string.IsNullOrEmpty(model.MiddleName) ||
string.IsNullOrEmpty(model.LastName) ||
string.IsNullOrEmpty(model.Post) ||
string.IsNullOrEmpty(model.Password))
{
throw new Exception("Все поля должны быть заполнены");
}
_employeeLogic.Create(model);
_logger.LogInformation("Зарегистрирован работник");
Response.Redirect("Enter");
}
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(EmployeeSearchModel model)
{
if (string.IsNullOrEmpty(model.PhoneNumber) || string.IsNullOrEmpty(model.Password))
{
throw new Exception("Все поля должны быть заполнены");
}
var result = _employeeLogic.ReadElement(model);
HttpContext.Session.SetString(SessionKeys.EmployeePhone, model.PhoneNumber);
HttpContext.Session.SetString(SessionKeys.EmployeePassword, model.Password);
_logger.LogInformation("Был осуществел вход за сотрудника {@employee} и добавлены его данные в сессию", result);
Response.Redirect("../../Home/Index");
}
}
}

View File

@ -0,0 +1,264 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.ViewModels;
using UniversityEmployeeApp.Filters;
using UniversityEmployeeApp.Models;
namespace UniversityEmployeeApp.Controllers
{
[AuthorizationFilter]
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IEmployeeLogic _employeeLogic;
private readonly IOperationLogic _carLogic;
private readonly ICostLogic _costLogic;
private readonly IPurchaseLogic _purchaseLogic;
private readonly IPaymentLogic _paymentLogic;
private readonly IReportLogic _reportLogic;
private EmployeeViewModel? _employee;
public HomeController(ILogger<HomeController> logger,
IEmployeeLogic employeeLogic, IOperationLogic carLogic, ICostLogic costLogic,
IPurchaseLogic purchaseLogic, IPaymentLogic paymentLogic, IReportLogic reportLogic)
{
_reportLogic = reportLogic;
_paymentLogic = paymentLogic;
_purchaseLogic = purchaseLogic;
_costLogic = costLogic;
_carLogic = carLogic;
_employeeLogic = employeeLogic;
_logger = logger;
}
private EmployeeViewModel Employee
{
get
{
if (_employee == null)
{
try
{
_employee = _employeeLogic.ReadElement(new()
{
PhoneNumber = HttpContext.Session.GetString(SessionKeys.EmployeePhone),
Password = HttpContext.Session.GetString(SessionKeys.EmployeePassword),
});
}
catch (Exception e)
{
_logger.LogError(e, "Не удалось получить пользователя, хотя был пройден фильтр авторизации");
throw;
}
}
return _employee;
}
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View(Employee);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public IActionResult Operations()
{
return View(_carLogic.ReadList(new() { EmployeeId = Employee.Id }));
}
public IActionResult Purchases()
{
return View(_carLogic.ReadList(new() { EmployeeId = Employee.Id }));
}
public IActionResult Costs()
{
return View(_costLogic.ReadList(new() { EmployeeId = Employee.Id }));
}
public IActionResult ReportFromOperations(string? getReport, string? sendToMail, DateTime startDate, DateTime endDate)
{
_logger.LogInformation("Попытка получить отчет: {@getReport}; {@sendToMail} Период: {0}---{1}", getReport, sendToMail, startDate, endDate);
if (startDate > endDate)
{
throw new Exception("Дата начала больше даты конца периода");
}
if (getReport != null)
{
return View(_paymentLogic.ReadList(new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
}));
}
if (sendToMail != null)
{
_reportLogic.SendPaymentsToEmail(
option: new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
},
email: Employee.Email
);
}
return View();
}
[HttpGet]
public IActionResult Operation(int? id)
{
if (id.HasValue)
{
return View(_carLogic.ReadElement(new() { Id = id }));
}
return View();
}
[HttpPost]
public void Operation(OperationBindingModel car)
{
var isOperationUpdate = Request.RouteValues.TryGetValue("id", out var identValue);
isOperationUpdate &= int.TryParse((string?)identValue, out var id);
_logger.LogInformation("При изменении обследования были получены данные: {_mark}; {_model}; {idUpdated}", car.Mark, car.Model, identValue);
if (isOperationUpdate)
{
car.Id = id;
_carLogic.Update(car);
Response.Redirect("../Operations");
}
else
{
car.EmployeeId = Employee.Id;
_carLogic.Create(car);
Response.Redirect("Operations");
}
}
public IActionResult RemoveOperation(int id)
{
_carLogic.Delete(new() { Id = id });
return Redirect("~/Home/Operations");
}
[HttpGet]
public FileResult ReportPurchasesInWord(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате word");
_logger.LogInformation("Получено {count} обследований для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SavePurchasesToWord(new()
{
Ids = ids,
Stream = mstream,
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportWord.docx");
}
[HttpGet]
public FileResult ReportPurchasesInExcel(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате excel");
_logger.LogInformation("Получено {count} обследований для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SavePurchasesToExcel(new()
{
Ids = ids,
Stream = mstream
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportExcel.xlsx");
}
public IActionResult Cost(int? id)
{
if (id.HasValue)
{
return View(_costLogic.ReadElement(new() { Id = id }));
}
return View();
}
[HttpPost]
public void Cost(string name, double price)
{
var isOperationUpdate = Request.RouteValues.TryGetValue("id", out var identValue);
isOperationUpdate &= int.TryParse((string?)identValue, out var id);
_logger.LogInformation("При изменении затрат были получены данные: {name}; {price}; {idUpdated}", name, price, identValue);
CostBindingModel model = new()
{
NameOfCost = name,
Price = price,
};
if (isOperationUpdate)
{
model.Id = id;
_costLogic.Update(model);
Response.Redirect("../Costs");
}
else
{
model.EmployeeId = Employee.Id;
_costLogic.Create(model);
Response.Redirect("Costs");
}
}
public IActionResult RemoveCost(int id)
{
_costLogic.Delete(new() { Id = id });
return Redirect("~/Home/Costs");
}
public IActionResult BindPurchase(int id)
{
ViewBag.Costs = _costLogic.ReadList(new() { EmployeeId = Employee.Id });
ViewBag.SelectedId = id;
ViewBag.Purchases = _purchaseLogic.ReadList();
return View();
}
[HttpPost]
public void BindPurchase(int cost, int purchase, int count)
{
var purchaseModel = _purchaseLogic.ReadElement(new() { Id = purchase });
var costmodel = _costLogic.ReadElement(new() { Id = cost });
_costLogic.Update(new()
{
Id = cost,
Price = costmodel.Price,
NameOfCost = costmodel.NameOfCost,
PurchasesModels =
{
[purchase] = new() { Count = count, PurchaseId = purchase }
}
});
Response.Redirect("/Home/Costs");
}
public double CalcCostSum(int cost, int count)
{
return _costLogic.ReadElement(new() { Id = cost }).Price * count;
}
}
}

View File

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using UniversityContracts.BusinessLogicContracts;
namespace UniversityEmployeeApp.Filters
{
public class AuthorizationFilter : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var logger = context.HttpContext.RequestServices.GetService<ILogger<AuthorizationFilter>>();
var logic = context.HttpContext.RequestServices.GetService<IEmployeeLogic>();
try
{
var employee = logic?.ReadElement(new()
{
PhoneNumber = context.HttpContext.Session.GetString(SessionKeys.EmployeePhone),
Password = context.HttpContext.Session.GetString(SessionKeys.EmployeePassword),
});
logger?.LogInformation("Авторизован пользователь: {@employee}", employee);
}
catch (Exception e)
{
logger?.LogInformation(e, "Пользователь не авторизован, либо авторизация не удалась");
context.Result = new RedirectToActionResult("Enter", "Authorization", new());
}
}
}
}

View File

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

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace UniversityEmpoyeeApp.Pages
namespace UniversityEmployeeApp.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace UniversityEmpoyeeApp.Pages
namespace UniversityEmployeeApp.Pages
{
public class IndexModel : PageModel
{

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace UniversityClientApp.Pages
namespace UniversityEmployeeApp.Pages
{
public class PrivacyModel : PageModel
{

View File

@ -3,16 +3,16 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - UniversityClientApp</title>
<title>@ViewData["Title"] - UniversityEmployeeApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/UniversityClientApp.styles.css" asp-append-version="true" />
<link rel="stylesheet" href="~/UniversityEmployeeApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">UniversityClientApp</a>
<a class="navbar-brand" asp-area="" asp-page="/Index">UniversityEmployeeApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
@ -38,7 +38,7 @@
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - UniversityClientApp - <a asp-area="" asp-page="/Privacy">Privacy</a>
&copy; 2024 - UniversityEmployeeApp - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>

View File

@ -0,0 +1,3 @@
@using UniversityEmployeeApp
@namespace UniversityEmployeeApp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,8 +1,8 @@
using Serilog;
using UniversityBusinessLogics.BusinessLogic;
using UniversityBusinessLogics.MailWorker;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityBusinessLogics.OfficePackage;
using UniversityBusinessLogics.OfficePackage.Implements;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.StoragesContracts;

View File

@ -3,16 +3,16 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:53545",
"sslPort": 44305
"applicationUrl": "http://localhost:50386",
"sslPort": 44344
}
},
"profiles": {
"UniversityEmpoyeeApp": {
"UniversityEmployeeApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7138;http://localhost:5122",
"applicationUrl": "https://localhost:7085;http://localhost:5256",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -1,9 +1,8 @@
namespace UniversityEmpoyeeApp
namespace UniversityEmployeeApp
{
public static class SessionKeys
{
public const string EmployeeLogin = "AuthenticationLogin";
public const string EmployeePhone = "AuthenticationPhone";
public const string EmployeePassword = "AuthenticationPassword";
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@ -11,11 +11,14 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" />
</ItemGroup>

View File

@ -0,0 +1,100 @@
@{
ViewData["Title"] = "Сотрудник-вход";
}
<style>
body {
background-color: #f2f2f2;
font-family: Arial, sans-serif;
}
.container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.title {
text-align: center;
font-size: 24px;
color: #333;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
font-size: 14px;
font-weight: bold;
color: #555;
}
.form-control {
width: 100%;
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
.btn {
display: inline-block;
padding: 10px 20px;
font-size: 16px;
color: #fff;
background-color: #337ab7;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn:hover {
background-color: #23527c;
}
.text-center {
text-align: center;
}
.register-link {
display: block;
font-size: 14px;
color: #777;
text-decoration: none;
margin-top: 10px;
}
.register-link:hover {
color: #333;
}
</style>
<div class="container">
<h2 class="title">@ViewData["Title"]</h2>
<form method="post">
<div class="form-group">
<label for="PhoneNumber">Номер телефона:</label>
<input type="text" class="form-control" id="PhoneNumber" name="PhoneNumber" placeholder="Номер телефона">
</div>
<div class="form-group">
<label for="Password">Пароль:</label>
<input type="password" class="form-control" id="Password" name="Password" placeholder="Пароль">
</div>
<div class="text-center">
<input type="submit" value="Войти" class="btn btn-primary" />
</div>
<div class="text-center">
<a class="register-link" asp-controller="Authorization" asp-action="Register">Зарегистрироваться.</a>
</div>
</form>
</div>

View File

@ -0,0 +1,131 @@
@{
ViewData["Title"] = "Регистрация за сотрудника";
}
<style>
body {
background: linear-gradient(to bottom right, #ff6a00, #ee0979);
color: #fff;
font-family: 'Arial', sans-serif;
}
.container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.title {
text-align: center;
font-size: 28px;
color: #333; /* Изменили цвет главной надписи */
margin-bottom: 30px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 5px;
}
.form-control {
width: 100%;
padding: 10px;
font-size: 16px;
border: none;
border-radius: 4px;
background-color: rgba(255, 255, 255, 0.8);
color: #333;
}
.btn {
display: inline-block;
padding: 10px 20px;
font-size: 18px;
font-weight: bold;
color: #fff;
background-color: #ff6a00;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.btn:hover {
background-color: #ee0979;
}
.text-center {
text-align: center;
}
.enter-link {
display: block;
font-size: 14px;
color: #fff;
text-decoration: none;
margin-top: 10px;
}
.enter-link:hover {
color: #ccc;
}
</style>
<div class="container">
<h2 class="title">@ViewData["Title"]</h2>
<form method="post">
<div class="form-group">
<label for="PhoneNumber">Номер телефона:</label>
<input type="text" class="form-control" id="PhoneNumber" name="PhoneNumber" placeholder="Номер телефона">
</div>
<div class="form-group">
<label for="Email">Почта:</label>
<input type="text" class="form-control" id="Email" name="Email" placeholder="Почта">
</div>
<div class="form-group">
<label for="FirstName">Фамилия:</label>
<input type="text" class="form-control" id="FirstName" name="FirstName" placeholder="Фамилия">
</div>
<div class="form-group">
<label for="MiddleName">Имя:</label>
<input type="text" class="form-control" id="MiddleName" name="MiddleName" placeholder="Имя">
</div>
<div class="form-group">
<label for="LastName">Отчество:</label>
<input type="text" class="form-control" id="LastName" name="LastName" placeholder="Отчество">
</div>
<div class="form-group">
<label for="Post">Должность:</label>
<input type="text" class="form-control" id="Post" name="Post" placeholder="Должность">
</div>
<div class="form-group">
<label for="Password">Пароль:</label>
<input type="password" class="form-control" id="Password" name="Password" placeholder="Пароль">
</div>
<div class="text-center">
<input type="submit" value="Зарегистрироваться" class="btn btn-primary" />
</div>
<div class="text-center">
<a class="enter-link" asp-controller="Authorization" asp-action="Enter">Если вы уже зарегистрированы - войдите.</a>
</div>
</form>
</div>

View File

@ -0,0 +1,62 @@
@{
ViewData["Title"] = "Привязка статьи затрат к сделке";
var costs = new SelectList(ViewBag.Costs, "Id", "NameOfCost");
costs.Where(x => Convert.ToInt32(x.Value) == ViewBag.SelectedId).ToList().ForEach(x => x.Selected = true);
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Статья затрат:</div>
<div class="col-sm-10">
<select id="cost" name="cost" class="form-control" asp-items="@costs"></select>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Сделки:</div>
<div class="col-sm-10">
<select id="purchase" name="purchase" class="form-control" asp-items="@(new SelectList(@ViewBag.Purchases, "Id", "Id"))"></select>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Количество:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name ="count" id="count" placeholder="Количество">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Итоговая сумма:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="resultSum" placeholder="Итоговая сумма" readonly>
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Привязать" class="btn btn-primary" id="submit" />
</div>
</form>
@section Scripts
{
<script>
$('#cost').on('change', check);
$('#count').on('change', check);
function check() {
var count = $('#count').val();
var cost = $('#cost').val();
if (count && cost) {
$.ajax({
method: "POST",
url: "/Home/CalcCostSum",
data: { count: count, cost: cost },
success: function (result) {
$("#resultSum").val(result);
}
});
};
}
</script>
</script>
}

View File

@ -0,0 +1,39 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model UniversityContracts.ViewModels.CostViewModel?
@{
ViewData["Title"] = Model == null ? "Создание статьи затрат" : "Изменение статьи затрат";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Название:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" id="input_name" placeholder="Название">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Стоимость:</div>
<div class="col-sm-10">
<input type="number" step="any" class="form-control" name="price" id="price" placeholder="Стоимость">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Создать" class="btn btn-primary" id="submit" />
</div>
</form>
@section Scripts
{
@if (Model != null)
{
<script>
$("#submit").val("Изменить");
$("#input_name").attr('readonly', true);
$("#input_name").val("@Html.Raw(Model.NameOfCost)");
$("#price").val("@Html.Raw(Model.Price)");
</script>
}
}

View File

@ -0,0 +1,35 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model List<UniversityContracts.ViewModels.CostViewModel>
@{
<h1>@ViewData["Title"]</h1>
}
<div class="text-center">
<a asp-action="Cost">Создать новую статью затрат</a>
<table class="table">
<thead>
<tr>
<th>Номер телефона сотрудника</th>
<th>Название</th>
<th>Стоимость</th>
<th>Изменить</th>
<th>Удалить</th>
<th>Привязка</th>
</tr>
</thead>
<tbody>
@foreach (var cost in Model)
{
<tr>
<td>@Html.DisplayFor(x => cost.PhoneNumber)</td>
<td>@Html.DisplayFor(x => cost.NameOfCost)</td>
<td>@Html.DisplayFor(x => cost.Price)</td>
<td><a asp-action="Cost" asp-route-id="@cost.Id">Изменить</a></td>
<td><a asp-action="RemoveCost" asp-route-id="@cost.Id">Удалить</a></td>
<td><a asp-action="BindPurchase" asp-route-id="@cost.Id">Привязать покупку</a></td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -0,0 +1,28 @@
@{
ViewData["Title"] = "Home Page";
}
<style>
body {
background-color: #fff; /* Изменяем фон на белый */
color: #333; /* Цвет текста */
font-family: 'Roboto', sans-serif;
}
.text-center {
text-align: center;
margin-top: 50px;
}
.display-4 {
font-size: 36px;
font-weight: bold;
margin-bottom: 30px;
}
</style>
<div class="text-center">
<h1 class="display-4">Добро пожаловать в «Банк «Вы банкрот». Сотрудник»</h1>
<img src="https://argumenti.ru/images/arhnews/587918.jpg" alt="Logo" />
</div>

View File

@ -0,0 +1,47 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model UniversityContracts.ViewModels.OperationViewModel?
@{
ViewData["Title"] = Model == null ? "Создание операции" : "Изменение операции";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Вид:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="Mark" id="Mark" placeholder="Вид">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Тип:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="Model" id="Model" placeholder="Тип">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Стоимость:</div>
<div class="col-sm-10">
<input type="text" class="form-control" name="Price" id="Price" placeholder="Стоимость">
</div>
</div>
<div class="text-center mb-2">
<input type="submit" value="Создать" class="btn btn-primary" id="submit"/>
</div>
</form>
@if (Model != null)
{
@section Scripts
{
<script>
$("#submit").val("Изменить");
$("#Mark").attr('readonly', true);
$("#Mark").val("@Html.Raw(Model.Mark)");
$("#Model").attr('readonly', true);
$("#Model").val("@Html.Raw(Model.Model)");
$("#Price").val("@Html.Raw(Model.Price)");
</script>
}
}

View File

@ -0,0 +1,37 @@
@using UniversityContracts.ViewModels;
@model List<OperationViewModel>
@{
ViewData["Title"] = "Операция";
}
<h1>@ViewData["Title"]</h1>
<div class="text-center">
<a asp-action="Operation">Создать новый операцию</a>
<table class="table table-striped table-hover" >
<thead>
<tr>
<th>Телефон сотрудника</th>
<th>Вид</th>
<th>Тип</th>
<th>Цена</th>
<th>Изменить</th>
<th>Удалить</th>
</tr>
</thead>
<tbody>
@foreach (var car in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => car.EmployeePhoneNumber)</td>
<td>@Html.DisplayFor(modelItem => car.Mark)</td>
<td>@Html.DisplayFor(modelItem => car.Model)</td>
<td>@Html.DisplayFor(modelItem => car.Price)</td>
<td><a asp-action="Operation" asp-route-id="@car.Id">Изменить</a></td>
<td><a asp-action="RemoveOperation" asp-route-id="@car.Id">Удалить</a></td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -0,0 +1,54 @@
@using UniversityContracts.ViewModels;
@model EmployeeViewModel
@{
ViewData["Title"] = "Личные данные сотрудника";
}
<div>
<h2 class="display-4">@ViewData["Title"]</h2>
</div>
<form method="post">
<div class="row mb-2">
<div class="col-2">Номер телефона:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_phoneNumber" placeholder="Номер телефона" value="@Model.PhoneNumber" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Должность:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_post" placeholder="должность" value="@Model.Post" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">почта:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_email" placeholder="почта" value="@Model.Email" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Фамилия:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_first_name" placeholder="Фамилия" value="@Model.LastName" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Имя:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_middle_name" placeholder="Имя" value="@Model.FirstName" readonly>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Отчество:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="input_last_name" placeholder="Отчество" value="@Model.MiddleName" readonly>
</div>
</div>
<div class="row mb-3">
<div class="col-2">Пароль:</div>
<div class="col-sm-10">
<input type="text" class="form-control" id="password" placeholder="Пароль" value="@Model.Password" readonly>
</div>
</div>
</form>

View File

@ -0,0 +1,89 @@
@using UniversityContracts.ViewModels;
@model List<OperationViewModel>
@{
<h1>@ViewData["Title"]</h1>
}
<h5>Выбрать операцию, по которым будут включены в отчет сделки</h5>
<div class="text-center">
<a id="reportToWord" href="javascript:void(0)" onclick="reportToWord();">Отчет в word</a>
<a id="reportToExcel" href="javascript:void(0)" onclick="reportToExcel();">Отчет в excel</a>
<table class="table">
<thead>
<tr>
<th>Включить в отчет</th>
<th>Номер телефона сотрудника</th>
<th>Вид</th>
<th>Тип</th>
<th>Стоимость</th>
</tr>
</thead>
<tbody>
@foreach (var car in Model)
{
<tr>
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="isIncludeInReports" id="@car.Id" checked>
</div>
</td>
<td>@car.EmployeePhoneNumber</td>
<td>@car.Mark</td>
<td>@car.Model</td>
<td>@car.Price</td>
</tr>
}
</tbody>
</table>
</div>
@section Scripts
{
<script>
jQuery.ajaxSettings.traditional = true;
function getIds() {
const ids = [];
var res = $("input[name=isIncludeInReports]");
for (var i = 0; i < res.length; i++) {
if (res[i].checked) {
ids.push(res[i].id);
}
}
return ids;
}
function downloadFile(data, textStatus, request) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = request.getResponseHeader("content-disposition").split(";")[1].split("=")[1];
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
}
function reportToWord() {
$.get({
url: '/Home/ReportPurchasesInWord',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
function reportToExcel() {
$.get({
url: '/Home/ReportPurchasesInExcel',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
</script>
}

View File

@ -0,0 +1,61 @@
@using UniversityContracts.ViewModels;
@model List<UniversityContracts.ViewModels.PaymentViewModel>?
@{
ViewData["Title"] = "Список операций с оплатами";
}
<h1>@ViewData["Title"]</h1>
<form method="post">
<div class="align-content-center row mb-3">
<div class="col-sm-auto">
<label for="startDate">С:</label>
</div>
<div class="col-3">
<input name="startDate" id="startDate" class="form-control" type="date"/>
</div>
<div class="col-sm-auto">
<label for="endDate">По:</label>
</div>
<div class="col-3">
<input name="endDate" id="endDate" class="form-control" type="date" value="@DateTime.Today.ToString("yyyy-MM-dd")" />
</div>
<div class="col-2">
<input type="submit" name="getReport" class="btn btn-primary" value="Сформировать отчет"/>
</div>
<div class="col-3">
<input type="submit" name="sendToMail" class="btn btn-primary" value="Отправить на почту" />
</div>
</div>
</form>
<div class="text-center">
<table class="table">
<thead>
<tr>
<th>Сделка</th>
<th>Вид операции</th>
<th>Тип операции</th>
<th>Дата оплаты</th>
<th>Внесенная оплата</th>
<th>Полная оплата</th>
</tr>
</thead>
<tbody id="fillReportOperations">
@if (Model != null)
{
foreach (var payment in Model)
{
<tr>
<td>@payment.OperationByPurchase.PurchaseId</td>
<td>@(payment.Operation?.Model ?? string.Empty)</td>
<td>@(payment.Operation?.Mark ?? string.Empty)</td>
<td>@(payment.Date.ToShortDateString() ?? string.Empty)</td>
<td>@payment.PaidPrice</td>
<td>@payment.FullPrice</td>
</tr>
}
}
</tbody>
</table>
</div>

View File

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

View File

@ -3,16 +3,16 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - UniversityEmpoyeeApp</title>
<title>@ViewData["Title"] - BankEmployeeApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/UniversityEmpoyeeApp.styles.css" asp-append-version="true" />
<link rel="stylesheet" href="~/AutocenterEmployeeApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">UniversityEmpoyeeApp</a>
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Банк сотрудник</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
@ -20,10 +20,25 @@
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Operations">Операции</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Authorization" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Authorization" asp-action="Register">Регистрация</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Purchases">Получить список сделок</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Costs">Затраты</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="ReportFromOperations">Получить отчет по операциям</a>
</li>
</ul>
</div>
@ -38,14 +53,12 @@
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - UniversityEmpoyeeApp - <a asp-area="" asp-page="/Privacy">Privacy</a>
&copy; 2023 - BankEmployeeApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

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

View File

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

View File

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

View File

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

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

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