/// <summary>
        /// Send the nomination reminder notification to specified team.
        /// </summary>
        /// <param name="rewardCycleEntity">Reward cycle model object.</param>
        /// <returns>A task that sends notification card in channel.</returns>
        private async Task SendCardToTeamAsync(RewardCycleEntity rewardCycleEntity)
        {
            rewardCycleEntity = rewardCycleEntity ?? throw new ArgumentNullException(nameof(rewardCycleEntity));

            var awardsList = await this.awardsStorageProvider.GetAwardsAsync(rewardCycleEntity.TeamId);

            var valuesFromTaskModule = new TaskModuleResponseDetails()
            {
                RewardCycleStartDate = rewardCycleEntity.RewardCycleStartDate,
                RewardCycleEndDate   = rewardCycleEntity.RewardCycleEndDate,
                RewardCycleId        = rewardCycleEntity.CycleId,
            };

            var teamDetails = await this.teamStorageProvider.GetTeamDetailAsync(rewardCycleEntity.TeamId);

            string serviceUrl = teamDetails.ServiceUrl;

            MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
            string teamGeneralChannelId = rewardCycleEntity.TeamId;

            this.logger.LogInformation($"sending notification to channel id - {teamGeneralChannelId}");

            await retryPolicy.ExecuteAsync(async() =>
            {
                try
                {
                    var conversationParameters = new ConversationParameters()
                    {
                        ChannelData = new TeamsChannelData()
                        {
                            Channel = new ChannelInfo()
                            {
                                Id = rewardCycleEntity.TeamId
                            }
                        },
                        Activity = (Activity)MessageFactory.Carousel(NominateCarouselCard.GetAwardNominationCards(this.options.Value.AppBaseUri, awardsList, this.localizer, valuesFromTaskModule)),
                    };

                    Activity mentionActivity = MessageFactory.Text(this.localizer.GetString("NominationReminderNotificationText"));

                    await((BotFrameworkAdapter)this.adapter).CreateConversationAsync(
                        Constants.TeamsBotFrameworkChannelId,
                        serviceUrl,
                        this.microsoftAppCredentials,
                        conversationParameters,
                        async(conversationTurnContext, conversationCancellationToken) =>
                    {
                        await conversationTurnContext.SendActivityAsync(mentionActivity, conversationCancellationToken);
                    },
                        default);
                }
                catch (Exception ex)
                {
                    this.logger.LogError(ex, "Error while sending mention card notification to channel.");
                    throw;
                }
            });
        }
Example #2
0
        /// <summary>
        /// Store or update reward cycle in table storage.
        /// </summary>
        /// <param name="rewardCycleEntity">Represents reward cycle entity used for storage and retrieval.</param>
        /// <returns><see cref="Task"/> that represents reward cycle entity is saved or updated.</returns>
        public async Task <RewardCycleEntity> StoreOrUpdateRewardCycleAsync(RewardCycleEntity rewardCycleEntity)
        {
            await this.EnsureInitializedAsync();

            TableOperation addOrUpdateOperation = TableOperation.InsertOrReplace(rewardCycleEntity);
            var            result = await this.CloudTable.ExecuteAsync(addOrUpdateOperation);

            return(result.Result as RewardCycleEntity);
        }
Example #3
0
        /// <summary>
        /// Update reward cycle entity properties based on recurrence settings.
        /// </summary>
        /// <param name="currentCycle">Current reward cycle for team.</param>
        /// <returns>Returns new reward cycle entity.</returns>
        private RewardCycleEntity UpdateRewardCycleState(RewardCycleEntity currentCycle)
        {
            var guidValue           = Guid.NewGuid().ToString();
            int cycleDurationInDays = (currentCycle.RewardCycleEndDate.Date - currentCycle.RewardCycleStartDate.Date).Days;

            currentCycle.CreatedOn            = DateTime.UtcNow;
            currentCycle.CycleId              = guidValue;
            currentCycle.ResultPublished      = (int)ResultPublishState.Unpublished;
            currentCycle.RewardCycleEndDate   = DateTime.UtcNow.AddDays(cycleDurationInDays);
            currentCycle.RewardCycleStartDate = DateTime.UtcNow;
            currentCycle.RewardCycleState     = (int)RewardCycleState.Active;

            return(currentCycle);
        }
Example #4
0
        public async Task <IActionResult> PostAsync([FromBody] RewardCycleEntity rewardCycleEntity)
        {
            try
            {
                this.logger.LogInformation("set reward cycle");
                if (rewardCycleEntity?.CycleId == null)
                {
                    rewardCycleEntity.CycleId   = Guid.NewGuid().ToString();
                    rewardCycleEntity.CreatedOn = DateTime.UtcNow;
                }

                return(this.Ok(await this.storageProvider.StoreOrUpdateRewardCycleAsync(rewardCycleEntity)));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error while making call to award service.");
                throw;
            }
        }
        public async Task <IActionResult> PostAsync([FromBody] RewardCycleEntity rewardCycleEntity)
        {
            try
            {
                if (rewardCycleEntity == null)
                {
                    this.logger.LogInformation("Set reward cycle entity is null.");
                    return(this.BadRequest(new { message = "Award cycle entity can not be null." }));
                }

                if (rewardCycleEntity.RewardCycleStartDate == null)
                {
                    this.logger.LogInformation("set reward cycle start date is null.");
                    return(this.BadRequest(new { message = "Award cycle start date can not be null." }));
                }

                if (rewardCycleEntity.RewardCycleEndDate == null)
                {
                    this.logger.LogInformation("Award cycle end date is null.");
                    return(this.BadRequest(new { message = "Award cycle end date can not be null." }));
                }

                if (rewardCycleEntity.CycleId == null)
                {
                    rewardCycleEntity.CycleId   = Guid.NewGuid().ToString();
                    rewardCycleEntity.CreatedOn = DateTime.UtcNow;
                }

                return(this.Ok(await this.storageProvider.StoreOrUpdateRewardCycleAsync(rewardCycleEntity)));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error while making call to award service.");
                throw;
            }
        }
Example #6
0
        /// <summary>
        /// Set current reward cycle
        /// </summary>
        /// <param name="currentCycle">Current reward cycle for team</param>
        /// <returns>Returns updated reward cycle entity</returns>
        private RewardCycleEntity SetAwardCycle(RewardCycleEntity currentCycle)
        {
            DateTime currentUtcTime = DateTime.UtcNow;

            // if recurring :false
            if (currentCycle.IsRecurring == (int)RecurringState.NonRecursive)
            {
                // current date should be between start date and end date
                if (currentUtcTime.Date >= currentCycle.RewardCycleStartDate.Date &&
                    currentUtcTime.Date <= currentCycle.RewardCycleEndDate.Date)
                {
                    currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                }
                else
                {
                    currentCycle.RewardCycleState = (int)RewardCycleState.InActive;
                }
            }
            else
            {
                var occurrenceType = (OccurrenceType)currentCycle.RangeOfOccurrence;

                switch (occurrenceType)
                {
                case OccurrenceType.NoEndDate:
                    if (currentUtcTime.Date > currentCycle.RewardCycleEndDate.Date)
                    {
                        // set a new award cycle for same duration.
                        this.GetNewCycle(currentCycle);
                    }

                    break;

                case OccurrenceType.EndDate:
                    int cycleDurationInDays = (currentCycle.RewardCycleEndDate.Date - currentCycle.RewardCycleStartDate.Date).Days;
                    int?remainingDaysInOccurrenceEndDate = (currentCycle.RangeOfOccurrenceEndDate?.Date - currentUtcTime.Date)?.Days;

                    if (currentUtcTime.Date <= currentCycle.RewardCycleEndDate.Date &&
                        currentUtcTime.Date >= currentCycle.RewardCycleStartDate.Date)
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                    }
                    else if (currentUtcTime.Date > currentCycle.RewardCycleEndDate.Date &&
                             currentUtcTime.Date <= currentCycle.RangeOfOccurrenceEndDate?.Date &&
                             remainingDaysInOccurrenceEndDate > cycleDurationInDays)
                    {
                        // set a new award cycle for same duration till occurrence end date.
                        this.GetNewCycle(currentCycle);
                    }
                    else
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.InActive;
                    }

                    break;

                case OccurrenceType.Occurrence:
                    if (currentCycle.NumberOfOccurrences > 0 &&
                        (currentUtcTime.Date > currentCycle.RewardCycleEndDate.Date))
                    {
                        this.GetNewCycle(currentCycle);
                        currentCycle.NumberOfOccurrences -= 1;
                    }
                    else if (currentCycle.NumberOfOccurrences >= 0 &&
                             currentUtcTime.Date <= currentCycle.RewardCycleEndDate.Date)
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                    }
                    else
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.InActive;
                    }

                    break;
                }
            }

            return(currentCycle);
        }
Example #7
0
        /// <summary>
        /// Update current reward cycle recurrence based on RecurrenceType:(RepeatIndefinitely / RepeatUntilEndDate / RepeatUntilOccurrenceCount).
        /// </summary>
        /// <param name="currentCycle">Current reward cycle for team</param>
        /// <returns>Returns updated reward cycle entity</returns>
        private RewardCycleEntity CheckAndUpdateRewardCycleState(RewardCycleEntity currentCycle)
        {
            DateTime currentUtcTime = DateTime.UtcNow;

            if (currentCycle.Recurrence == (int)RecurrenceType.SingleOccurrence)
            {
                // current date should be between start date and end date
                if (currentUtcTime >= currentCycle.RewardCycleStartDate.Date &&
                    currentUtcTime <= currentCycle.RewardCycleEndDate.Date &&
                    currentCycle.ResultPublished != (int)ResultPublishState.Published)
                {
                    currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                }
                else
                {
                    currentCycle.RewardCycleState = (int)RewardCycleState.Inactive;
                }
            }
            else
            {
                var occurrenceType = (RecurrenceType)currentCycle.Recurrence;

                switch (occurrenceType)
                {
                case RecurrenceType.RepeatIndefinitely:
                    if (currentUtcTime > currentCycle.RewardCycleEndDate.Date)
                    {
                        // set a new award cycle for same duration.
                        this.UpdateRewardCycleState(currentCycle);
                    }

                    break;

                case RecurrenceType.RepeatUntilEndDate:
                    currentCycle.RangeOfOccurrenceEndDate = currentCycle.RangeOfOccurrenceEndDate?.Date.ToUniversalTime();
                    int cycleDurationInDays = (currentCycle.RewardCycleEndDate.Date - currentCycle.RewardCycleStartDate.Date).Days;
                    int?remainingDaysInOccurrenceEndDate = (currentCycle.RangeOfOccurrenceEndDate?.Date - currentUtcTime)?.Days;

                    if (currentUtcTime <= currentCycle.RewardCycleEndDate.Date &&
                        currentUtcTime >= currentCycle.RewardCycleStartDate.Date &&
                        currentCycle.ResultPublished != (int)ResultPublishState.Published)
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                    }
                    else if (currentUtcTime > currentCycle.RewardCycleEndDate.Date &&
                             currentUtcTime <= currentCycle.RangeOfOccurrenceEndDate?.Date &&
                             remainingDaysInOccurrenceEndDate > cycleDurationInDays)
                    {
                        // set a new award cycle for same duration till occurrence end date.
                        this.UpdateRewardCycleState(currentCycle);
                    }
                    else
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Inactive;
                    }

                    break;

                case RecurrenceType.RepeatUntilOccurrenceCount:
                    if (currentCycle.NumberOfOccurrences > 0 &&
                        (currentUtcTime > currentCycle.RewardCycleEndDate.Date))
                    {
                        this.UpdateRewardCycleState(currentCycle);
                        currentCycle.NumberOfOccurrences -= 1;
                    }
                    else if (currentCycle.NumberOfOccurrences >= 0 &&
                             currentUtcTime <= currentCycle.RewardCycleEndDate.Date &&
                             currentCycle.ResultPublished != (int)ResultPublishState.Published)
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Active;
                    }
                    else
                    {
                        currentCycle.RewardCycleState = (int)RewardCycleState.Inactive;
                    }

                    break;
                }
            }

            return(currentCycle);
        }
        /// <summary>
        /// Send the given attachment to the specified team.
        /// </summary>
        /// <param name="rewardCycleEntity">Reward cycle model object.</param>
        /// <returns>A task that sends notification card in channel.</returns>
        private async Task SendCardToTeamAsync(RewardCycleEntity rewardCycleEntity)
        {
            try
            {
                var awardsList = await this.awardsStorageProvider.GetAwardsAsync(rewardCycleEntity.TeamId);

                var valuesfromTaskModule = new TaskModuleResponseDetails()
                {
                    RewardCycleStartDate = rewardCycleEntity.RewardCycleStartDate,
                    RewardCycleEndDate   = rewardCycleEntity.RewardCycleEndDate,
                    RewardCycleId        = rewardCycleEntity.CycleId,
                };

                var teamDetails = await this.teamStorageProvider.GetTeamDetailAsync(rewardCycleEntity.TeamId);

                string serviceUrl = teamDetails.ServiceUrl;

                MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
                string teamsChannelId = rewardCycleEntity.TeamId;

                var conversationReference = new ConversationReference()
                {
                    ChannelId = Channel,
                    Bot       = new ChannelAccount()
                    {
                        Id = this.microsoftAppCredentials.MicrosoftAppId
                    },
                    ServiceUrl   = serviceUrl,
                    Conversation = new ConversationAccount()
                    {
                        ConversationType = ChannelConversationType, IsGroup = true, Id = teamsChannelId, TenantId = teamsChannelId
                    },
                };

                this.logger.LogInformation($"sending notification to channelId- {teamsChannelId}");

                await retryPolicy.ExecuteAsync(async() =>
                {
                    try
                    {
                        var conversationParameters = new ConversationParameters()
                        {
                            ChannelData = new TeamsChannelData()
                            {
                                Team = new TeamInfo()
                                {
                                    Id = rewardCycleEntity.TeamId
                                }, Channel = new ChannelInfo()
                                {
                                    Id = rewardCycleEntity.TeamId
                                }
                            },
                            Activity = (Activity)MessageFactory.Carousel(NominateCarouselCard.GetAwardsCard(this.options.Value.AppBaseUri, awardsList, this.localizer, valuesfromTaskModule)),
                            Bot      = new ChannelAccount()
                            {
                                Id = this.microsoftAppCredentials.MicrosoftAppId
                            },
                            IsGroup  = true,
                            TenantId = this.options.Value.TenantId,
                        };

                        await((BotFrameworkAdapter)this.adapter).CreateConversationAsync(
                            Channel,
                            serviceUrl,
                            this.microsoftAppCredentials,
                            conversationParameters,
                            async(conversationTurnContext, conversationCancellationToken) =>
                        {
                            Activity mentionActivity = MessageFactory.Text(this.localizer.GetString("NominationReminderNotificationText"));
                            await((BotFrameworkAdapter)this.adapter).ContinueConversationAsync(
                                this.microsoftAppCredentials.MicrosoftAppId,
                                conversationTurnContext.Activity.GetConversationReference(),
                                async(continueConversationTurnContext, continueConversationCancellationToken) =>
                            {
                                mentionActivity.ApplyConversationReference(conversationTurnContext.Activity.GetConversationReference());
                                await continueConversationTurnContext.SendActivityAsync(mentionActivity, continueConversationCancellationToken);
                            }, conversationCancellationToken);
                        },
                            default);
                    }
                    catch (Exception ex)
                    {
                        this.logger.LogError(ex, "Error while performing retry logic to send notification to channel.");
                        throw;
                    }
                });
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error while sending notification to channel from background service.");
            }
        }