Compare commits

...

3 Commits

Author SHA1 Message Date
GokaPek
2c4de39d60 Merge branch 'main' of https://git.is.ulstu.ru/StroevVladimir/CourseWork 2024-05-30 00:09:14 +04:00
GokaPek
70560b602e Фильтрация по времени 2024-05-30 00:09:06 +04:00
GokaPek
3da62fe249 На грани нервного срыва 2024-05-29 23:23:53 +04:00
15 changed files with 359 additions and 33 deletions

View File

@ -1,5 +1,4 @@
using UniversityBusinessLogic.OfficePackage; using UniversityBusinessLogic.OfficePackage;
using University.ViewModels;
using UniversityContracts.BindingModels; using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.SearchModels; using UniversityContracts.SearchModels;
@ -12,10 +11,6 @@ namespace UniversityBusinessLogics.BusinessLogics;
public class ReportLogic : IReportLogic public class ReportLogic : IReportLogic
{ {
public List<ReportDisciplineViewModel> GetDisciplines(ReportBindingModel model)
{
throw new NotImplementedException();
}
/*private readonly AbstractSaveToWord _saveToWord; /*private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToExcel _saveToExcel; private readonly AbstractSaveToExcel _saveToExcel;
@ -32,13 +27,13 @@ public class ReportLogic : IReportLogic
private readonly AbstractSaveToPdfWorker _saveToPdfWorker; private readonly AbstractSaveToPdfWorker _saveToPdfWorker;
private readonly AbstractSaveToExcelStorekeeper _saveToExcelStorekeeper; private readonly AbstractSaveToExcelStorekeeper _saveToExcelStorekeeper;
//private readonly AbstractSaveToPdfWorker _saveToPdfWorker; private readonly AbstractSaveToPdfStorekeeper _saveToPdfStorekeeper;
private readonly AbstractSaveToWordStorekeeper _saveToWordStorekeeper; private readonly AbstractSaveToWordStorekeeper _saveToWordStorekeeper;
public ReportLogic (ITeacherStorage teacherStorage, IDisciplineStorage public ReportLogic (ITeacherStorage teacherStorage, IDisciplineStorage
disciplineStorage, IStudentStorage studentStorage, IStatementStorage statementStorage, disciplineStorage, IStudentStorage studentStorage, IStatementStorage statementStorage,
IPlanOfStudyStorage planOfStudyStorage, AbstractSaveToExcelWorker saveToExcelWorker, AbstractSaveToWordWorker saveToWordWorker IPlanOfStudyStorage planOfStudyStorage, AbstractSaveToExcelWorker saveToExcelWorker, AbstractSaveToWordWorker saveToWordWorker
,AbstractSaveToPdfWorker saveToPdfWorker, AbstractSaveToWordStorekeeper saveToWordStorekeeper, ,AbstractSaveToPdfWorker saveToPdfWorker, AbstractSaveToWordStorekeeper saveToWordStorekeeper,
AbstractSaveToExcelStorekeeper saveToExcelStorekeeper) AbstractSaveToExcelStorekeeper saveToExcelStorekeeper, AbstractSaveToPdfStorekeeper saveToPdfStorekeeper)
{ {
_teacherStorage = teacherStorage; _teacherStorage = teacherStorage;
_disciplineStorage = disciplineStorage; _disciplineStorage = disciplineStorage;
@ -52,6 +47,7 @@ public class ReportLogic : IReportLogic
_saveToWordStorekeeper = saveToWordStorekeeper; _saveToWordStorekeeper = saveToWordStorekeeper;
_saveToExcelStorekeeper = saveToExcelStorekeeper; _saveToExcelStorekeeper = saveToExcelStorekeeper;
_saveToPdfStorekeeper = saveToPdfStorekeeper;
} }
public List<ReportTeacherViewModel> GetTeachers(int userId) public List<ReportTeacherViewModel> GetTeachers(int userId)
{ {
@ -106,7 +102,7 @@ public class ReportLogic : IReportLogic
public List<ReportDisciplineViewModel> GetDisciplines(ReportDateRangeBindingModel model) public List<ReportDisciplineViewModel> GetDisciplines(ReportDateRangeBindingModel model)
{ {
var disciplines = _disciplineStorage.GetFullList(); var disciplines = _disciplineStorage.GetFilteredList(new DisciplineSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo});
var reportDisciplineViewModels = new List<ReportDisciplineViewModel>(); var reportDisciplineViewModels = new List<ReportDisciplineViewModel>();
@ -258,7 +254,12 @@ public class ReportLogic : IReportLogic
public void SendDisciplinesToEmail(ReportDateRangeBindingModel option, string email) public void SendDisciplinesToEmail(ReportDateRangeBindingModel option, string email)
{ {
throw new NotImplementedException(); _saveToPdfWorker.CreateDoc(new PdfInfoWorker
{
FileName = option.FileName,
Title = "Отчёт по дисциплинам",
PlanOfStudyAndStudent = GetPlanOfStudyAndStudents()
});
} }
public void SendPlanOfStudyToEmail(ReportBindingModel option) public void SendPlanOfStudyToEmail(ReportBindingModel option)

View File

@ -0,0 +1,71 @@
using UniversityBusinessLogic.OfficePackage.HelperEnums;
using UniversityBusinessLogic.OfficePackage.HelperModels;
namespace UniversityBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdfStorekeeper
{
public void CreateDoc(PdfInfoStorekeeper info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
CreateTable(new List<string> { "2cm", "3cm", "6cm", "3cm", "4 cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Дисциплина", "План обучения", "Ведомость" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var item in info.Disciplines)
{
foreach (var plOfSt in item.PlanOfStudys) {
foreach (var statement in item.Statements)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { item.DisciplineName, plOfSt, statement},
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
}
}
SavePdf(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfoStorekeeper info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SavePdf(PdfInfoStorekeeper info);
}
}

View File

@ -0,0 +1,16 @@
using UniversityContracts.ViewModels;
namespace UniversityBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfoStorekeeper
{
public string? FileName { get; set; }
public Stream? Stream { get; set; }
public string Title { get; set; } = string.Empty;
public DateOnly DateFrom { get; set; }
public DateOnly DateTo { get; set; }
public List<object> ReportObjects { get; set; } = new();
public List<ReportDisciplineViewModel> Disciplines { get; set; } = new();
}
}

View File

@ -1,5 +1,4 @@
using University.ViewModels; using UniversityContracts.ViewModels;
using UniversityContracts.ViewModels;
namespace UniversityBusinessLogic.OfficePackage.HelperModels namespace UniversityBusinessLogic.OfficePackage.HelperModels
{ {

View File

@ -0,0 +1,115 @@
using UniversityBusinessLogic.OfficePackage.HelperEnums;
using UniversityBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
namespace UniversityBusinessLogic.OfficePackage.Implements
{
public class SaveToPdfStorekeeper : AbstractSaveToPdfStorekeeper
{
private Document? _document;
private Section? _section;
private Table? _table;
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Right => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
/// <summary>
/// Создание стилей для документа
/// </summary>
/// <param name="document"></param>
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfoStorekeeper info)
{
_document = new Document();
DefineStyles(_document);
_document.DefaultPageSetup.Orientation = Orientation.Landscape;
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfoStorekeeper info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -217,6 +217,38 @@ namespace UniversityClientApp.Controllers
} }
} }
/*[HttpGet]
public IActionResult ReportDisciplines()
{
if (APIStorekeeper.Client == null)
{
return Redirect("~/Home/Enter");
}
return View();
}*/
[HttpGet]
public IActionResult ReportDisciplines(DateOnly dateFrom, DateOnly dateTo)
{
if (APIStorekeeper.Client == null)
{
return Redirect("~/Home/Enter");
}
// Ïîëó÷àåì äàííûå îò ñåðâåðà
//var reportData = APIStorekeeper.GetRequest<List<ReportDisciplineViewModel>>($"api/disciplines/GetReportDisciplines?datefrom={dateFrom}&dateto={dateTo}");
// Ïåðåäàåì äàííûå â ÷àñòè÷íîå ïðåäñòàâëåíèå
if (dateFrom == DateOnly.MinValue || dateTo == DateOnly.MaxValue)
{
return View("ReportDisciplines", null);
}
var reportData = APIStorekeeper.GetRequest<List<ReportDisciplineViewModel>>($"api/discipline/getreportdisciplines?datefrom={dateFrom:yyyy-MM-dd}&dateto={dateTo:yyyy-MM-dd}");
return View("ReportDisciplines", reportData);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error() public IActionResult Error()
{ {

View File

@ -8,6 +8,7 @@
<a href="/Home/Teachers">Teachers</a> <a href="/Home/Teachers">Teachers</a>
<a href="/Home/Statements">Statements</a> <a href="/Home/Statements">Statements</a>
<a href="/Home/Report">Report</a> <a href="/Home/Report">Report</a>
<a href="/Home/ReportDisciplines">ReportDisciplines</a>
</div> </div>
<div class="header"> <div class="header">
<img src="" alt="Logo" class="logo"> <img src="" alt="Logo" class="logo">

View File

@ -0,0 +1,42 @@
@using UniversityContracts.ViewModels
@model List<ReportDisciplineViewModel>
<form method="get" action="/Home/ReportDisciplines">
<div class="text-center">
<h2 class="display-4">Отчёт за период по дисциплинам</h2>
</div>
<div class="form-group">
<label class="mb-3" for="dateFrom">Начало периода:</label>
<input type="date" placeholder="Выберите дату начала периода" id="dateFrom" name="dateFrom" />
</div>
<div class="form-group">
<label class="mb-3" for="dateTo">Окончание периода:</label>
<input type="date" placeholder="Выберите дату окончания периода" id="dateTo" name="dateTo" />
</div>
<div class="row">
<div class="col-4"><input type="submit" value="Вывести здесь" class="btn btn-primary" /></div>
</div>
</form>
@if (Model != null && Model.Any())
{
<table class="table" id="reportTable">
<thead>
<tr>
<th>Название дисциплины</th>
<th>Планы обучения</th>
<th>Заявления</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.DisciplineName</td>
<td>@string.Join(", ", item.PlanOfStudys)</td>
<td>@string.Join(", ", item.Statements)</td>
</tr>
}
</tbody>
</table>
}

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using University.ViewModels;
using UniversityContracts.BindingModels; using UniversityContracts.BindingModels;
using UniversityContracts.ViewModels; using UniversityContracts.ViewModels;
@ -17,7 +16,7 @@ namespace UniversityContracts.BusinessLogicContracts
/// <param name="model"></param> /// <param name="model"></param>
/// <returns></returns> /// <returns></returns>
List<ReportTeacherViewModel> GetTeachers(int userId); List<ReportTeacherViewModel> GetTeachers(int userId);
List<ReportDisciplineViewModel> GetDisciplines(ReportBindingModel model); List<ReportDisciplineViewModel> GetDisciplines(ReportDateRangeBindingModel model);
List<ReportPlanOfStudyViewModel> GetPlanOfStudyAndDisciplines(int userId); List<ReportPlanOfStudyViewModel> GetPlanOfStudyAndDisciplines(int userId);
List<ReportPlanOfStudyAndStudentViewModel> GetPlanOfStudyAndStudents(); List<ReportPlanOfStudyAndStudentViewModel> GetPlanOfStudyAndStudents();

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace University.ViewModels namespace UniversityContracts.ViewModels
{ {
public class ReportDisciplineViewModel public class ReportDisciplineViewModel
{ {

View File

@ -94,11 +94,25 @@ namespace UniversityDatabaseImplement.Implements
query = query.Where(x => x.TeacherId == model.TeacherId.Value); query = query.Where(x => x.TeacherId == model.TeacherId.Value);
} }
if (model.DateFrom.HasValue && model.DateTo.HasValue)
/*if (model.DateFrom.HasValue && model.DateTo.HasValue)
{ {
query = query.Where(x => model.DateFrom.Value <= x.Date && x.Date <= model.DateTo.Value); query = query.Where(x => model.DateFrom.Value <= x.Date && x.Date <= model.DateTo.Value);
}*/
var x = query.Select(x => x.GetViewModel).ToList();
var res = new List<DisciplineViewModel>();
foreach (var item in x) {
if (item.Date > model.DateFrom && item.Date < model.DateTo)
{
res.Add(item);
}
} }
return query.Select(x => x.GetViewModel).ToList();
//return query.Select(x => x.GetViewModel).ToList();
return res;
} }

View File

@ -24,21 +24,28 @@ namespace UniversityDatabaseImplement.Implements
return context.Statements.Include(x => x.Teacher).FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; return context.Statements.Include(x => x.Teacher).FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
} }
public List<StatementViewModel> GetFilteredList(StatementSearchModel model) public List<StatementViewModel> GetFilteredList(StatementSearchModel model)
{ {
if (!model.Id.HasValue && !model.Date.HasValue) using var context = new UniversityDatabase();
{
return new();
}
using var context = new UniversityDatabase();
return context.Statements
.Where(x => x.Id == model.Id || model.Date <= x.Date)
.Include(x => x.Teacher)
.Select(x => x.GetViewModel)
.ToList();
}
public List<StatementViewModel> GetFullList() // Фильтр по Id
IQueryable<Statement> query = context.Statements;
if (model.Id.HasValue)
{
query = query.Where(x => x.Id == model.Id.Value);
}
// Фильтр по Date
if (model.Date.HasValue)
{
query = query.Where(x => x.Date <= model.Date.Value);
}
// Загрузка связанных данных
return query.Include(x => x.Teacher).Select(x => x.GetViewModel).ToList();
}
public List<StatementViewModel> GetFullList()
{ {
using var context = new UniversityDatabase(); using var context = new UniversityDatabase();
return context.Statements.Include(x => x.Teacher).Select(x => x.GetViewModel).ToList(); return context.Statements.Include(x => x.Teacher).Select(x => x.GetViewModel).ToList();

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels; using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.BusinessLogicsContracts; using UniversityContracts.BusinessLogicsContracts;
using UniversityContracts.SearchModels; using UniversityContracts.SearchModels;
using UniversityContracts.ViewModels; using UniversityContracts.ViewModels;
@ -12,10 +13,12 @@ namespace UniversityRestApi.Controllers
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IDisciplineLogic _logic; private readonly IDisciplineLogic _logic;
public DisciplineController(IDisciplineLogic logic, ILogger<DisciplineController> logger) private readonly IReportLogic _reportLogic;
public DisciplineController(IDisciplineLogic logic, ILogger<DisciplineController> logger, IReportLogic reportLogic)
{ {
_logic = logic; _logic = logic;
_logger = logger; _logger = logger;
_reportLogic = reportLogic;
} }
[HttpGet] [HttpGet]
public List<DisciplineViewModel>? GetDisciplines(int userId) public List<DisciplineViewModel>? GetDisciplines(int userId)
@ -30,6 +33,33 @@ namespace UniversityRestApi.Controllers
throw; throw;
} }
} }
[HttpGet]
public List<ReportDisciplineViewModel> GetReportDisciplines(DateOnly dateFrom, DateOnly dateTo)
{
try
{
return _reportLogic.GetDisciplines(new ReportDateRangeBindingModel { DateFrom = dateFrom, DateTo = dateTo });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка дисциплин");
throw;
}
}
[HttpPost]
public List<ReportDisciplineViewModel> GetReportDisciplines()
{
try
{
return _reportLogic.GetDisciplines(new ReportDateRangeBindingModel { DateFrom = DateOnly.MinValue, DateTo = DateOnly.MaxValue });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка дисциплин");
throw;
}
}
[HttpPost] [HttpPost]
public void CreateDiscipline(DisciplineBindingModel model) public void CreateDiscipline(DisciplineBindingModel model)
{ {

View File

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using University.ViewModels;
using UniversityContracts.BindingModels; using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.BusinessLogicsContracts; using UniversityContracts.BusinessLogicsContracts;

View File

@ -30,7 +30,7 @@ builder.Services.AddTransient<AbstractSaveToWordWorker, SaveToWordWorker>();
builder.Services.AddTransient<AbstractSaveToPdfWorker, SaveToPdfWorker>(); builder.Services.AddTransient<AbstractSaveToPdfWorker, SaveToPdfWorker>();
builder.Services.AddTransient<AbstractSaveToExcelStorekeeper, SaveToExcelStorekeeper>(); builder.Services.AddTransient<AbstractSaveToExcelStorekeeper, SaveToExcelStorekeeper>();
builder.Services.AddTransient<AbstractSaveToWordStorekeeper, SaveToWordStorekeeper>(); builder.Services.AddTransient<AbstractSaveToWordStorekeeper, SaveToWordStorekeeper>();
// builder.Services.AddTransient<AbstractSaveToPdfStorekeeper, SaveToPdfStorekeeper>(); builder.Services.AddTransient<AbstractSaveToPdfStorekeeper, SaveToPdfStorekeeper>();
builder.Services.AddTransient<IReportLogic, ReportLogic>(); builder.Services.AddTransient<IReportLogic, ReportLogic>();
builder.Services.AddTransient<IUserLogic, UserLogic>(); builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<IDisciplineLogic, DisciplineLogic>(); builder.Services.AddTransient<IDisciplineLogic, DisciplineLogic>();