Yc.Box.Types.TimeSlots 1.2.0

dotnet add package Yc.Box.Types.TimeSlots --version 1.2.0
                    
NuGet\Install-Package Yc.Box.Types.TimeSlots -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yc.Box.Types.TimeSlots" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Yc.Box.Types.TimeSlots" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Yc.Box.Types.TimeSlots" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Yc.Box.Types.TimeSlots --version 1.2.0
                    
#r "nuget: Yc.Box.Types.TimeSlots, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Yc.Box.Types.TimeSlots@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Yc.Box.Types.TimeSlots&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Yc.Box.Types.TimeSlots&version=1.2.0
                    
Install as a Cake Tool

Yc.Box.Types.TimeSlots

Библиотека типов для работы с временными слотами в проектах YC. Предоставляет модель для управления временными интервалами с поддержкой доступности, ограничений участников и метаданных.

🚀 Возможности

  • Временные слоты - Модель для представления временных интервалов
  • Управление доступностью - Контроль доступности слотов
  • Ограничения участников - Максимальное и текущее количество участников
  • Автоматические вычисления - Продолжительность слота вычисляется автоматически
  • Метаданные - Временные метки создания и обновления
  • Типобезопасность - Полная поддержка типизированных моделей

📦 Установка

dotnet add package Yc.Box.Types.TimeSlots

🔧 Использование

Создание временного слота

using Yc.Box.Types.TimeSlots.Models;

public class TimeSlotService
{
    public YcTimeSlot CreateTimeSlot(string name, TimeSpan startTime, TimeSpan endTime)
    {
        return new YcTimeSlot
        {
            Id = Guid.NewGuid(),
            Name = name,
            StartTime = startTime,
            EndTime = endTime,
            Description = "Описание временного слота",
            IsAvailable = true,
            MaxParticipants = 10,
            CurrentParticipants = 0
        };
    }

    public YcTimeSlot CreateMorningSlot()
    {
        return new YcTimeSlot
        {
            Id = Guid.NewGuid(),
            Name = "Утренний слот",
            StartTime = TimeSpan.FromHours(9),
            EndTime = TimeSpan.FromHours(12),
            Description = "Утренние часы работы",
            IsAvailable = true,
            MaxParticipants = 5,
            CurrentParticipants = 0
        };
    }

    public YcTimeSlot CreateAfternoonSlot()
    {
        return new YcTimeSlot
        {
            Id = Guid.NewGuid(),
            Name = "Дневной слот",
            StartTime = TimeSpan.FromHours(13),
            EndTime = TimeSpan.FromHours(17),
            Description = "Дневные часы работы",
            IsAvailable = true,
            MaxParticipants = 8,
            CurrentParticipants = 0
        };
    }
}

Управление доступностью

public class TimeSlotManager
{
    public bool IsSlotAvailable(YcTimeSlot timeSlot)
    {
        return timeSlot.IsAvailable && 
               timeSlot.CurrentParticipants < timeSlot.MaxParticipants;
    }

    public bool CanAddParticipant(YcTimeSlot timeSlot)
    {
        if (!timeSlot.IsAvailable)
            return false;

        if (timeSlot.MaxParticipants.HasValue)
            return timeSlot.CurrentParticipants < timeSlot.MaxParticipants.Value;

        return true; // Нет ограничений
    }

    public bool AddParticipant(YcTimeSlot timeSlot)
    {
        if (!CanAddParticipant(timeSlot))
            return false;

        timeSlot.CurrentParticipants++;
        timeSlot.UpdatedAt = DateTime.UtcNow;
        return true;
    }

    public bool RemoveParticipant(YcTimeSlot timeSlot)
    {
        if (timeSlot.CurrentParticipants > 0)
        {
            timeSlot.CurrentParticipants--;
            timeSlot.UpdatedAt = DateTime.UtcNow;
            return true;
        }
        return false;
    }

    public void SetAvailability(YcTimeSlot timeSlot, bool isAvailable)
    {
        timeSlot.IsAvailable = isAvailable;
        timeSlot.UpdatedAt = DateTime.UtcNow;
    }
}

Работа с продолжительностью

public class TimeSlotCalculator
{
    public TimeSpan GetSlotDuration(YcTimeSlot timeSlot)
    {
        return timeSlot.Duration; // Автоматически вычисляется
    }

    public bool IsSlotValid(YcTimeSlot timeSlot)
    {
        return timeSlot.StartTime < timeSlot.EndTime;
    }

    public bool DoSlotsOverlap(YcTimeSlot slot1, YcTimeSlot slot2)
    {
        return slot1.StartTime < slot2.EndTime && slot2.StartTime < slot1.EndTime;
    }

    public TimeSpan GetOverlapDuration(YcTimeSlot slot1, YcTimeSlot slot2)
    {
        if (!DoSlotsOverlap(slot1, slot2))
            return TimeSpan.Zero;

        var overlapStart = slot1.StartTime > slot2.StartTime ? slot1.StartTime : slot2.StartTime;
        var overlapEnd = slot1.EndTime < slot2.EndTime ? slot1.EndTime : slot2.EndTime;

        return overlapEnd - overlapStart;
    }

    public List<YcTimeSlot> GetAvailableSlots(List<YcTimeSlot> slots)
    {
        return slots.Where(s => s.IsAvailable && s.CurrentParticipants < s.MaxParticipants).ToList();
    }

    public List<YcTimeSlot> GetSlotsByDuration(List<YcTimeSlot> slots, TimeSpan minDuration)
    {
        return slots.Where(s => s.Duration >= minDuration).ToList();
    }
}

Интеграция с расписанием

public class ScheduleTimeSlotManager
{
    public List<YcTimeSlot> CreateDailySlots(DateTime date, TimeSpan workStart, TimeSpan workEnd, int slotDurationMinutes)
    {
        var slots = new List<YcTimeSlot>();
        var currentTime = workStart;
        var slotNumber = 1;

        while (currentTime < workEnd)
        {
            var slotEnd = currentTime.Add(TimeSpan.FromMinutes(slotDurationMinutes));
            if (slotEnd > workEnd)
                slotEnd = workEnd;

            var slot = new YcTimeSlot
            {
                Id = Guid.NewGuid(),
                Name = $"Слот {slotNumber}",
                StartTime = currentTime,
                EndTime = slotEnd,
                Description = $"Временной слот {slotNumber} на {date:dd.MM.yyyy}",
                IsAvailable = true,
                MaxParticipants = 5,
                CurrentParticipants = 0,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };

            slots.Add(slot);
            currentTime = slotEnd;
            slotNumber++;
        }

        return slots;
    }

    public Dictionary<DayOfWeek, List<YcTimeSlot>> CreateWeeklySchedule(
        TimeSpan workStart, TimeSpan workEnd, int slotDurationMinutes)
    {
        var weeklySchedule = new Dictionary<DayOfWeek, List<YcTimeSlot>>();

        for (int day = 0; day < 7; day++)
        {
            var dayOfWeek = (DayOfWeek)day;
            var slots = CreateDailySlots(DateTime.Today, workStart, workEnd, slotDurationMinutes);
            weeklySchedule[dayOfWeek] = slots;
        }

        return weeklySchedule;
    }
}

API контроллер с временными слотами

using Yc.Box.Types.TimeSlots.Models;
using Yc.Box.Types.Core.Models.ApiResponses;

[ApiController]
[Route("api/[controller]")]
public class TimeSlotsController : ControllerBase
{
    private readonly TimeSlotService _timeSlotService;
    private readonly TimeSlotManager _timeSlotManager;

    public TimeSlotsController(TimeSlotService timeSlotService, TimeSlotManager timeSlotManager)
    {
        _timeSlotService = timeSlotService;
        _timeSlotManager = timeSlotManager;
    }

    [HttpGet]
    public ActionResult<YcApiResponse<List<YcTimeSlot>>> GetTimeSlots()
    {
        var slots = _timeSlotService.GetAllSlots();
        return this.SuccessResponse(slots, "Временные слоты получены");
    }

    [HttpGet("available")]
    public ActionResult<YcApiResponse<List<YcTimeSlot>>> GetAvailableSlots()
    {
        var slots = _timeSlotService.GetAllSlots();
        var availableSlots = slots.Where(s => _timeSlotManager.IsSlotAvailable(s)).ToList();
        return this.SuccessResponse(availableSlots, "Доступные слоты получены");
    }

    [HttpPost]
    public ActionResult<YcApiResponse<YcTimeSlot>> CreateTimeSlot([FromBody] CreateTimeSlotRequest request)
    {
        if (!ModelState.IsValid)
            return this.ValidationError();

        var timeSlot = _timeSlotService.CreateTimeSlot(
            request.Name, 
            request.StartTime, 
            request.EndTime);

        return this.SuccessResponse(timeSlot, "Временной слот создан");
    }

    [HttpPost("{id}/participants")]
    public ActionResult<YcApiResponse> AddParticipant(Guid id)
    {
        var timeSlot = _timeSlotService.GetById(id);
        if (timeSlot == null)
            return this.NotFoundError($"Временной слот с ID {id} не найден");

        if (!_timeSlotManager.AddParticipant(timeSlot))
            return this.ValidationError("Не удалось добавить участника. Слот недоступен или заполнен.");

        return this.SuccessResponse("Участник добавлен");
    }

    [HttpDelete("{id}/participants")]
    public ActionResult<YcApiResponse> RemoveParticipant(Guid id)
    {
        var timeSlot = _timeSlotService.GetById(id);
        if (timeSlot == null)
            return this.NotFoundError($"Временной слот с ID {id} не найден");

        if (!_timeSlotManager.RemoveParticipant(timeSlot))
            return this.ValidationError("Не удалось удалить участника.");

        return this.SuccessResponse("Участник удален");
    }
}

📋 Свойства модели YcTimeSlot

Основные свойства

  • Id - Уникальный идентификатор слота
  • Name - Название слота
  • StartTime - Время начала
  • EndTime - Время окончания
  • Description - Описание слота

Управление доступностью

  • IsAvailable - Доступен ли слот
  • MaxParticipants - Максимальное количество участников
  • CurrentParticipants - Текущее количество участников

Вычисляемые свойства

  • Duration - Продолжительность слота (EndTime - StartTime)

Метаданные

  • CreatedAt - Дата создания
  • UpdatedAt - Дата обновления

🏗️ Структура пакета

Yc.Box.Types.TimeSlots/
└── Models/
    └── YcTimeSlot.cs                   # Модель временного слота

🔒 Совместимость

  • .NET 9.0+
  • Все классы имеют префикс Yc для избежания конфликтов имен

📄 Лицензия

Проект YC Team

🤝 Поддержка

Для вопросов и предложений обращайтесь к команде разработки YC.

📈 Версии

  • 1.0.0 - Первоначальный релиз с моделью временного слота
  • 1.1.0 - Добавлены вычисляемые свойства
  • 1.2.0 - Переименование классов с префиксом Yc
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 222 7/26/2025
1.1.0 235 7/26/2025
1.0.0 233 7/26/2025