public async Task <IActionResult> Get(CancellationToken cancellationToken, Guid tenantId, DateTimeOffset start, DateTimeOffset end)
        {
            var command = new EventRangeQuery(User, tenantId, start, end);
            var result  = await Mediator.Send(command, cancellationToken);

            return(Ok(result));
        }
        public async Task <IActionResult> Get(CancellationToken cancellationToken, string tenant, DateTimeOffset?start, DateTimeOffset?end)
        {
            var query       = new TenantSlugQuery(User, tenant);
            var tenantModel = await Mediator.Send(query);

            var tenantId = tenantModel.Id;

            if (start == null)
            {
                start = DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(60));
            }

            if (end == null)
            {
                end = start.Value.AddMonths(6);
            }

            var command = new EventRangeQuery(User, tenantId, start.Value, end.Value);
            var events  = await Mediator.Send(command, cancellationToken);


            var calendar = new Ical.Net.Calendar();

            calendar.Method = "PUBLISH";
            calendar.AddTimeZone(tenantModel.TimeZone);

            foreach (var e in events)
            {
                var calendarEvent = new CalendarEvent();
                calendarEvent.Class       = "PUBLIC";
                calendarEvent.Uid         = e.Id;
                calendarEvent.Summary     = e.Title;
                calendarEvent.Description = e.Description;
                calendarEvent.Location    = e.Location;
                calendarEvent.Categories.Add("Training");

                if (e.Start.HasValue)
                {
                    calendarEvent.Start = new CalDateTime(e.Start.Value.UtcDateTime)
                    {
                        HasTime = true
                    }
                }
                ;

                if (e.End.HasValue)
                {
                    calendarEvent.End = new CalDateTime(e.End.Value.UtcDateTime)
                    {
                        HasTime = true
                    }
                }
                ;

                calendarEvent.LastModified = new CalDateTime(e.Modified.UtcDateTime);

                calendar.Events.Add(calendarEvent);
            }

            var serializationContext = new SerializationContext();
            var calendarSerializer   = new CalendarSerializer(serializationContext);
            var calendarText         = calendarSerializer.SerializeToString(calendar);

            var contentType = "text/calendar; charset=utf-8";

            var contentDisposition = new System.Net.Mime.ContentDisposition();

            contentDisposition.FileName = "training.ics";
            contentDisposition.Inline   = true;

            Response.Headers.Add("Content-Disposition", contentDisposition.ToString());
            Response.Headers.Add("X-Content-Type-Options", "nosniff");

            return(Content(calendarText, contentType, Encoding.UTF8));
        }
    }
}
        protected override async Task <IReadOnlyCollection <EventReadModel> > Process(EventRangeQuery request, CancellationToken cancellationToken)
        {
            var tenant = await DataContext.Tenants
                         .FindAsync(request.TenantId)
                         .ConfigureAwait(false);

            var query = DataContext.Sessions
                        .AsNoTracking()
                        .Where(q => q.TenantId == request.TenantId)
                        .Where(q => q.StartDate >= request.Start && q.StartDate < request.End)
                        .OrderBy(q => q.StartDate)
                        .ThenBy(q => q.StartTime);

            var sessions = await query
                           .ProjectTo <SessionReadModel>(Mapper.ConfigurationProvider)
                           .ToListAsync(cancellationToken)
                           .ConfigureAwait(false);

            // convert to event
            var events = new List <EventReadModel>();

            foreach (var session in sessions)
            {
                var eventModel = new EventReadModel();
                eventModel.Id       = session.Id.ToString();
                eventModel.AllDay   = false;
                eventModel.Editable = false;
                eventModel.Required = session.IsRequired;

                eventModel.Title       = $"{session.TopicTitle} - {session.GroupName}";
                eventModel.Description = session.TopicSummary;
                eventModel.Location    = session.LocationName;

                if (session.IsRequired)
                {
                    if (eventModel.ClassNames == null)
                    {
                        eventModel.ClassNames = new List <string>();
                    }

                    eventModel.ClassNames.Add("event-required");
                }

                var startDate = DateTimeFactory.Create(session.StartDate, session.StartTime, session.TenantTimeZone);
                eventModel.Start = startDate?.ToUniversalTime();

                var endDate = DateTimeFactory.Create(session.EndDate, session.EndTime, session.TenantTimeZone);
                eventModel.End = endDate?.ToUniversalTime();

                eventModel.Modified = session.Updated;

                var url = _urlHelper.Page(
                    "/topic/view",
                    values: new
                {
                    tenant = tenant.Slug,
                    id     = session.TopicId
                }
                    );

                eventModel.Url = url;

                events.Add(eventModel);
            }
            return(events);
        }