示例#1
0
        private CommunityEvent CreateGenericEvent(Int32 idCommunity, CommunityEventItem item, CommunityEventType eventType, litePerson person)
        {
            CommunityEvent oEventItem = new CommunityEvent();

            oEventItem.IdCommunityOwner = idCommunity;
            oEventItem.ForEver          = false;
            oEventItem.IsMacro          = false;
            oEventItem.IsRepeat         = false;
            oEventItem.IsVisible        = item.IsVisible;
            oEventItem.Items            = new List <CommunityEventItem>();
            oEventItem.Link             = item.Link;

            if (item.ModifiedOn.Equals(DateTime.MinValue))
            {
                oEventItem.ModifiedOn = DateTime.Now;
                item.ModifiedOn       = oEventItem.ModifiedOn;
            }
            else
            {
                oEventItem.ModifiedOn = item.ModifiedOn;
            }
            oEventItem.Name = "";
            ////DiaryItem.Title
            oEventItem.Note      = item.Note;
            oEventItem.NotePlain = item.NotePlain;
            oEventItem.Owner     = person;
            oEventItem.Place     = item.Place;
            oEventItem.Year      = item.StartDate.Year;
            oEventItem.EventType = eventType;
            if (item.StartDate.Month < 9)
            {
                oEventItem.Year = oEventItem.Year - 1;
            }
            return(oEventItem);
        }
示例#2
0
        private EmbedBuilder CreateEventProposalEmbed(CommunityEvent Event)
        {
            IUser          Author  = DiscordSocketClient.GetUser(Event.ProposerID);
            DateTimeOffset Release = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone));

            return(CreateEventProposalEmbed(Event.ID, Event.Status, Author, Release, Event.Description, Event.ResolveReason));
        }
示例#3
0
        /// <summary>
        /// A callback method to be called when an event suggestion is declined. It sets the status to denied and handles timer cleanup.
        /// </summary>
        /// <param name="EventID">The unique numerical ID for the target event.</param>
        /// <param name="Reason">The optional reason why the event was declined.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until this method completes successfully.</returns>

        public async Task DeclineEventCallback(int EventID, string Reason = "")
        {
            CommunityEvent Event    = GetEvent(EventID);
            IUser          Proposer = DiscordSocketClient.GetUser(Event.ProposerID);

            if (Event == null)
            {
                return;
            }

            Event.ResolveReason = Reason;
            await UpdateEventProposal(Event.ID);

            if (TimerService.TimerExists(Event.ReleaseTimer))
            {
                TimerService.RemoveTimer(Event.ReleaseTimer);
            }

            await BuildEmbed(EmojiEnum.Annoyed)
            .WithTitle("Event has been declined!")
            .WithDescription($"Event #{Event.ID} has been declined.")
            .WithCurrentTimestamp()
            .SendDMAttachedEmbed(Context.Channel, BotConfiguration, Proposer,
                                 BuildEmbed(EmojiEnum.Love)
                                 .WithTitle("Your Event has been Declined!")
                                 .WithDescription(Event.Description)
                                 .AddField(Reason.Length > 0, "Reason: ", Reason));

            Event.Status = EventStatus.Denied;

            CommunityEventsDB.SaveChanges();
        }
示例#4
0
        /// <summary>
        /// Manually removes an event, automatically denying it and preventing it from running. It also deleted the associated proposal.
        /// </summary>
        /// <param name="EventID">The unique ID of the target Event.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns>

        public async Task RemoveEvent(int EventID)
        {
            CommunityEvent Event = GetEvent(EventID);

            if (Event.Status == EventStatus.Released)
            {
                await BuildEmbed(EmojiEnum.Annoyed)
                .WithTitle("Event already released!")
                .WithDescription("You can't remove an event that has already been released!")
                .WithCurrentTimestamp()
                .SendEmbed(Context.Channel);
            }

            if (TimerService.TimerExists(Event.ReleaseTimer))
            {
                TimerService.RemoveTimer(Event.ReleaseTimer);
            }

            Event.Status = EventStatus.Removed;
            await UpdateEventProposal(Event.ID);

            CommunityEventsDB.SaveChanges();

            await BuildEmbed(EmojiEnum.Love)
            .WithTitle("Event was successfully removed!")
            .WithDescription($"The event \"{Event.Description}\" has been removed from the proposal system.")
            .WithCurrentTimestamp()
            .SendEmbed(Context.Channel);
        }
示例#5
0
        public void SaveItem(Int32 idCommunity, long idItem, CommunityEventItem dto, DateTime startDate, DateTime endDate, List <dtoWeekDay> weekDays, String description, String descriptionPlain)
        {
            if (UserContext.isAnonymous)
            {
                View.DisplaySessionTimeout(idCommunity, idItem);
            }
            else
            {
                CommunityEventType type     = Service.GetDiaryEventType();
                CommunityEvent     eventObj = Service.AddMultipleItems(idCommunity, dto, description, descriptionPlain, UserContext.CurrentUserID, type, startDate, endDate, weekDays);

                if (eventObj == null)
                {
                    View.SetBackToDiary(idCommunity, 0);
                }
                else if (eventObj.Items != null && eventObj.Items.Count > 0)
                {
                    View.SendToItemsList(idCommunity, eventObj.Items.FirstOrDefault().Id);
                }
                else
                {
                    View.SetBackToDiary(idCommunity, 0);
                }
            }
        }
示例#6
0
        public CommunityEvent AddMultipleItems(Int32 idCommunity, CommunityEventItem dtoItem, String description, String descriptionPlain, int ownerId, CommunityEventType eventType, DateTime startDate, DateTime endDate, List <dtoWeekDay> weekDays)
        {
            CommunityEvent communityEvent = null;

            try
            {
                litePerson    person    = Manager.GetLitePerson(ownerId);
                liteCommunity community = Manager.GetLiteCommunity(idCommunity);
                if ((community != null && idCommunity > 0) && person != null)
                {
                    List <dtoWeekDayRecurrence> itemsToInsert = dtoWeekDayRecurrence.CreateRecurrency(startDate, endDate, weekDays);
                    if (itemsToInsert.Count > 0)
                    {
                        Manager.BeginTransaction();
                        communityEvent = CreateGenericEvent(idCommunity, dtoItem, eventType, person);
                        Manager.SaveOrUpdate(communityEvent);
                        foreach (dtoWeekDayRecurrence recurrence in itemsToInsert)
                        {
                            CommunityEventItem eventItem = new CommunityEventItem()
                            {
                                IdCommunityOwner = idCommunity, EventOwner = communityEvent, Owner = person, CreatedBy = person, CreatedOn = DateTime.Now
                            };
                            eventItem.ModifiedBy   = eventItem.CreatedBy;
                            eventItem.ModifiedOn   = eventItem.CreatedOn;
                            eventItem.Note         = dtoItem.Note;
                            eventItem.NotePlain    = dtoItem.NotePlain;
                            eventItem.Place        = dtoItem.Place;
                            eventItem.Title        = dtoItem.Title;
                            eventItem.StartDate    = recurrence.StartDate;
                            eventItem.EndDate      = recurrence.EndDate;
                            eventItem.ShowDateInfo = dtoItem.ShowDateInfo;
                            eventItem.IsVisible    = dtoItem.IsVisible;
                            eventItem.Link         = dtoItem.Link;
                            eventItem.AllowEdit    = true;
                            Manager.SaveOrUpdate(eventItem);
                            if (!String.IsNullOrEmpty(description))
                            {
                                DescriptionEventItem descriptionItem = new DescriptionEventItem()
                                {
                                    Id = eventItem.Id, Description = description
                                };
                                descriptionItem.DescriptionPlain = descriptionPlain;
                                Manager.SaveOrUpdate(descriptionItem);
                            }
                            communityEvent.Items.Add(eventItem);
                        }
                        Manager.SaveOrUpdate(communityEvent);
                        Manager.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                Manager.RollBack();
                communityEvent = null;
            }
            return(communityEvent);
        }
示例#7
0
        /// <summary>
        /// Updates a proposal linked to a given ID, by setting its status and relevant information, modifying the linked embed.
        /// </summary>
        /// <param name="EventID">The ID of the target event to update.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns>

        public async Task UpdateEventProposal(int EventID)
        {
            CommunityEvent Event = GetEvent(EventID);

            if (Event == null)
            {
                return;
            }

            if (Event.EventType == EventType.Official)
            {
                return;
            }

            SocketChannel ProposalChannel = DiscordSocketClient.GetChannel(CommunityConfiguration.EventsNotificationsChannel);

            IUserMessage Proposal = null;

            if (ProposalChannel is SocketTextChannel TextChannel)
            {
                try {
                    Proposal = await TextChannel.GetMessageAsync(Event.EventProposal) as IUserMessage;
                }
                catch (HttpException) {
                    await BuildEmbed(EmojiEnum.Annoyed)
                    .WithTitle("Failed to update event proposal")
                    .WithDescription("The message doesn't exist anymore! Perhaps it was deleted?")
                    .AddField("Message ID", Event.EventProposal)
                    .SendEmbed(Context.Channel);
                }
            }

            if (Proposal == null)
            {
                return;
            }

            string ProposalText = Event.Status switch {
                EventStatus.Pending => $"**New Event Proposal >>>** {CommunityConfiguration.EventsNotificationMention}",
                EventStatus.Approved => $"**Upcoming Event [{DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)):MMM M 'at' h:mm tt}] >>>**",
                EventStatus.Released => $"**Released Event**",
                _ => $"**{Event.Status} Event Proposal >>>**"
            };

            if (Event.Status is EventStatus.Pending or EventStatus.Approved or EventStatus.Released)
            {
                string Link = Event.Description.GetHyperLinks().FirstOrDefault();
                if (Link != null && Link.Length > 0)
                {
                    ProposalText += $"\n{Link}";
                }
            }

            await Proposal.ModifyAsync(Properties => {
                Properties.Content = ProposalText;
                Properties.Embed   = CreateEventProposalEmbed(Event).Build();
            });
        }
示例#8
0
        /// <summary>
        /// Gets an event from the events database given its <paramref name="Description"/>.
        /// </summary>
        /// <param name="Description">The text Description of the target event.</param>
        /// <returns>An event with the exact given <paramref name="Description"/>.</returns>

        public CommunityEvent GetEvent(string Description)
        {
            CommunityEvent Event = CommunityEventsDB.Events
                                   .AsQueryable()
                                   .Where(Event => Event.Description == Description)
                                   .FirstOrDefault();

            return(Event);
        }
示例#9
0
        /// <summary>
        /// A function to be called when an event is released or updated after its release date.
        /// </summary>
        /// <param name="EventID">The unique numeric ID of the target event.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns>

        public async Task ReleaseEvent(int EventID)
        {
            CommunityEvent Event = GetEvent(EventID);

            if (Event == null)
            {
                return;
            }

            if (Event.Status is EventStatus.Denied or EventStatus.Removed or EventStatus.Released)
            {
                return;
            }
            if (Event.Status == EventStatus.Expired && CommunityConfiguration.FailOnOverdueApproval)
            {
                return;
            }

            IUser User = DiscordSocketClient.GetUser(Event.ProposerID);

            if (Event.Status == EventStatus.Pending)
            {
                Event.Status = EventStatus.Expired;

                try {
                    await BuildEmbed(EmojiEnum.Sign)
                    .WithTitle("Event Expired")
                    .WithDescription($"One of your events expired without the admins giving their feedback in time! \n{Event.Description}")
                    .WithCurrentTimestamp()
                    .SendEmbed(await User.GetOrCreateDMChannelAsync());
                }
                catch (HttpException) { }
            }
            else
            {
                Event.Status = EventStatus.Released;

                ulong           ChannelID = Event.EventType == EventType.Official ? CommunityConfiguration.OfficialEventsChannel : CommunityConfiguration.CommunityEventsChannel;
                IMessageChannel Channel   = DiscordSocketClient.GetChannel(ChannelID) as IMessageChannel;

                string RoleMention  = $"<@&{(Event.EventType == EventType.Official ? CommunityConfiguration.OfficialEventsNotifiedRole : CommunityConfiguration.CommunityEventsNotifiedRole)}>";
                string ProposalText = $"**New {(Event.EventType == EventType.Official ? "Official" : "Community")} Event >>>** {RoleMention} \n" +
                                      $"*Event by <@{Event.ProposerID}>:* \n" +
                                      $"{Event.Description}";

                await Channel.SendMessageAsync(text : ProposalText);
            }

            await UpdateEventProposal(Event.ID);

            CommunityEventsDB.SaveChanges();
        }
示例#10
0
        /// <summary>
        /// Creates a standardized field to display an event in an embed.
        /// </summary>
        /// <param name="Event">The event to take the field parameters from.</param>
        /// <returns>An EmbedFieldBuilder which can be used as an argument for <c>EmbedBuilder.AddField(FieldEmbedBuilder)</c>.</returns>

        public EmbedFieldBuilder GenerateEventField(CommunityEvent Event)
        {
            DateTimeOffset Release     = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone));
            DateTimeOffset ProposeTime = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeProposed).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone));

            string TimeInfo = Event.Status switch {
                EventStatus.Expired => $"**Proposed:** {ProposeTime:G} \n**Expired:** {Release:G}",
                EventStatus.Pending => $"**Proposed:** {ProposeTime:G} \n**Programmed for:** {Release:G}",
                EventStatus.Approved or EventStatus.Released => $"Release: {Release:G}",
                EventStatus.Removed or EventStatus.Denied or _ => $"**Proposed:** {ProposeTime:G}"
            };

            return(new EmbedFieldBuilder()
                   .WithName($"Event #{Event.ID} [**{Event.Status.ToString().ToUpper()}**]:")
                   .WithValue($"{(Event.Description.Length > 256 ? Event.Description[..256] + "..." : Event.Description)}\n" +
示例#11
0
        /// <summary>
        /// Edits the target event to change its description to something new. It also deletes the old proposal and creates a new one with the updated information.
        /// </summary>
        /// <param name="EventID">The unique ID of the target event.</param>
        /// <param name="NewDescription">The new Description for the target event.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns>

        public async Task EditEvent(int EventID, string NewDescription)
        {
            CommunityEvent Event = GetEvent(EventID);

            if (NewDescription.Length > 1000)
            {
                await BuildEmbed(EmojiEnum.Annoyed)
                .WithTitle("Event description too long!")
                .WithDescription($"Try to keep the description under 1000 characters, the current description is {NewDescription.Length} characters long.")
                .SendEmbed(Context.Channel);

                return;
            }

            if (Event.EventType != EventType.Official)
            {
                if (Event.Status is EventStatus.Approved or EventStatus.Denied or EventStatus.Removed or EventStatus.Released)
                {
                    await BuildEmbed(EmojiEnum.Annoyed)
                    .WithTitle("Event is not pending!")
                    .WithDescription($"This event has already been {Event.Status}; and thus can't be edited. \nYou can remove this event and propose a new one if you wish to change it.")
                    .WithCurrentTimestamp()
                    .SendEmbed(Context.Channel);

                    return;
                }
            }

            Event.Description = NewDescription;
            await UpdateEventProposal(Event.ID);

            CommunityEventsDB.SaveChanges();

            await BuildEmbed(EmojiEnum.Love)
            .WithTitle("Event was successfully edited!")
            .WithDescription($"Event #{Event.ID}'s description has been changed to: \n" +
                             $"{Event.Description}")
            .WithCurrentTimestamp()
            .SendEmbed(Context.Channel);
        }
示例#12
0
        /// <summary>
        /// Resolves an event proposal by setting it as approved or declined depending on <paramref name="Action"/>.
        /// </summary>
        /// <param name="EventID">The unique numeric ID of the target event.</param>
        /// <param name="Reason">The optional reason behind the resolution.</param>
        /// <param name="Action">Either Action.Approve or Action.Decline, defines how the event proposal is resolved.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns>

        public async Task ResolveEventProposal(int EventID, string Reason, Enums.ActionType Action)
        {
            CommunityEvent Event = GetEvent(EventID);

            if (Event == null)
            {
                return;
            }

            if (Event.Status is EventStatus.Approved or EventStatus.Denied or EventStatus.Released or EventStatus.Removed)
            {
                await BuildEmbed(EmojiEnum.Annoyed)
                .WithTitle("Event already resolved!")
                .WithDescription($"Event #{EventID} has already been {Event.Status}.")
                .SendEmbed(Context.Channel);

                return;
            }

            Event.Status = Action switch {
                Enums.ActionType.Approve => EventStatus.Approved,
                Enums.ActionType.Decline => EventStatus.Denied,
                _ => Event.Status
            };

            if (Action == Enums.ActionType.Approve)
            {
                await ApproveEventCallback(EventID, Reason);
            }
            else
            {
                await DeclineEventCallback(EventID, Reason);
            }

            Event.ResolveReason = Reason;
            await UpdateEventProposal(Event.ID);
        }
示例#13
0
        public Boolean PhisicalDeleteItem(CommunityEventItem item, String baseFilePath, String baseThumbnailPath)
        {
            Boolean result = (item == null);

            if (item != null)
            {
                Boolean isInTransaction = Manager.IsInTransaction();
                try
                {
                    CommunityEvent eventOwner    = item.EventOwner;
                    List <string>  filesToRemove = new List <string>();
                    if (!isInTransaction)
                    {
                        Manager.BeginTransaction();
                    }
                    List <EventItemFile>  attachments = QueryAttachments(a => a.IdItemOwner == item.Id).ToList();
                    List <liteModuleLink> links       = attachments.Where(a => a.Link != null).Select(a => a.Link).ToList();

                    foreach (EventItemFile attachment in attachments.Where(a => a.Item != null && a.Item.IsInternal))
                    {
                        filesToRemove.Add(ServiceRepository.GetItemDiskFullPath(baseFilePath, attachment.Item));
                        filesToRemove.Add(ServiceRepository.GetItemThumbnailFullPath(baseThumbnailPath, attachment.Item));
                        Manager.DeletePhysical(attachment.Item);
                        if (attachment.Version != null)
                        {
                            Manager.DeletePhysical(attachment.Version);
                        }
                    }

                    if (links.Any())
                    {
                        Manager.DeletePhysicalList(links);
                    }
                    if (attachments.Any())
                    {
                        Manager.DeletePhysicalList(attachments);
                    }

                    if (eventOwner != null)
                    {
                        eventOwner.Items.Remove(item);
                    }

                    Manager.DeletePhysical(item);
                    if (eventOwner.Items.Count > 0)
                    {
                        Manager.SaveOrUpdate(eventOwner);
                    }
                    else
                    {
                        Manager.DeletePhysical(eventOwner);
                    }
                    if (!isInTransaction)
                    {
                        Manager.Commit();
                    }
                    Delete.Files(filesToRemove);
                }
                catch (Exception ex)
                {
                    if (!isInTransaction)
                    {
                        Manager.RollBack();
                    }
                    result = false;
                }
            }
            return(result);
        }
示例#14
0
        public CommunityEventItem SaveEventItem(int idCommunity, CommunityEventItem unsavedItem, String description, String descriptionPlain, int ownerId, int savedById, CommunityEventType eventType)
        {
            CommunityEventItem eventItem = null;

            litePerson     owner      = Manager.GetLitePerson(ownerId);
            litePerson     savedBy    = Manager.GetLitePerson(savedById);
            liteCommunity  community  = Manager.GetLiteCommunity(idCommunity);
            CommunityEvent eventOwner = unsavedItem.EventOwner;

            try
            {
                if (owner != null && savedBy != null && (community != null && idCommunity > 0))
                {
                    Manager.BeginTransaction();
                    if (unsavedItem.Id == 0)
                    {
                        eventItem                  = new CommunityEventItem();
                        eventItem.Owner            = owner;
                        eventItem.CreatedBy        = savedBy;
                        eventItem.CreatedOn        = DateTime.Now;
                        eventItem.ModifiedBy       = savedBy;
                        eventItem.ModifiedOn       = eventItem.CreatedOn;
                        eventItem.IdCommunityOwner = idCommunity;
                        eventItem.AllowEdit        = true;
                    }
                    else
                    {
                        eventItem = Manager.Get <CommunityEventItem>(unsavedItem.Id);
                        if (eventItem.Owner == null)
                        {
                            eventItem.Owner = savedBy;
                        }
                        eventItem.ModifiedBy = savedBy;
                        eventItem.ModifiedOn = DateTime.Now;
                    }
                    eventItem.Note         = unsavedItem.Note;
                    eventItem.NotePlain    = unsavedItem.NotePlain;
                    eventItem.Place        = unsavedItem.Place;
                    eventItem.Title        = unsavedItem.Title;
                    eventItem.StartDate    = unsavedItem.StartDate;
                    eventItem.EndDate      = unsavedItem.EndDate;
                    eventItem.ShowDateInfo = unsavedItem.ShowDateInfo;
                    eventItem.IsVisible    = unsavedItem.IsVisible;
                    eventItem.Link         = unsavedItem.Link;

                    if (unsavedItem.Id == 0)
                    {
                        eventOwner = CreateGenericEvent(idCommunity, eventItem, eventType, savedBy);
                        Manager.SaveOrUpdate(eventOwner);
                        eventItem.EventOwner = eventOwner;
                        if (eventOwner.Items == null)
                        {
                            eventOwner.Items = new List <CommunityEventItem>();
                        }
                        eventOwner.Items.Add(eventItem);
                        Manager.SaveOrUpdate(eventItem);
                        Manager.SaveOrUpdate(eventOwner);
                    }
                    else
                    {
                        Manager.SaveOrUpdate(eventItem);
                    }

                    DescriptionEventItem descriptionItem = Manager.Get <DescriptionEventItem>(eventItem.Id);
                    if (descriptionItem == null && !string.IsNullOrEmpty(description))
                    {
                        descriptionItem = new DescriptionEventItem()
                        {
                            Id = eventItem.Id
                        }
                    }
                    ;
                    if (descriptionItem != null)
                    {
                        descriptionItem.Description      = description;
                        descriptionItem.DescriptionPlain = descriptionPlain;
                        Manager.SaveOrUpdate(descriptionItem);
                    }
                    Manager.Commit();
                }
            }
            catch (Exception ex)
            {
                Manager.RollBack();
                eventItem = null;
            }

            return(eventItem);
        }
示例#15
0
        /// <summary>
        /// Gets an event from the events database given its <paramref name="EventID"/>.
        /// </summary>
        /// <param name="EventID">The ID of the target event.</param>
        /// <returns>An event whose ID is exactly that given by <paramref name="EventID"/>.</returns>

        public CommunityEvent GetEvent(int EventID)
        {
            CommunityEvent Event = CommunityEventsDB.Events.Find(EventID);

            return(Event);
        }
示例#16
0
 public void ViewEvent(CommunityEvent obj)
 {
     OnViewEvent(obj);
 }
示例#17
0
        /// <summary>
        /// A callback method to be called when an event suggestion is approved. It sets the status to approved and handles expired events.
        /// </summary>
        /// <param name="EventID">The unique numerical ID for the target event.</param>
        /// <param name="Reason">The optional reason for approval of the event.</param>
        /// <returns>A <c>Task</c> object, which can be awaited until this method completes successfully.</returns>

        public async Task ApproveEventCallback(int EventID, string Reason = "")
        {
            CommunityEvent Event    = GetEvent(EventID);
            IUser          Proposer = DiscordSocketClient.GetUser(Event.ProposerID);

            if (Event == null)
            {
                return;
            }

            if (Event.Status == EventStatus.Expired)
            {
                if (CommunityConfiguration.FailOnOverdueApproval)
                {
                    await BuildEmbed(EmojiEnum.Annoyed)
                    .WithTitle("This Event has already expired!")
                    .WithDescription("Expired events can't be approved (FailOnOverdueApproval configuration is activated)")
                    .WithCurrentTimestamp()
                    .SendEmbed(Context.Channel);

                    return;
                }
                else
                {
                    await BuildEmbed(EmojiEnum.Sign)
                    .WithTitle("This Event is overdue!")
                    .WithDescription("The event will be released immediately (FailOnOverDueApproval configuration is off)")
                    .WithCurrentTimestamp()
                    .SendEmbed(Context.Channel);

                    Event.Status = EventStatus.Approved;
                    await ReleaseEvent(EventID);

                    return;
                }
            }

            DateTimeOffset Release = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone));

            if (!TimerService.TimerExists(Event.ReleaseTimer))
            {
                Event.ReleaseTimer = await CreateEventTimer(ReleaseEventCallback,
                                                            new Dictionary <string, string> {
                    { "ID", Event.ID.ToString() }
                },
                                                            (int)Release.Subtract(DateTimeOffset.Now).TotalSeconds,
                                                            TimerType.Expire);
            }

            Event.ResolveReason = Reason;
            Event.Status        = EventStatus.Approved;
            await UpdateEventProposal(Event.ID);

            await BuildEmbed(EmojiEnum.Love)
            .WithTitle("Event approved for release!")
            .WithDescription($"Event #{Event.ID} will be released at {Release:ddd', 'MMM d 'at' hh:mm tt 'UTC'z} ({Release.Humanize()}).")
            .WithCurrentTimestamp()
            .SendDMAttachedEmbed(Context.Channel, BotConfiguration, Proposer,
                                 BuildEmbed(EmojiEnum.Love)
                                 .WithTitle("Your Event has been Approved!")
                                 .WithDescription(Event.Description)
                                 .AddField(Reason.Length > 0, "Reason: ", Reason)
                                 .AddField("Release Time:", $"{Release:ddd', 'MMM d 'at' hh:mm tt 'UTC'z}"));

            CommunityEventsDB.SaveChanges();
        }