Compare commits

...

2 Commits

Author SHA1 Message Date
5317b7b563 feat: add import to excel
All checks were successful
Build and Deploy Docker Container / build-and-deploy (push) Successful in 2m33s
.NET Test Pipeline / build-and-test (push) Successful in 2m34s
Made at the request of the customer
2024-10-27 08:25:46 +03:00
665544236f build: add timezone 2024-10-27 07:34:26 +03:00
2 changed files with 166 additions and 0 deletions

View File

@ -77,6 +77,7 @@ jobs:
-e SECURITY_SALT_SIZE=$SECURITY_SALT_SIZE \ -e SECURITY_SALT_SIZE=$SECURITY_SALT_SIZE \
-e ACTUAL_SUB_PATH=api \ -e ACTUAL_SUB_PATH=api \
-e SWAGGER_SUB_PATH=swagger \ -e SWAGGER_SUB_PATH=swagger \
-e TZ=Europe/Moscow \
$DOCKER_IMAGE $DOCKER_IMAGE
" "

View File

@ -0,0 +1,165 @@
using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList;
using Mirea.Api.Dto.Requests;
using Mirea.Api.Endpoint.Configuration.Model;
using OfficeOpenXml;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Controllers.V1;
[ApiVersion("1.0")]
public class ImportController(IMediator mediator, IOptionsSnapshot<GeneralConfig> config) : BaseController
{
// todo: transfer data to storage
private static string GetFaculty(char c) =>
c switch
{
'У' => "ИТУ",
'Б' => "ИКБ",
'Х' => "ИТХТ",
'Э' => "ИПТИП",
'Т' => "ИПТИП",
'Р' => "ИРИ",
'К' => "ИИИ",
'И' => "ИИТ",
'П' => "ИИТ",
_ => throw new ArgumentOutOfRangeException(nameof(c), c, null)
};
/// <summary>
/// Creates an Excel file based on a schedule filter
/// </summary>
/// <param name="request">The request object containing filter criteria.</param>
/// <returns>Excel file</returns>
[HttpPost("ImportToExcel")]
[Produces("application/vnd.ms-excel")]
public async Task<IActionResult> ImportToExcel([FromBody] ScheduleRequest request)
{
var result = (await mediator.Send(new GetScheduleListQuery
{
IsEven = request.IsEven,
DisciplineIds = request.Disciplines,
GroupIds = request.Groups,
LectureHallIds = request.LectureHalls,
ProfessorIds = request.Professors
})).Schedules;
if (result.Count == 0)
return NoContent();
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Расписание");
int row = 1;
int col = 1;
worksheet.Cells[row, col++].Value = "День";
worksheet.Cells[row, col++].Value = "Пара";
worksheet.Cells[row, col++].Value = "Неделя";
worksheet.Cells[row, col++].Value = "Время";
worksheet.Cells[row, col++].Value = "Группа";
worksheet.Cells[row, col++].Value = "Институт";
worksheet.Cells[row, col++].Value = "Курс";
worksheet.Cells[row, col++].Value = "Дисциплина";
worksheet.Cells[row, col++].Value = "Преподаватель";
worksheet.Cells[row, col++].Value = "Вид";
worksheet.Cells[row, col++].Value = "Кампус";
worksheet.Cells[row, col].Value = "Ауд.";
row++;
col = 1;
var pairsDictionary = config.Value.ScheduleSettings!.PairPeriod;
foreach (var dto in result.GroupBy(s => new
{
s.DayOfWeek,
s.PairNumber,
s.IsEven,
s.DisciplineId,
TypeOfOccupations = string.Join(',', s.TypeOfOccupations.OrderBy(x => x)),
LectureHalls = string.Join(',', s.LectureHalls.OrderBy(x => x)),
Campus = string.Join(',', s.Campus.OrderBy(x => x)),
Professors = string.Join(',', s.Professors.OrderBy(x => x))
})
.Select(g => new
{
g.Key.DayOfWeek,
g.Key.PairNumber,
g.Key.IsEven,
g.First().Discipline,
g.First().LectureHalls,
g.First().Campus,
g.First().Professors,
Groups = string.Join('\n', g.Select(x => x.Group)),
IsExclude = g.First().IsExcludedWeeks,
g.First().TypeOfOccupations,
g.First().Weeks
})
.ToList())
{
// День
worksheet.Cells[row, col++].Value =
$"{(int)dto.DayOfWeek} [{CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedDayName(dto.DayOfWeek).ToUpper()}]";
// Пара
worksheet.Cells[row, col++].Value = dto.PairNumber + " п";
// Неделя
worksheet.Cells[row, col++].Value = $"[{(dto.IsEven ? 2 : 1)}] {(dto.IsEven ? "Четная" : "Нечетная")}";
// Время
worksheet.Cells[row, col++].Value = pairsDictionary[dto.PairNumber].Start.ToString(CultureInfo.CurrentCulture);
// Группа
worksheet.Cells[row, col].Style.WrapText = true;
worksheet.Cells[row, col++].Value = dto.Groups;
var groupTemplate = dto.Groups.Split('\n')[0];
// Институт
worksheet.Cells[row, col++].Value = GetFaculty(groupTemplate[0]);
// Курс
worksheet.Cells[row, col++].Value = groupTemplate[2] == 'М' ?
'М' :
(24 - int.Parse(groupTemplate.Split(' ')[0].Split('-').TakeLast(1).ElementAt(0)) + 1).ToString();
var disciplineAdditional = string.Empty;
if (dto.IsExclude.HasValue && dto.Weeks != null && dto.Weeks.Any())
disciplineAdditional += $"{(dto.IsExclude.Value ? "Кр. " : "")}{string.Join(", ", dto.Weeks.OrderBy(x => x))} н. ";
// Дисциплина
worksheet.Cells[row, col++].Value = disciplineAdditional + dto.Discipline;
// Преподаватель
worksheet.Cells[row, col++].Value = dto.Professors;
// Вид
worksheet.Cells[row, col++].Value = dto.TypeOfOccupations.FirstOrDefault();
// Кампус
worksheet.Cells[row, col++].Value = dto.Campus.FirstOrDefault()?.Replace("С-20", "С20").Replace("В-78", "В78");
// Ауд.
worksheet.Cells[row, col].Value = dto.LectureHalls;
col = 1;
row++;
}
worksheet.Cells[1, 1, 1, 12].AutoFilter = true;
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
var stream = new MemoryStream();
await package.SaveAsAsync(stream);
stream.Position = 0;
return File(stream, "application/vnd.ms-excel", "data.xlsx");
}
}