/// <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; } }); }
/// <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); }
/// <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); }
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; } }
/// <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); }
/// <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."); } }