feat: подтянул занятость из Modeus
Backend CI / build-and-test (push) Successful in 53s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 7s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 6m26s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 14s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s

This commit is contained in:
2026-05-30 14:08:49 +03:00
parent a8d51df3f1
commit 09d3d2778d
16 changed files with 1349 additions and 48 deletions
@@ -1,6 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using UniVerse.Application.DTOs.Sync;
using UniVerse.Application.Interfaces;
using UniVerse.Domain.Entities;
@@ -55,6 +54,7 @@ public class ScheduleSyncService : IScheduleSyncService
}
var lectureCapacity = maxEnrollments ?? GetEventTeamSize(events, ev.Id) ?? 0;
var mandatoryAttendeesCount = GetMandatoryAttendeesCount(ev.IctisStats);
var startsAt = EnsureUtc(ev.StartsAt);
var endsAt = EnsureUtc(ev.EndsAt);
@@ -68,6 +68,7 @@ public class ScheduleSyncService : IScheduleSyncService
existing.LocationId = location?.Id;
existing.TeacherId = teacher?.Id;
existing.MaxEnrollments = lectureCapacity;
existing.MandatoryAttendeesCount = mandatoryAttendeesCount;
existing.UpdatedAt = DateTime.UtcNow;
updated++;
}
@@ -91,7 +92,8 @@ public class ScheduleSyncService : IScheduleSyncService
ExternalId = ev.Id,
StartsAt = startsAt,
EndsAt = endsAt,
MaxEnrollments = lectureCapacity
MaxEnrollments = lectureCapacity,
MandatoryAttendeesCount = mandatoryAttendeesCount
});
created++;
}
@@ -111,7 +113,7 @@ public class ScheduleSyncService : IScheduleSyncService
updated,
skipped,
[
$"requestJson={BuildScheduleRequestJson(request)}",
"endpoint=POST /api/ictis?includeCounts=true",
$"timeMin={request.TimeMin:O}",
$"timeMax={request.TimeMax:O}"
]));
@@ -443,6 +445,9 @@ public class ScheduleSyncService : IScheduleSyncService
private static int? NormalizeCapacity(int? capacity) =>
capacity is > 0 ? capacity : null;
private static int GetMandatoryAttendeesCount(ModeusIctisStats? stats) =>
Math.Max(0, stats?.StudentCount ?? 0) + Math.Max(0, stats?.TeacherCount ?? 0);
private static string BuildModeusTeacherEmail(string personId) =>
$"modeus-{personId}@modeus.local".ToLowerInvariant();
@@ -488,37 +493,6 @@ public class ScheduleSyncService : IScheduleSyncService
return details;
}
private static string BuildScheduleRequestJson(SyncScheduleRequest request)
{
var body = new Dictionary<string, object?>
{
["size"] = request.Size is > 0 ? request.Size.Value : 900,
["timeMin"] = request.TimeMin,
["timeMax"] = request.TimeMax
};
AddNonEmpty(body, "roomId", request.RoomId);
AddNonEmpty(body, "attendeePersonId", request.AttendeePersonId);
AddNonEmpty(body, "courseUnitRealizationId", request.CourseUnitRealizationId);
AddNonEmpty(body, "cycleRealizationId", request.CycleRealizationId);
AddNonEmpty(body, "specialtyCode", request.SpecialtyCode);
AddNonEmpty(body, "learningStartYear", request.LearningStartYear);
AddNonEmpty(body, "profileName", request.ProfileName);
AddNonEmpty(body, "curriculumId", request.CurriculumId);
AddNonEmpty(body, "typeId", request.TypeId);
return JsonSerializer.Serialize(body);
}
private static void AddNonEmpty<T>(
IDictionary<string, object?> body,
string key,
IReadOnlyList<T>? values)
{
if (values is { Count: > 0 })
body[key] = values;
}
private static string? GetHrefId(string? href)
{
if (string.IsNullOrWhiteSpace(href))