последние 3 коммита были страшные вебы)

This commit is contained in:
1234 2024-05-01 02:25:19 +04:00
parent 87812cb587
commit 6e000e9b62
22 changed files with 672 additions and 89 deletions

View File

@ -0,0 +1,265 @@
using System.Diagnostics;
using HospitalDirectorApp;
using HospitalDirectorApp.Models;
using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.ViewModels;
using UniversityDirectorApp.Filters;
namespace UniversityDirectorApp.Controllers
{
[AuthorizationFilter]
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IDirectorLogic _employeeLogic;
private readonly IClientLogic _clientLogic;
private readonly IRequirementLogic _requirementLogic;
private readonly IDisciplineLogic _disciplineLogic;
private readonly IAccountLogic _accountLogic;
private readonly IReportLogic _reportLogic;
private DirectorViewModel? _director;
public HomeController(ILogger<HomeController> logger,
IDirectorLogic directorLogic, IClientLogic clientLogic, IRequirementLogic requirementLogic,
IDisciplineLogic disciplineLogic, IAccountLogic accountLogic, IReportLogic reportLogic)
{
_reportLogic = reportLogic;
_accountLogic = accountLogic;
_disciplineLogic = disciplineLogic;
_requirementLogic = requirementLogic;
_clientLogic = clientLogic;
_employeeLogic = directorLogic;
_logger = logger;
}
private DirectorViewModel Director {
get
{
if (_director == null)
{
try
{
_director = _employeeLogic.ReadElement(new()
{
Login = HttpContext.Session.GetString(SessionKeys.DirectorLogin),
Password = HttpContext.Session.GetString(SessionKeys.DirectorPassword),
});
}
catch (Exception e)
{
_logger.LogError(e, "Не удалось получить пользователя, хотя был пройден фильтр авторизации");
throw;
}
}
return _director;
}
}
public IActionResult Index()
{
_logger.LogInformation("Переход на главную страницу");
return View();
}
public IActionResult Privacy()
{
return View(Director);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public IActionResult Clients()
{
return View(_clientLogic.ReadList(new() { DirectorId = Director.Id }));
}
public IActionResult Disciplines()
{
return View(_clientLogic.ReadList(new() { DirectorId = Director.Id }));
}
public IActionResult Requirements()
{
return View(_requirementLogic.ReadList(new() { DirectorId = Director.Id }));
}
public IActionResult ReportFromClients(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(_accountLogic.ReadList(new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
}));
}
if (sendToMail != null)
{
_reportLogic.SendAccountsToEmail(
option: new()
{
DateFrom = DateOnly.FromDateTime(startDate),
DateTo = DateOnly.FromDateTime(endDate)
},
email: Director.Login
);
}
return View();
}
[HttpGet]
public IActionResult Client(int? id)
{
if (id.HasValue)
{
return View(_clientLogic.ReadElement(new() {Id = id}));
}
return View();
}
[HttpPost]
public void Client(string name, int course)
{
var isOperationUpdate = Request.RouteValues.TryGetValue("id", out var identValue);
isOperationUpdate &= int.TryParse((string?)identValue, out var id);
_logger.LogInformation("При изменении клиента были получены данные: {name}; {course}; {idUpdated}", name, course, identValue);
ClientBindingModel model = new()
{
Name = name,
Course = course,
};
if (isOperationUpdate)
{
model.Id = id;
_clientLogic.Update(model);
Response.Redirect("../Clients");
}
else
{
model.DirectorId = Director.Id;
_clientLogic.Create(model);
Response.Redirect("Clients");
}
}
public IActionResult RemoveClient(int id)
{
_clientLogic.Delete(new() { Id = id });
return Redirect("~/Home/Clients");
}
[HttpGet]
public FileResult ReportDisciplinesInWord(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате word");
_logger.LogInformation("Получено {count} клиентов для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SaveDisciplinesToWord(new()
{
Ids = ids,
Stream = mstream,
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportWord.docx");
}
[HttpGet]
public FileResult ReportDisciplinesInExcel(int[] ids)
{
_logger.LogInformation("Запрошен отчет в формате excel");
_logger.LogInformation("Получено {count} клиентов для отчета", ids.Length);
MemoryStream mstream = new();
_reportLogic.SaveDisciplinesToExcel(new()
{
Ids = ids,
Stream = mstream
});
return File(mstream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Octet, "reportExcel.xlsx");
}
public IActionResult Requirement(int? id)
{
if (id.HasValue)
{
return View(_requirementLogic.ReadElement(new() { Id = id }));
}
return View();
}
[HttpPost]
public void Requirement(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);
RequirementBindingModel model = new()
{
NameOfRequirement = name,
Price = price,
};
if (isOperationUpdate)
{
model.Id = id;
_requirementLogic.Update(model);
Response.Redirect("../Requirements");
}
else
{
model.DirectorId = Director.Id;
_requirementLogic.Create(model);
Response.Redirect("Requirements");
}
}
public IActionResult RemoveRequirement(int id)
{
_requirementLogic.Delete(new() { Id = id });
return Redirect("~/Home/Requirements");
}
public IActionResult BindDiscipline(int id)
{
ViewBag.Requirements = _requirementLogic.ReadList(new() { DirectorId = Director.Id });
ViewBag.SelectedId = id;
ViewBag.Disciplines = _disciplineLogic.ReadList();
return View();
}
[HttpPost]
public void BindDiscipline(int requirement, int discipline, int count)
{
var disciplineModel = _disciplineLogic.ReadElement(new() { Id = discipline });
_requirementLogic.Update(new()
{
Id = requirement,
Price = _requirementLogic.ReadElement(new() {Id = requirement}).Price,
DisciplinesModels =
{
[discipline] = new() { Count = count, DisciplineId = discipline }
}
});
Response.Redirect("/Home/Requirements");
}
public double CalcRequirementSum(int requirement, int count)
{
return _requirementLogic.ReadElement(new() {Id = requirement}).Price * count;
}
}
}

View File

@ -0,0 +1,9 @@
namespace HospitalDirectorApp.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 UniversityDirectorApp.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,10 +0,0 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View File

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

View File

@ -1,8 +0,0 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

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

View File

@ -0,0 +1,61 @@
@{
ViewData["Title"] = "Привязка требований к дисциплине";
var requirements = new SelectList(ViewBag.Requirements, "Id", "NameOfRequirement");
requirements.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="requirement" name="requirement" class="form-control" asp-items="@requirements"></select>
</div>
</div>
<div class="row mb-2">
<div class="col-2">Дисциплины:</div>
<div class="col-sm-10">
<select id="discipline" name="discipline" class="form-control" asp-items="@(new SelectList(@ViewBag.Disciplines, "Id", "Name"))"></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>
$('#requirement').on('change', check);
$('#count').on('change', check);
function check() {
var count = $('#count').val();
var requirement = $('#requirement').val();
if (count && requirement) {
$.ajax({
method: "POST",
url: "/Home/CalcRequirementSum",
data: { count: count, requirement: requirement },
success: function (result) {
$("#resultSum").val(result);
}
});
};
}
</script>
}

View File

@ -0,0 +1,39 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model UniversityContracts.ViewModels.ClientViewModel?
@{
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="name" placeholder="ФИО">
</div>
</div>
<div class="row mb-2">
<div class="col-2">Номер курса:</div>
<div class="col-sm-10">
<input type="number" class="form-control" name="course" id="course" 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("Изменить");
$("#name").attr('readonly', true);
$("#name").val("@Html.Raw(Model.Name)");
$("#course").val("@Html.Raw(Model.Course)");
</script>
}
}

View File

@ -0,0 +1,33 @@
@using UniversityContracts.ViewModels;
@model List<ClientViewModel>
@{
ViewData["Title"] = "Клиенты";
}
<h1>@ViewData["Title"]</h1>
<div class="text-center">
<a asp-action="Client">Создать нового клиента</a>
<table class="table">
<thead>
<tr>
<th>Фио студента</th>
<th>Курс</th>
<th>Изменить</th>
<th>Удалить</th>
</tr>
</thead>
<tbody>
@foreach (var client in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => client.Name)</td>
<td>@Html.DisplayFor(modelItem => client.Course)</td>
<td><a asp-action="Client" asp-route-id="@client.Id">Изменить</a></td>
<td><a asp-action="RemoveClient" asp-route-id="@client.Id">Удалить</a></td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -0,0 +1,87 @@
@using UniversityContracts.ViewModels;
@model List<ClientViewModel>
@{
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>
</tr>
</thead>
<tbody>
@foreach (var client in Model)
{
<tr>
<td>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="isIncludeInReports" id="@client.Id" checked>
</div>
</td>
<td>@client.Name</td>
<td>@client.Course</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/ReportDisciplinesInWord',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
function reportToExcel() {
$.get({
url: '/Home/ReportDisciplinesInExcel',
xhrFields: {
responseType: 'blob'
},
data: { ids: getIds() },
success: downloadFile
});
}
</script>
}

View File

@ -0,0 +1,7 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Добро пожаловать в университет "Все отчислены"</h1>
</div>

View File

@ -0,0 +1,36 @@
@using UniversityContracts.ViewModels;
@model DirectorViewModel
@{
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_login" placeholder="Логин" value="@Model.Login" 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.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.LastName" 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,57 @@
@model List<UniversityContracts.ViewModels.AccountViewModel>?
@{
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"/>
</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>
</tr>
</thead>
<tbody id="fillReportInpections">
@if (Model != null) {
foreach (var account in Model)
{
<tr>
<td>@(account.Client?.Name ?? string.Empty)</td>
<td>@(account.Discipline?.Name ?? string.Empty)</td>
<td>@(account.ClientByDiscipline?.DateOfClient.ToShortDateString() ?? string.Empty)</td>
<td>@account.DateOfAccount</td>
<td>@account.Price</td>
</tr>
}
}
</tbody>
</table>
</div>

View File

@ -0,0 +1,39 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model UniversityContracts.ViewModels.RequirementViewModel?
@{
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.NameOfRequirement)");
$("#price").val("@Html.Raw(Model.Price)");
</script>
}
}

View File

@ -0,0 +1,37 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model List<UniversityContracts.ViewModels.RequirementViewModel>
@{
ViewData["Title"] = "Требования";
}
<h1>@ViewData["Title"]</h1>
<div class="text-center">
<a asp-action="Requirement">Создать новое требование</a>
<table class="table">
<thead>
<tr>
<th>Логин сотрудника</th>
<th>Название</th>
<th>Стоимость</th>
<th>Изменить</th>
<th>Удалить</th>
<th>Привязка</th>
</tr>
</thead>
<tbody>
@foreach (var requirement in Model)
{
<tr>
<td>@Html.DisplayFor(x => requirement.DirectorLogin)</td>
<td>@Html.DisplayFor(x => requirement.NameOfRequirement)</td>
<td>@Html.DisplayFor(x => requirement.Price)</td>
<td><a asp-action="Requirement" asp-route-id="@requirement.Id">Изменить</a></td>
<td><a asp-action="RemoveRequirement" asp-route-id="@requirement.Id">Удалить</a></td>
<td><a asp-action="BindDiscipline" asp-route-id="@requirement.Id">Привязать дисциплину</a></td>
</tr>
}
</tbody>
</table>
</div>

View File

@ -1,5 +1,4 @@
@page @model ErrorViewModel
@model ErrorModel
@{ @{
ViewData["Title"] = "Error"; ViewData["Title"] = "Error";
} }
@ -16,7 +15,7 @@
<h3>Development Mode</h3> <h3>Development Mode</h3>
<p> <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>
<p> <p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong> <strong>The Development environment shouldn't be enabled for deployed applications.</strong>