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 University.ViewModels;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.SearchModels;
@ -12,10 +11,6 @@ namespace UniversityBusinessLogics.BusinessLogics;
public class ReportLogic : IReportLogic
{
public List<ReportDisciplineViewModel> GetDisciplines(ReportBindingModel model)
{
throw new NotImplementedException();
}
/*private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToExcel _saveToExcel;
@ -32,13 +27,13 @@ public class ReportLogic : IReportLogic
private readonly AbstractSaveToPdfWorker _saveToPdfWorker;
private readonly AbstractSaveToExcelStorekeeper _saveToExcelStorekeeper;
//private readonly AbstractSaveToPdfWorker _saveToPdfWorker;
private readonly AbstractSaveToPdfStorekeeper _saveToPdfStorekeeper;
private readonly AbstractSaveToWordStorekeeper _saveToWordStorekeeper;
public ReportLogic (ITeacherStorage teacherStorage, IDisciplineStorage
disciplineStorage, IStudentStorage studentStorage, IStatementStorage statementStorage,
IPlanOfStudyStorage planOfStudyStorage, AbstractSaveToExcelWorker saveToExcelWorker, AbstractSaveToWordWorker saveToWordWorker
,AbstractSaveToPdfWorker saveToPdfWorker, AbstractSaveToWordStorekeeper saveToWordStorekeeper,
AbstractSaveToExcelStorekeeper saveToExcelStorekeeper)
AbstractSaveToExcelStorekeeper saveToExcelStorekeeper, AbstractSaveToPdfStorekeeper saveToPdfStorekeeper)
{
_teacherStorage = teacherStorage;
_disciplineStorage = disciplineStorage;
@ -52,6 +47,7 @@ public class ReportLogic : IReportLogic
_saveToWordStorekeeper = saveToWordStorekeeper;
_saveToExcelStorekeeper = saveToExcelStorekeeper;
_saveToPdfStorekeeper = saveToPdfStorekeeper;
}
public List<ReportTeacherViewModel> GetTeachers(int userId)
{
@ -106,7 +102,7 @@ public class ReportLogic : IReportLogic
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>();
@ -258,7 +254,12 @@ public class ReportLogic : IReportLogic
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)

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
{

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)]
public IActionResult Error()
{

View File

@ -8,6 +8,7 @@
<a href="/Home/Teachers">Teachers</a>
<a href="/Home/Statements">Statements</a>
<a href="/Home/Report">Report</a>
<a href="/Home/ReportDisciplines">ReportDisciplines</a>
</div>
<div class="header">
<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.Text;
using System.Threading.Tasks;
using University.ViewModels;
using UniversityContracts.BindingModels;
using UniversityContracts.ViewModels;
@ -17,7 +16,7 @@ namespace UniversityContracts.BusinessLogicContracts
/// <param name="model"></param>
/// <returns></returns>
List<ReportTeacherViewModel> GetTeachers(int userId);
List<ReportDisciplineViewModel> GetDisciplines(ReportBindingModel model);
List<ReportDisciplineViewModel> GetDisciplines(ReportDateRangeBindingModel model);
List<ReportPlanOfStudyViewModel> GetPlanOfStudyAndDisciplines(int userId);
List<ReportPlanOfStudyAndStudentViewModel> GetPlanOfStudyAndStudents();

View File

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

View File

@ -94,11 +94,25 @@ namespace UniversityDatabaseImplement.Implements
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);
}*/
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

@ -26,16 +26,23 @@ namespace UniversityDatabaseImplement.Implements
public List<StatementViewModel> GetFilteredList(StatementSearchModel model)
{
if (!model.Id.HasValue && !model.Date.HasValue)
{
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();
// Фильтр по 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()

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.BusinessLogicsContracts;
using UniversityContracts.SearchModels;
using UniversityContracts.ViewModels;
@ -12,10 +13,12 @@ namespace UniversityRestApi.Controllers
{
private readonly ILogger _logger;
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;
_logger = logger;
_reportLogic = reportLogic;
}
[HttpGet]
public List<DisciplineViewModel>? GetDisciplines(int userId)
@ -30,6 +33,33 @@ namespace UniversityRestApi.Controllers
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]
public void CreateDiscipline(DisciplineBindingModel model)
{

View File

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

View File

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