Список word и excel сделан.

Почти сделан pdf (добавил вспомогательный viewmodel так как C# не умеет в кортежи).
Нужно доделать pdf с отправкой на почту и навести красоту (стили, валидацию)
This commit is contained in:
Danil Markov 2023-05-18 21:57:00 +04:00
parent bc6d955ad4
commit 96a6d6bbf7
44 changed files with 1819 additions and 139 deletions

View File

@ -1,4 +1,4 @@
using System; /*using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -108,3 +108,4 @@ namespace UniversityBusinessLogic.BusinessLogics
} }
} }
} }
*/

View File

@ -1,14 +1,13 @@
using System; using UniversityContracts.BindingModels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.ViewModels; using UniversityContracts.ViewModels;
using UniversityContracts.SearchModels; using UniversityContracts.SearchModels;
using UniversityContracts.StoragesContracts; using UniversityContracts.StoragesContracts;
using CarDealershipBusinessLogic.BusinessLogic.OfficePackage;
using UniversityBusinessLogic.OfficePackage; using UniversityBusinessLogic.OfficePackage;
using System.Reflection.PortableExecutable;
using DocumentFormat.OpenXml.InkML;
using DocumentFormat.OpenXml.Wordprocessing;
namespace UniversityBusinessLogic.BusinessLogics namespace UniversityBusinessLogic.BusinessLogics
{ {
@ -20,19 +19,19 @@ namespace UniversityBusinessLogic.BusinessLogics
private readonly IEducationGroupStorage _educationGroupStorage; private readonly IEducationGroupStorage _educationGroupStorage;
private readonly IDisciplineStorage _disciplineStorage; private readonly IDisciplineStorage _disciplineStorage;
private readonly IStreamStorage _streamStorage; private readonly IStreamStorage _streamStorage;
private readonly AbstractSaveToExcelProvider _saveToExcel; private readonly WordBuilderProvider wordBuilder;
private readonly AbstractSaveToWordProvider _saveToWord; private readonly ExcelBuilderProvider excelBuilder;
private readonly AbstractSaveToPdfProvider _saveToPdf; private readonly PdfBuilderProvider pdfBuilder;
public ReportProviderLogic(IDocumentStorage documentStorage, public ReportProviderLogic(IDocumentStorage documentStorage,
IStudentStorage studentStorage, IStudentStorage studentStorage,
IEducationStatusStorage educationStatusStorage, IEducationStatusStorage educationStatusStorage,
IEducationGroupStorage educationGroupStorage, IEducationGroupStorage educationGroupStorage,
IDisciplineStorage disciplineStorage, IDisciplineStorage disciplineStorage,
IStreamStorage streamStorage, IStreamStorage streamStorage,
AbstractSaveToExcelProvider saveToExcel, WordBuilderProvider wordBuilder,
AbstractSaveToWordProvider saveToWord, ExcelBuilderProvider excelBuilder,
AbstractSaveToPdfProvider saveToPdf) PdfBuilderProvider pdfBuilder)
{ {
_documentStorage = documentStorage; _documentStorage = documentStorage;
_studentStorage = studentStorage; _studentStorage = studentStorage;
@ -40,69 +39,96 @@ namespace UniversityBusinessLogic.BusinessLogics
_educationGroupStorage = educationGroupStorage; _educationGroupStorage = educationGroupStorage;
_disciplineStorage = disciplineStorage; _disciplineStorage = disciplineStorage;
_streamStorage = streamStorage; _streamStorage = streamStorage;
_saveToExcel = saveToExcel; this.wordBuilder = wordBuilder;
_saveToWord = saveToWord; this.excelBuilder = excelBuilder;
_saveToPdf = saveToPdf; this.pdfBuilder = pdfBuilder;
} }
public List<ReportStudentsDisciplineViewModel> GetStudentsDiscipline(List<StudentViewModel> students) public List<ReportStudentsDisciplineViewModel> GetStudentsDiscipline(List<StudentViewModel> students)
{ {
var result = students var reportRecords = new List<ReportStudentsDisciplineViewModel>();
.Select(student => new ReportStudentsDisciplineViewModel foreach (var student in students)
{
var disciplines = _studentStorage.GetStudentStreams(new() { Id = student.Id })
.SelectMany(stream => _streamStorage.GetStreamDisciplines(new() { Id = stream.Id }))
.Select(discipline => discipline.Name)
.ToList();
ReportStudentsDisciplineViewModel reportRecord = new()
{ {
StudentFIO = $"{student.Name} {student.Surname}", Student = student.Name + " " + student.Surname + " " + student.StudentCard,
Disciplines = _streamStorage.GetFullList() Disciplines = disciplines
.Where(stream => stream.StudentStream.ContainsKey(student.Id)) };
.Join(_disciplineStorage.GetFullList(), reportRecords.Add(reportRecord);
stream => stream.Id, }
discipline => discipline.StreamId, return reportRecords;
(stream, discipline) => discipline.Name)
.ToList()
})
.ToList();
return result;
} }
public List<ReportStreamStudentEdStatPeriodViewModel> StreamStudentEdStatPeriod(ReportBindingModel model) public List<ReportStreamStudentEdStatPeriodViewModel> GetStreamStudentEdStatPeriod(ReportBindingModel model)
{ {
var result = _streamStorage List<ReportStreamStudentEdStatPeriodViewModel> reportRecords = new List<ReportStreamStudentEdStatPeriodViewModel>();
.GetFilteredList(new StreamSearchModel { UserId = model.UserId })
.Select(stream => new ReportStreamStudentEdStatPeriodViewModel var streams = _streamStorage.GetFilteredList(new StreamSearchModel()
{ {
StreamName = stream.Name, UserId = model.UserId,
StudentEdStatus = stream.StudentStream });
.Where(student => _documentStorage.GetFilteredList(new DocumentSearchModel
{ foreach (var stream in streams)
UserId = model.UserId, {
DateFrom = model.DateFrom, ReportStreamStudentEdStatPeriodViewModel reportData = new ReportStreamStudentEdStatPeriodViewModel();
DateTo = model.DateTo, reportData.StreamName = stream.Name;
})
.Any(document => document.DocumentStudents.Any(x => x.Id == student.Value.Id)))//Выбираем студентов, которые есть в приказах за выбранный промежуток времени var students = _streamStorage.GetStreamStudents(new() { Id = stream.Id })
.Select(student => ( .Select(s => new StudentStatusViewModel()
StudentFIO: $"{student.Value.Name} {student.Value.Surname}", {
EdStatus: _educationStatusStorage.GetElement(new EducationStatusSearchModel { Id = student.Value.EducationStatusId })?.Name ?? "не удалось получить")) StudentName = s.Name + " " + s.Surname,
.ToList() EducationStatus = s.EducationStatusName
}) })
.ToList(); .ToList();
return result;
reportData.StudentStatus = students;
reportRecords.Add(reportData);
}
return reportRecords;
} }
public void SaveBlanksToWordFile(ReportBindingModel model) public byte[] SaveListFile(StudentDisciplineListBindingModel model)
{ {
throw new NotImplementedException(); byte[] file = Array.Empty<byte>();
//TODO if (model.FileType == "docx")
{
wordBuilder.CreateDocument();
wordBuilder.CreateTitle("Список комплектаций по выбранным покупкам");
wordBuilder.CreateStudentsDisciplineTable(GetStudentsDiscipline(model.Students));
file = wordBuilder.GetFile();
}
else if (model.FileType == "xlsx")
{
excelBuilder.CreateDocument();
excelBuilder.CreateTitle("Список комплектаций по выбранным покупкам");
excelBuilder.CreateStudentsDisciplineTable(GetStudentsDiscipline(model.Students));
file = excelBuilder.GetFile();
}
return file;
} }
public void SaveDocumentBlankToExcelFile(ReportBindingModel model) public void SendByMailEducationStatusReport(ReportBindingModel reportModel)
{ {
throw new NotImplementedException(); byte[] file = pdfBuilder.GetEquipmentReportFile(new()
//TODO {
} Title = "Отчет по комплектациям",
DateFrom = reportModel.DateFrom,
public void SaveOrdersToPdfFile(ReportBindingModel model) DateTo = reportModel.DateTo,
{ Records = GetStreamStudentEdStatPeriod(reportModel)
throw new NotImplementedException(); });
//TODO /* mailSender.SendMailAsync(new ()
{
MailAddress = reportModel.UserEmail,
Subject = "Отчет по комплектациям",
Text = $"За период с {reportModel.DateFrom.ToShortDateString()} " +
$"по {reportModel.DateTo.ToShortDateString()}.",
File = file
}); */
} }
} }
} }

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcelProvider
{
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdfProvider
{
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWordProvider
{
}
}

View File

@ -0,0 +1,8 @@
namespace UniversityBusinessLogic.OfficePackage.Enums
{
public enum PdfParagraphAlignmentType
{
Center,
Left
}
}

View File

@ -0,0 +1,356 @@
using UniversityBusinessLogic.OfficePackage.Models;
using UniversityContracts.ViewModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace UniversityBusinessLogic.OfficePackage
{
public class ExcelBuilderProvider
{
private readonly string tempFileName = "temp.xlsx";
private SpreadsheetDocument? spreadsheetDocument;
private SharedStringTablePart? shareStringPart;
private Worksheet? worksheet;
private void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fonts.Append(fontUsual);
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 12D });
fonts.Append(fontTitle);
var fills = new Fills() { Count = 3U };
var fill1 = new Fill();
fill1.Append(new PatternFill()
{
PatternType = PatternValues.None
});
var fill2 = new Fill();
fill2.Append(new PatternFill()
{
PatternType = PatternValues.Gray125
});
var fill3 = new Fill();
fill3.Append(new PatternFill()
{
PatternType = PatternValues.Solid,
ForegroundColor = new()
{
Rgb = "e0e8ff"
}
});
var fill4 = new Fill();
fill1.Append(new PatternFill()
{
PatternType = PatternValues.None
});
fills.Append(fill1);
fills.Append(fill2);
fills.Append(fill3);
fills.Append(fill4);
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var rightBorder = new RightBorder() { Style = BorderStyleValues.Thin };
rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
var bottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin };
bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
CellFormats cellFormats = new() { Count = 4U };
CellFormat cellFormatEmpty = new()
{
FontId = 0U,
FillId = 0U,
BorderId = 1U,
ApplyFont = true
};
CellFormat cellFormatDefault = new()
{
FontId = 0U,
FillId = 3U,
BorderId = 1U,
ApplyFont = true
};
CellFormat cellFormatTitle = new()
{
FontId = 1U,
FillId = 2U,
BorderId = 1U,
ApplyFont = true,
ApplyBorder = true,
Alignment = new Alignment()
{
Vertical = VerticalAlignmentValues.Center,
Horizontal = HorizontalAlignmentValues.Center,
WrapText = true
}
};
cellFormats.Append(cellFormatEmpty);
cellFormats.Append(cellFormatDefault);
cellFormats.Append(cellFormatTitle);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellFormats);
}
public void CreateDocument()
{
spreadsheetDocument = SpreadsheetDocument.Create(tempFileName,
SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
shareStringPart = spreadsheetDocument.WorkbookPart!
.GetPartsOfType<SharedStringTablePart>()
.Any()
? spreadsheetDocument.WorkbookPart
.GetPartsOfType<SharedStringTablePart>()
.First()
: spreadsheetDocument.WorkbookPart
.AddNewPart<SharedStringTablePart>();
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
worksheet = worksheetPart.Worksheet;
}
public void InsertCellInWorksheet(ExcelCellData cellData)
{
if (worksheet == null || shareStringPart == null)
{
return;
}
var sheetData = worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
Row? row = sheetData.Elements<Row>()
.Where(r => r.RowIndex! == cellData.RowIndex)
.FirstOrDefault();
if (row == null)
{
row = new Row() { RowIndex = cellData.RowIndex };
sheetData.Append(row);
}
Cell? cell = row.Elements<Cell>()
.Where(c => c.CellReference!.Value == cellData.CellReference)
.FirstOrDefault();
if (cell == null)
{
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value, cellData.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell()
{
CellReference = cellData.CellReference
};
row.InsertBefore(newCell, refCell);
cell = newCell;
}
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(cellData.Text)));
shareStringPart.SharedStringTable.Save();
cell.CellValue = new CellValue((shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count() - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = cellData.StyleIndex;
}
private void MergeCells(ExcelMergeParameters excelParams)
{
if (worksheet == null)
{
return;
}
MergeCells mergeCells;
if (worksheet.Elements<MergeCells>().Any())
{
mergeCells = worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (worksheet.Elements<CustomSheetView>().Any())
{
worksheet.InsertAfter(mergeCells, worksheet.Elements<CustomSheetView>().First());
}
else
{
worksheet.InsertAfter(mergeCells, worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
private void Save()
{
if (spreadsheetDocument == null)
{
return;
}
spreadsheetDocument.WorkbookPart!.Workbook.Save();
spreadsheetDocument.Dispose();
}
public byte[] GetFile()
{
Save();
byte[] file = File.ReadAllBytes(tempFileName);
File.Delete(tempFileName);
return file;
}
public void CreateTitle(string text)
{
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "B1"
});
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "A",
RowIndex = 1,
Text = text,
StyleIndex = 0
});
}
public void CreateStudentsDisciplineTable(List<ReportStudentsDisciplineViewModel> data)
{
if (worksheet == null || shareStringPart == null)
{
return;
}
Columns columns = new();
Column columnA = new() { Min = 1, Max = 1, Width = 30, CustomWidth = true };
columns.Append(columnA);
Column columnB = new() { Min = 2, Max = 2, Width = 30, CustomWidth = true };
columns.Append(columnB);
worksheet.InsertAt(columns, 0);
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "A",
RowIndex = 2,
Text = "Название предмета",
StyleIndex = 2
});
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "B",
RowIndex = 2,
Text = "ФИО студента",
StyleIndex = 2
});
uint currentRow = 3;
foreach (ReportStudentsDisciplineViewModel student in data)
{
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "A",
RowIndex = currentRow,
Text = student.Student,
StyleIndex = 1
});
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "B",
RowIndex = currentRow,
Text = "",
StyleIndex = 1
});
currentRow++;
foreach (string discipline in student.Disciplines)
{
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "A",
RowIndex = currentRow,
Text = "",
StyleIndex = 1
});
InsertCellInWorksheet(new ExcelCellData
{
ColumnName = "B",
RowIndex = currentRow,
Text = discipline,
StyleIndex = 1
});
currentRow++;
}
}
}
}
}

View File

@ -0,0 +1,15 @@
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class ExcelCellData
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public uint StyleIndex { get; set; } = 0;
}
}

View File

@ -0,0 +1,11 @@
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,13 @@
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class PdfData<T>
{
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<T> Records { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
using UniversityBusinessLogic.OfficePackage.Enums;
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using UniversityBusinessLogic.OfficePackage.Enums;
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace UniversityBusinessLogic.OfficePackage.Models
{
public class WordTableData
{
public List<(string, int)> Columns { get; set; } = new();
public List<List<string>> Rows { get; set; } = new();
}
}

View File

@ -0,0 +1,176 @@
using UniversityBusinessLogic.OfficePackage.Enums;
using UniversityBusinessLogic.OfficePackage.Models;
using UniversityContracts.ViewModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using PdfSharp.Pdf;
namespace CarDealershipBusinessLogic.BusinessLogic.OfficePackage
{
public class PdfBuilderProvider
{
private readonly string tempFileName = "temp.pdf";
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,
_ => ParagraphAlignment.Justify,
};
}
private 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;
}
public void CreateDocument()
{
document = new Document();
DefineStyles(document);
section = document.AddSection();
}
public 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;
}
public void CreateTable(List<string> columns)
{
if (document == null)
{
return;
}
table = document.LastSection.AddTable();
foreach (var elem in columns)
{
table.AddColumn(elem);
}
}
public 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;
}
}
private void Save()
{
var renderer = new PdfDocumentRenderer(true)
{
Document = document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(tempFileName);
}
public byte[] GetFile()
{
Save();
byte[] file = File.ReadAllBytes(tempFileName);
File.Delete(tempFileName);
return file;
}
public byte[] GetEquipmentReportFile(PdfData<ReportStreamStudentEdStatPeriodViewModel> data)
{
CreateDocument();
CreateParagraph(new PdfParagraph
{
Text = data.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"за период с {data.DateFrom.ToShortDateString()} " +
$"по {data.DateTo.ToShortDateString()}",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "5cm", "5cm", "5cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Статус обучения", "Поток", "Количество студентов" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var record in data.Records)
{
List<StudentStatusViewModel> studentsAndStatus = record.StudentStatus;
int recordHeight = studentsAndStatus.Count + 1;
for (int i = 0; i < recordHeight; i++)
{
List<string> cellsData = new() { "", "", "" };
if (i == 0)
{
cellsData[0] = record.StreamName;
CreateRow(new PdfRowParameters
{
Texts = cellsData,
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
continue;
}
int k = i - 1;
if (k < studentsAndStatus.Count)
{
cellsData[1] = studentsAndStatus[k].StudentName;
cellsData[2] = studentsAndStatus[k].EducationStatus;
}
CreateRow(new PdfRowParameters
{
Texts = cellsData,
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
}
return GetFile();
}
}
}

View File

@ -0,0 +1,170 @@
using UniversityBusinessLogic.OfficePackage.Models;
using UniversityContracts.ViewModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace CarDealershipBusinessLogic.BusinessLogic.OfficePackage
{
public class WordBuilderProvider
{
private readonly string tempFileName = "temp.docx";
private WordprocessingDocument? wordDocument;
private Body? documentBody;
public void CreateDocument()
{
wordDocument = WordprocessingDocument.Create(tempFileName,
WordprocessingDocumentType.Document);
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
documentBody = mainPart.Document.AppendChild(new Body());
}
public void CreateParagraph(string text)
{
if (documentBody == null)
{
return;
}
Paragraph paragraph = new();
Run run = new();
run.AppendChild(new Text
{
Text = text
});
paragraph.AppendChild(run);
documentBody.AppendChild(paragraph);
}
public void CreateTitle(string text)
{
if (documentBody == null)
{
return;
}
Paragraph paragraph = new();
Run run = new();
RunProperties properties = new();
properties.AppendChild(new Bold());
run.AppendChild(properties);
run.AppendChild(new Text
{
Text = text
});
paragraph.AppendChild(run);
documentBody.AppendChild(paragraph);
}
private TableCell CreateTableCell(string text, bool inHead = false, int? cellWidth = null)
{
Run run = new();
TableCell tableCell = new();
TableCellProperties cellProperties = new()
{
TableCellWidth = new()
{
Width = cellWidth.ToString()
},
TableCellMargin = new()
{
LeftMargin = new()
{
Width = "100"
}
}
};
if (inHead)
{
Shading shading = new()
{
Color = "auto",
Fill = "e0e8ff",
Val = ShadingPatternValues.Clear
};
cellProperties.Append(shading);
RunProperties properties = new();
properties.AppendChild(new Bold());
run.AppendChild(properties);
}
run.AppendChild(new Text
{
Text = text
});
Paragraph paragraph = new(run);
tableCell.AppendChild(paragraph);
tableCell.Append(cellProperties);
return tableCell;
}
protected void CreateTable(WordTableData tableData)
{
if (documentBody == null || tableData == null)
{
return;
}
var table = new Table();
TableProperties tableProperties = new(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 3 }
)
);
table.AppendChild(tableProperties);
table.Append(new TableRow(tableData.Columns.Select(x => CreateTableCell(x.Item1, true, x.Item2))));
table.Append(tableData.Rows.Select(x => new TableRow(x.Select(y => CreateTableCell(y)))));
documentBody.AppendChild(table);
}
private void Save()
{
if (documentBody == null || wordDocument == null)
{
return;
}
wordDocument.MainDocumentPart!.Document.Save();
wordDocument.Dispose();
}
public byte[] GetFile()
{
Save();
byte[] file = File.ReadAllBytes(tempFileName);
File.Delete(tempFileName);
return file;
}
public void CreateStudentsDisciplineTable(List<ReportStudentsDisciplineViewModel> data)
{
List<List<string>> rows = new();
foreach (ReportStudentsDisciplineViewModel student in data)
{
List<string> disciplineCells = new() { student.Student, "" };
rows.Add(disciplineCells);
List<string> workCells;
foreach (string discipline in student.Disciplines)
{
workCells = new() { "", discipline };
rows.Add(workCells);
}
}
WordTableData wordTable = new()
{
Columns = new List<(string, int)>()
{
("Дисциплина", 3000),
("Студент", 3000)
},
Rows = rows
};
CreateTable(wordTable);
}
}
}

View File

@ -11,9 +11,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="OfficePackage\HelperEnums\" />
<Folder Include="OfficePackage\HelperModels\" />
<Folder Include="OfficePackage\Implements\" /> <Folder Include="OfficePackage\Implements\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
</Project> </Project>

View File

@ -8,10 +8,9 @@ namespace UniversityContracts.BindingModels
{ {
public class ReportBindingModel public class ReportBindingModel
{ {
public string FileName { get; set; } = string.Empty; public string UserEmail { get; set; } = string.Empty;
public string DisciplineName { get; set; } = string.Empty; public DateTime DateFrom { get; set; }
public DateTime? DateFrom { get; set; } public DateTime DateTo { get; set; }
public DateTime? DateTo { get; set; } public int UserId { get; set; }
public int? UserId { get; set; }
} }
} }

View File

@ -13,6 +13,7 @@ namespace UniversityContracts.BindingModels
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public string Surname { get; set; } = string.Empty; public string Surname { get; set; } = string.Empty;
public DateTime DateOfBirth { get; set; } public DateTime DateOfBirth { get; set; }
public DateTime DateOfAddmission { get; set; }
public int StudentCard { get; set; } public int StudentCard { get; set; }
public int? EducationStatusId { get; set; } public int? EducationStatusId { get; set; }
public int UserId { get; set; } public int UserId { get; set; }

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UniversityContracts.ViewModels;
namespace UniversityContracts.BindingModels
{
public class StudentDisciplineListBindingModel
{
public string FileType { get; set; } = string.Empty;
public List<StudentViewModel> Students { get; set; } = new();
}
}

View File

@ -12,12 +12,10 @@ namespace UniversityContracts.BusinessLogicContracts
{ {
List<ReportStudentsDisciplineViewModel> GetStudentsDiscipline(List<StudentViewModel> students); List<ReportStudentsDisciplineViewModel> GetStudentsDiscipline(List<StudentViewModel> students);
List<ReportStreamStudentEdStatPeriodViewModel> StreamStudentEdStatPeriod(ReportBindingModel model); List<ReportStreamStudentEdStatPeriodViewModel> GetStreamStudentEdStatPeriod(ReportBindingModel model);
void SaveBlanksToWordFile(ReportBindingModel model); byte[] SaveListFile(StudentDisciplineListBindingModel model);
void SaveDocumentBlankToExcelFile(ReportBindingModel model); void SendByMailEducationStatusReport(ReportBindingModel reportModel);
void SaveOrdersToPdfFile(ReportBindingModel model);
} }
} }

View File

@ -17,5 +17,7 @@ namespace UniversityContracts.StoragesContracts
StreamViewModel? Insert(StreamBindingModel model); StreamViewModel? Insert(StreamBindingModel model);
StreamViewModel? Update(StreamBindingModel model); StreamViewModel? Update(StreamBindingModel model);
StreamViewModel? Delete(StreamBindingModel model); StreamViewModel? Delete(StreamBindingModel model);
List<DisciplineViewModel> GetStreamDisciplines(StreamSearchModel model);
List<StudentViewModel> GetStreamStudents(StreamSearchModel model);
} }
} }

View File

@ -17,6 +17,7 @@ namespace UniversityContracts.StoragesContracts
StudentViewModel? Insert(StudentBindingModel model); StudentViewModel? Insert(StudentBindingModel model);
StudentViewModel? Update(StudentBindingModel model); StudentViewModel? Update(StudentBindingModel model);
StudentViewModel? Delete(StudentBindingModel model); StudentViewModel? Delete(StudentBindingModel model);
List<StreamViewModel> GetStudentStreams(StudentSearchModel model);
int GetNumberOfPages(int userId, int pageSize); int GetNumberOfPages(int userId, int pageSize);
} }
} }

View File

@ -10,6 +10,6 @@ namespace UniversityContracts.ViewModels
{ {
public int Id { get; set; } public int Id { get; set; }
public string StreamName { get; set; } = string.Empty; public string StreamName { get; set; } = string.Empty;
public List<(string StudentFIO, string EdStatus)> StudentEdStatus { get; set; } = new(); public List<StudentStatusViewModel> StudentStatus { get; set; } = new();
} }
} }

View File

@ -8,7 +8,7 @@ namespace UniversityContracts.ViewModels
{ {
public class ReportStudentsDisciplineViewModel public class ReportStudentsDisciplineViewModel
{ {
public string StudentFIO { get; set; } = string.Empty; public string Student { get; set; } = string.Empty;
public List<string> Disciplines { get; set; } = new(); public List<string> Disciplines { get; set; } = new();
} }
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UniversityContracts.ViewModels
{
public class StudentStatusViewModel
{
public string StudentName { get; set; } = string.Empty;
public string EducationStatus { get; set; } = string.Empty;
}
}

View File

@ -19,6 +19,8 @@ namespace UniversityContracts.ViewModels
public string Surname { get; set; } = string.Empty; public string Surname { get; set; } = string.Empty;
[DisplayName("Дата рождения студента")] [DisplayName("Дата рождения студента")]
public DateTime DateOfBirth { get; set; } = DateTime.Now; public DateTime DateOfBirth { get; set; } = DateTime.Now;
[DisplayName("Дата поступления")]
public DateTime DateOfAddmission { get; set; } = DateTime.Now;
[DisplayName("Статус обучения")] [DisplayName("Статус обучения")]
public string EducationStatusName { get; set; } = string.Empty; public string EducationStatusName { get; set; } = string.Empty;
public int StudentCard { get; set; } public int StudentCard { get; set; }

View File

@ -47,20 +47,6 @@ namespace UniversityDataBaseImplemet.Implements
.Select(record => record.GetViewModel) .Select(record => record.GetViewModel)
.ToList(); .ToList();
} }
else if (model.DateFrom != null && model.DateTo != null && model.UserId.HasValue)
{
return context.Documents
.Where(d => d.Date >= model.DateFrom && d.Date <= model.DateTo && d.UserId == model.UserId)
.Include(d => d.Students)
.ThenInclude(sd => sd.Student)
.ThenInclude(s => s.StudentStream)
.ThenInclude(ss => ss.Stream)
.Include(d => d.Students)
.ThenInclude(sd => sd.Student)
.ThenInclude(s => s.EducationStatus)
.Select(result => result.GetViewModel)
.ToList();
}
else if (model.UserId.HasValue) else if (model.UserId.HasValue)
{ {
return context.Documents return context.Documents

View File

@ -44,7 +44,7 @@ namespace UniversityDataBaseImplemet.Implements
{ {
return context.Streams return context.Streams
.Include(record => record.StreamStudents) .Include(record => record.StreamStudents)
.ThenInclude(record => record.Student) .ThenInclude(record => record.Student)
.Where(record => record.UserId == model.UserId) .Where(record => record.UserId == model.UserId)
.Select(record => record.GetViewModel) .Select(record => record.GetViewModel)
.ToList(); .ToList();
@ -112,5 +112,32 @@ namespace UniversityDataBaseImplemet.Implements
context.SaveChanges(); context.SaveChanges();
return stream.GetViewModel; return stream.GetViewModel;
} }
public List<DisciplineViewModel> GetStreamDisciplines(StreamSearchModel model) {
if (model == null)
{
return new();
}
using var context = new Database();
var disciplines = context.Discipline
.Where(x => x.StreamId == model.Id)
.Select(x => x.GetViewModel)
.ToList();
return disciplines;
}
public List<StudentViewModel> GetStreamStudents(StreamSearchModel model)
{
if (model == null)
{
return new();
}
using var context = new Database();
var students = context.StudentStreams
.Where(x => x.StreamId == model.Id)
.Select(x => x.Student.GetViewModel)
.ToList();
return students;
}
} }
} }

View File

@ -60,6 +60,14 @@ namespace UniversityDataBaseImplemet.Implements
.Select(record => record.GetViewModel) .Select(record => record.GetViewModel)
.ToList(); .ToList();
} }
else if (model.DateFrom != null && model.DateTo != null && model.UserId.HasValue)
{
return context.Students
.Where(s => s.DateOfAddmission >= model.DateFrom && s.DateOfAddmission <= model.DateTo && s.UserId == model.UserId)
.Include(s => s.EducationStatus)
.Select(result => result.GetViewModel)
.ToList();
}
else if (model.UserId.HasValue && model.EducationStatusId.HasValue) else if (model.UserId.HasValue && model.EducationStatusId.HasValue)
{ {
return context.Students return context.Students
@ -152,5 +160,19 @@ namespace UniversityDataBaseImplemet.Implements
int numberOfpages = (int)Math.Ceiling((double)carsCount / pageSize); int numberOfpages = (int)Math.Ceiling((double)carsCount / pageSize);
return numberOfpages != 0 ? numberOfpages : 1; return numberOfpages != 0 ? numberOfpages : 1;
} }
public List<StreamViewModel> GetStudentStreams(StudentSearchModel model)
{
if (model == null)
{
return new();
}
using var context = new Database();
var streams = context.StudentStreams
.Where(x => x.StudentId == model.Id)
.Select(x => x.Stream.GetViewModel)
.ToList();
return streams;
}
} }
} }

View File

@ -0,0 +1,488 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using UniversityDataBaseImplemet;
#nullable disable
namespace UniversityDataBaseImplemet.Migrations
{
[DbContext(typeof(Database))]
[Migration("20230518162032_fix2")]
partial class fix2
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Discipline", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Hours")
.HasColumnType("integer");
b.Property<bool>("MarkType")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("StreamId")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("StreamId");
b.HasIndex("UserId");
b.ToTable("Discipline");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Document", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Documents");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroup", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("NumberOfStudent")
.HasColumnType("integer");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("EducationGroups");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroupDocument", b =>
{
b.Property<int>("EducationGroupId")
.HasColumnType("integer");
b.Property<int>("DocumentId")
.HasColumnType("integer");
b.HasKey("EducationGroupId", "DocumentId");
b.HasIndex("DocumentId");
b.ToTable("EducationGroupsDocuments");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroupStream", b =>
{
b.Property<int>("EducationGroupId")
.HasColumnType("integer");
b.Property<int>("StreamId")
.HasColumnType("integer");
b.HasKey("EducationGroupId", "StreamId");
b.HasIndex("StreamId");
b.ToTable("EducationGroupsStreams");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationStatus", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("EducationStatuses");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Stream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Course")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Streams");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Student", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("DateOfAddmission")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateOfBirth")
.HasColumnType("timestamp with time zone");
b.Property<int?>("EducationStatusId")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("StudentCard")
.HasColumnType("integer");
b.Property<string>("Surname")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("EducationStatusId");
b.HasIndex("UserId");
b.ToTable("Students");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.StudentDocument", b =>
{
b.Property<int>("StudentId")
.HasColumnType("integer");
b.Property<int>("DocumentId")
.HasColumnType("integer");
b.HasKey("StudentId", "DocumentId");
b.HasIndex("DocumentId");
b.ToTable("StudentDocuments");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.StudentStream", b =>
{
b.Property<int>("StudentId")
.HasColumnType("integer");
b.Property<int>("StreamId")
.HasColumnType("integer");
b.HasKey("StudentId", "StreamId");
b.HasIndex("StreamId");
b.ToTable("StudentStreams");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Login")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Discipline", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.Stream", "Stream")
.WithMany()
.HasForeignKey("StreamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("Disciplines")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Stream");
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Document", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("Documents")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroup", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("EducationGroups")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroupDocument", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.Document", "Document")
.WithMany("EducationGroupDocument")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UniversityDataBaseImplemet.Models.EducationGroup", "EducationGroup")
.WithMany("EducationGroupDocument")
.HasForeignKey("EducationGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Document");
b.Navigation("EducationGroup");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroupStream", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.EducationGroup", "EducationGroup")
.WithMany("EducationGroupStream")
.HasForeignKey("EducationGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UniversityDataBaseImplemet.Models.Stream", "Stream")
.WithMany("EducationGroupStream")
.HasForeignKey("StreamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EducationGroup");
b.Navigation("Stream");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationStatus", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("EducationStatuses")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Stream", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("Streams")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Student", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.EducationStatus", "EducationStatus")
.WithMany("Students")
.HasForeignKey("EducationStatusId");
b.HasOne("UniversityDataBaseImplemet.Models.User", "User")
.WithMany("Students")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.NoAction)
.IsRequired();
b.Navigation("EducationStatus");
b.Navigation("User");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.StudentDocument", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.Document", "Document")
.WithMany("Students")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UniversityDataBaseImplemet.Models.Student", "Student")
.WithMany("DocumentStudents")
.HasForeignKey("StudentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Document");
b.Navigation("Student");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.StudentStream", b =>
{
b.HasOne("UniversityDataBaseImplemet.Models.Stream", "Stream")
.WithMany("StreamStudents")
.HasForeignKey("StreamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("UniversityDataBaseImplemet.Models.Student", "Student")
.WithMany("StudentStream")
.HasForeignKey("StudentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Stream");
b.Navigation("Student");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Document", b =>
{
b.Navigation("EducationGroupDocument");
b.Navigation("Students");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationGroup", b =>
{
b.Navigation("EducationGroupDocument");
b.Navigation("EducationGroupStream");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.EducationStatus", b =>
{
b.Navigation("Students");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Stream", b =>
{
b.Navigation("EducationGroupStream");
b.Navigation("StreamStudents");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.Student", b =>
{
b.Navigation("DocumentStudents");
b.Navigation("StudentStream");
});
modelBuilder.Entity("UniversityDataBaseImplemet.Models.User", b =>
{
b.Navigation("Disciplines");
b.Navigation("Documents");
b.Navigation("EducationGroups");
b.Navigation("EducationStatuses");
b.Navigation("Streams");
b.Navigation("Students");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace UniversityDataBaseImplemet.Migrations
{
/// <inheritdoc />
public partial class fix2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "DateOfAddmission",
table: "Students",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DateOfAddmission",
table: "Students");
}
}
}

View File

@ -190,6 +190,9 @@ namespace UniversityDataBaseImplemet.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("DateOfAddmission")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateOfBirth") b.Property<DateTime>("DateOfBirth")
.HasColumnType("timestamp with time zone"); .HasColumnType("timestamp with time zone");

View File

@ -21,6 +21,8 @@ namespace UniversityDataBaseImplemet.Models
[Required] [Required]
public DateTime DateOfBirth { get; set; } public DateTime DateOfBirth { get; set; }
[Required] [Required]
public DateTime DateOfAddmission { get; set; }
[Required]
public int StudentCard { get; set; } public int StudentCard { get; set; }
public int? EducationStatusId { get; set; } public int? EducationStatusId { get; set; }
@ -41,6 +43,7 @@ namespace UniversityDataBaseImplemet.Models
Name = model.Name, Name = model.Name,
Surname = model.Surname, Surname = model.Surname,
DateOfBirth = model.DateOfBirth, DateOfBirth = model.DateOfBirth,
DateOfAddmission = model.DateOfAddmission,
StudentCard = model.StudentCard, StudentCard = model.StudentCard,
EducationStatusId = model.EducationStatusId, EducationStatusId = model.EducationStatusId,
UserId = model.UserId UserId = model.UserId
@ -51,6 +54,7 @@ namespace UniversityDataBaseImplemet.Models
Name = model.Name; Name = model.Name;
Surname = model.Surname; Surname = model.Surname;
DateOfBirth = model.DateOfBirth; DateOfBirth = model.DateOfBirth;
DateOfAddmission = model.DateOfAddmission;
StudentCard = model.StudentCard; StudentCard = model.StudentCard;
EducationStatusId = model.EducationStatusId; EducationStatusId = model.EducationStatusId;
} }
@ -60,6 +64,7 @@ namespace UniversityDataBaseImplemet.Models
Name = Name, Name = Name,
Surname = Surname, Surname = Surname,
DateOfBirth = DateOfBirth, DateOfBirth = DateOfBirth,
DateOfAddmission = DateOfAddmission,
StudentCard = StudentCard, StudentCard = StudentCard,
EducationStatusId = EducationStatusId, EducationStatusId = EducationStatusId,
UserId = UserId, UserId = UserId,

View File

@ -11,6 +11,7 @@ namespace UniversityModels.Models
string Name { get; } string Name { get; }
string Surname { get; } string Surname { get; }
DateTime DateOfBirth { get; } DateTime DateOfBirth { get; }
DateTime DateOfAddmission { get; }
int StudentCard { get; } int StudentCard { get; }
int? EducationStatusId { get; } int? EducationStatusId { get; }
int UserId { get; } int UserId { get; }

View File

@ -43,5 +43,25 @@ namespace UniversityProvider
throw new Exception(result); throw new Exception(result);
} }
} }
public static O? PostRequestWithResult<I, O>(string requestUrl, I model)
{
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var response = _user.PostAsync(requestUrl, data);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (response.Result.IsSuccessStatusCode)
{
var temp = JsonConvert.DeserializeObject<O>(result);
return temp;
}
else
{
return default;
}
}
} }
} }

View File

@ -116,6 +116,42 @@ namespace UniversityProvider.Controllers
return View(); return View();
} }
public IActionResult DisciplineStudentList()
{
return View();
}
[HttpPost]
public int[]? DisciplineStudentList([FromBody] StudentDisciplineListBindingModel listModel)
{
if (APIClient.User == null)
{
return Array.Empty<int>();
}
byte[]? file = APIClient.PostRequestWithResult<StudentDisciplineListBindingModel, byte[]>
("api/reportprovider/studentdisciplinelist", listModel);
return file!.Select(b => (int)b).ToArray();
}
public IActionResult GetReport()
{
return View();
}
[HttpPost]
public List<ReportStreamStudentEdStatPeriodViewModel>? GetReport([FromBody] ReportBindingModel reportModel)
{
if (APIClient.User == null)
{
return new();
}
reportModel.UserId = APIClient.User.Id;
reportModel.UserEmail = APIClient.User.Login;
List<ReportStreamStudentEdStatPeriodViewModel>? list = APIClient.PostRequestWithResult<ReportBindingModel, List<ReportStreamStudentEdStatPeriodViewModel>>
("api/reportprovider/getreportdata", reportModel);
return list;
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error() public IActionResult Error()
{ {

View File

@ -0,0 +1,44 @@
@{
ViewData["Title"] = "Список дисциплин по студентам";
}
<h4 class="fw-bold">Список дисциплин по студентам</h4>
<div id="error-div-shell" class="error-div-shell mb-2">
<div>
<p id="error-p" class="error-p"></p>
</div>
</div>
<select id="file-type">
<option>docx</option>
<option>xlsx</option>
</select>
<button id="create-button" type="button" class="button-primary text-button">
Показать итоговый вариант
</button>
<button id="save-button" type="button" class="button-primary text-button">
Сохранить результат
</button>
<div>
<div class="scrollable-table">
<table class="table table-bordered">
<thead class="thead-light">
<tr>
<th>Имя</th>
<th>Фамилия</th>
<th>Дата рождения</th>
<th>Номер студ. билета</th>
<th>Статус обучения</th>
</tr>
</thead>
<tbody id="scrollable-table__tbody">
</tbody>
</table>
</div>
</div>
<script src="~/js/report/reportlist.js" asp-append-version="true"></script>

View File

@ -1,5 +0,0 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

View File

@ -1,5 +1,30 @@
@* @{
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 ViewData["Title"] = "Список дисциплин по студентам";
*@
@{
} }
<h4 class="fw-bold">Список дисциплин по студентам</h4>
<div id="error-div-shell" class="error-div-shell mb-2">
<div>
<p id="error-p" class="error-p"></p>
</div>
</div>
<div class="d-flex flex-wrap gap-1 align-items-end mb-2">
<div class="mb-2">
<p class="mb-0">Дата начала:</p>
<input id="date-from-input" class="form-control" type="date" />
</div>
<div class="mb-2">
<p class="mb-0">Дата конца:</p>
<input id="date-to-input" class="form-control" type="date" />
</div>
<button id="generate-button" class="button-primary text-button mb-2">
Показать
</button>
<button id="send-by-mail-button" class="button-primary text-button mb-2">
На почту
</button>
</div>
<script src="~/js/report/reportpdf.js" asp-append-version="true"></script>

View File

@ -29,7 +29,7 @@
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="EducationStatuses">Статусы обучения</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="EducationStatuses">Статусы обучения</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="GetList">Получить список</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="DisciplineStudentList">Получить список</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="GetReport">Отчет</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="GetReport">Отчет</a>

View File

@ -0,0 +1,97 @@
const createBtn = document.getElementById("create-button")
const tbody = document.getElementById("scrollable-table__tbody")
const nameInput = document.getElementById("name-input")
var fileType = document.getElementById("file-type")
var students = []
var dataArray = [];
const wordMIME = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
const excelMIME = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
window.addEventListener('load', () => {
$.ajax({
url: "/student/getallbyuser",
type: "GET",
contentType: "json"
}).done((result) => {
students = result;
students.forEach((student) => createRowForStudentsTable(student));
});
})
createBtn.addEventListener('click', () => {
let listModel = {
"Students": Array.from(dataArray),
"FileType": fileType.value
};
$.ajax({
url: "/home/disciplinestudentlist",
type: "POST",
contentType: "application/json",
data: JSON.stringify(listModel)
}).done((file) => {
let byteArray = new Uint8Array(file);
saveFile(byteArray, fileType);
});
})
const saveFile = async function (bytes, fileType) {
if (window.showSaveFilePicker) {
let type;
if (fileType.value == "docx") {
type = {
description: "Microsoft Word (OpenXML)",
accept: { [wordMIME]: [".docx"] }
};
} else if (fileType.value == "xlsx") {
type = {
description: "Microsoft Excel (OpenXML)",
accept: { [excelMIME]: [".xlsx"] }
};
}
const opts = {
suggestedName: `student-discipline-list.${fileType.value}`,
types: [type],
};
const handle = await showSaveFilePicker(opts);
const writable = await handle.createWritable();
await writable.write(bytes);
writable.close();
}
}
const createRowForStudentsTable = (student) => {
const { id, name, surname, dateOfBirth, studentCard, educationStatusName } = student;
const row = tbody.insertRow();
row.setAttribute("data-id", id);
const cells = [name, surname, formatDate(dateOfBirth), studentCard, educationStatusName];
cells.forEach((value) => {
const cell = row.insertCell();
cell.textContent = value;
});
row.addEventListener('click', () => addAndRemoveFromList(row));
};
const formatDate = (dateString) => {
const date = new Date(dateString);
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
return `${year}-${month}-${day}`;
};
const addAndRemoveFromList = (row) => {
var id = parseInt(row.dataset.id);
console.log(students.find(x => x.id === id))
var index = dataArray.indexOf(students.find(x => x.id === id));
if (index === -1) {
dataArray.push(students.find(x => x.id === id));
row.classList.add("bg-success");
} else {
dataArray.splice(index, 1);
row.classList.remove("bg-success");
}
console.log(dataArray);
}

View File

@ -0,0 +1,44 @@
const dateFromInput = document.getElementById("date-from-input");
const dateToInput = document.getElementById("date-to-input");
const generateButton = document.getElementById("generate-button");
const sendByMailButton = document.getElementById("send-by-mail-button");
generateButton.addEventListener("click", () => {
const dateFrom = new Date(dateFromInput.value);
const dateTo = new Date(dateToInput.value);
const reportModel = {
"DateFrom": dateFrom,
"DateTo": dateTo
};
$.ajax({
url: "/home/getreport",
type: "POST",
contentType: "application/json",
data: JSON.stringify(reportModel)
}).done((reportData) => {
/*dateFromSpan.innerHTML = reportModel["DateFrom"].toLocaleDateString();
dateToSpan.innerHTML = reportModel["DateTo"].toLocaleDateString();*/
renderTable(reportData);
});
});
sendByMailButton.addEventListener("click", () => {
const dateFrom = new Date(dateFromInput.value);
const dateTo = new Date(dateToInput.value);
const reportModel = {
"DateFrom": dateFrom,
"DateTo": dateTo
};
$.ajax({
url: "/home/sendbymailequipmentreport",
type: "POST",
contentType: "application/json",
data: JSON.stringify(reportModel)
}).done(() => {
alert("Отчет успешно отправлен на вашу почту!")
});
});
const renderTable = function (reportData) {
console.log(reportData)
}

View File

@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc;
using UniversityContracts.BindingModels;
using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.ViewModels;
namespace UniversityRestAPI.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ReportProviderController : Controller
{
private readonly IReportProviderLogic reportLogic;
public ReportProviderController(IReportProviderLogic reportLogic)
{
this.reportLogic = reportLogic;
}
[HttpPost]
public byte[] StudentDisciplineList(StudentDisciplineListBindingModel listModel)
{
byte[] file = reportLogic.SaveListFile(listModel);
return file;
}
[HttpPost]
public List<ReportStreamStudentEdStatPeriodViewModel> GetReportData(ReportBindingModel reportModel)
{
var list = reportLogic.GetStreamStudentEdStatPeriod(reportModel);
return list;
}
[HttpPost]
public void SendByMailEquipmentReport(ReportBindingModel reportModel)
{
//reportLogic.SendByMailEquipmentReport(reportModel);
}
}
}

View File

@ -1,5 +1,8 @@
using CarDealershipBusinessLogic.BusinessLogic.OfficePackage;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using System.Reflection.PortableExecutable;
using UniversityBusinessLogic.BusinessLogics; using UniversityBusinessLogic.BusinessLogics;
using UniversityBusinessLogic.OfficePackage;
using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicContracts;
using UniversityContracts.StoragesContracts; using UniversityContracts.StoragesContracts;
using UniversityDataBaseImplemet.Implements; using UniversityDataBaseImplemet.Implements;
@ -12,12 +15,21 @@ builder.Services.AddTransient<IStudentStorage, StudentStorage>();
builder.Services.AddTransient<IEducationStatusStorage, EducationStatusStorage>(); builder.Services.AddTransient<IEducationStatusStorage, EducationStatusStorage>();
builder.Services.AddTransient<IDocumentStorage, DocumentStorage>(); builder.Services.AddTransient<IDocumentStorage, DocumentStorage>();
builder.Services.AddTransient<IEducationGroupStorage, EducationGroupStorage>(); builder.Services.AddTransient<IEducationGroupStorage, EducationGroupStorage>();
builder.Services.AddTransient<IDisciplineStorage, DisciplineStorage>();
builder.Services.AddTransient<IStreamStorage, StreamStorage>();
builder.Services.AddTransient<IUserLogic, UserLogic>(); builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<IStudentLogic, StudentLogic>(); builder.Services.AddTransient<IStudentLogic, StudentLogic>();
builder.Services.AddTransient<IEducationStatusLogic, EducationStatusLogic>(); builder.Services.AddTransient<IEducationStatusLogic, EducationStatusLogic>();
builder.Services.AddTransient<IDocumentLogic, DocumentLogic>(); builder.Services.AddTransient<IDocumentLogic, DocumentLogic>();
builder.Services.AddTransient<IEducationGroupLogic, EducationGroupLogic>(); builder.Services.AddTransient<IEducationGroupLogic, EducationGroupLogic>();
builder.Services.AddTransient<IDisciplineLogic, DisciplineLogic>();
builder.Services.AddTransient<IStreamLogic, StreamLogic>();
builder.Services.AddTransient<IReportProviderLogic, ReportProviderLogic>();
builder.Services.AddTransient<WordBuilderProvider>();
builder.Services.AddTransient<ExcelBuilderProvider>();
builder.Services.AddTransient<PdfBuilderProvider>();
builder.Services.AddControllers(); builder.Services.AddControllers();