/// <summary> /// Loads the prerequisite list. /// </summary> private void SyncPrerequisiteList() { var config = GetAchievementConfiguration(); var achievementTypeCache = GetAchievementTypeCache(); var isNew = IsAddMode(); List <AchievementTypeCache> eligiblePrerequisites; if (isNew) { eligiblePrerequisites = config == null ? new List <AchievementTypeCache>() : AchievementTypeService.GetEligiblePrerequisiteAchievementTypeCachesForNewAchievement(config.AchieverEntityTypeCache.Id); } else { eligiblePrerequisites = AchievementTypeService.GetEligiblePrerequisiteAchievementTypeCaches(achievementTypeCache); } cblPrerequsities.DataSource = eligiblePrerequisites; cblPrerequsities.DataBind(); cblPrerequsities.Visible = eligiblePrerequisites.Any(); if (!isNew) { cblPrerequsities.SetValues(achievementTypeCache.Prerequisites.Select(statp => statp.PrerequisiteAchievementTypeId)); } }
/// <summary> /// Handles the Click event of the btnRebuild control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnRebuild_Click(object sender, EventArgs e) { var achievementTypeCache = GetAchievementTypeCache(); AchievementTypeService.Process(achievementTypeCache.Id); NavigateToCurrentPage(new Dictionary <string, string> { { PageParameterKey.AchievementTypeId, achievementTypeCache.Id.ToString() } }); }
/// <summary> /// Gets the achievement type service. /// </summary> /// <returns></returns> private AchievementTypeService GetAchievementTypeService() { if (_achievementTypeService == null) { var rockContext = GetRockContext(); _achievementTypeService = new AchievementTypeService(rockContext); } return(_achievementTypeService); }
public static void ClassInitialize(TestContext testContext) { _rockContext = new RockContext(); _stepProgramService = new StepProgramService(_rockContext); _achievementTypeService = new AchievementTypeService(_rockContext); DeleteTestData(); CreateStepProgramData(); CreateAchievementTypeData(); }
public static void ClassInitialize(TestContext testContext) { _rockContext = new RockContext(); _interactionService = new InteractionService(_rockContext); _achievementTypeService = new AchievementTypeService(_rockContext); DeleteTestData(); CreatePersonAliasData(); CreateInteractionData(); CreateAchievementTypeData(); }
public static void ClassInitialize(TestContext testContext) { _rockContext = new RockContext(); _accountService = new FinancialAccountService(_rockContext); _batchService = new FinancialBatchService(_rockContext); _transactionService = new FinancialTransactionService(_rockContext); _paymentService = new FinancialPaymentDetailService(_rockContext); _achievementTypeService = new AchievementTypeService(_rockContext); _definedValueService = new DefinedValueService(_rockContext); _definedTypeService = new DefinedTypeService(_rockContext); _transactionDetailService = new FinancialTransactionDetailService(_rockContext); DeleteTestData(); PopulateDefinedValues(); CreateFinancialTransactionData(); CreateAchievementTypeData(); }
/// <summary> /// Gets the badge markup for this achiever for this achievement. /// </summary> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="achieverEntityId">The achiever entity identifier.</param> /// <returns></returns> public override string GetBadgeMarkup(AchievementTypeCache achievementTypeCache, int achieverEntityId) { if (!achievementTypeCache.BadgeLavaTemplate.IsNullOrWhiteSpace()) { var mergeFields = GetBadgeMergeFields(achievementTypeCache, achieverEntityId); return(achievementTypeCache.BadgeLavaTemplate.ResolveMergeFields(mergeFields)); } var rockContext = new RockContext(); var achievementTypeService = new AchievementTypeService(rockContext); var progressStatement = achievementTypeService.GetProgressStatement(achievementTypeCache, achieverEntityId); if (progressStatement.SuccessCount < 1) { return(string.Empty); } var iconClass = GetStepProgramCache(achievementTypeCache)?.IconCssClass; if (iconClass.IsNullOrWhiteSpace()) { iconClass = achievementTypeCache.AchievementIconCssClass; } if (iconClass.IsNullOrWhiteSpace()) { iconClass = "fa fa-medal"; } var successCountMarkup = string.Empty; if (progressStatement.SuccessCount > 1) { successCountMarkup = $@"<span class=""badge-count""> {progressStatement.SuccessCount} </span>"; } return ($@"<div style=""color: #16c98d""> <i class=""badge-icon {iconClass}""></i> {successCountMarkup} </div>"); }
/// <summary> /// Delete the data created by this test class /// </summary> private static void DeleteTestData() { var paymentQuery = _paymentService.Queryable().Where(fb => fb.ForeignKey == KEY); _paymentService.DeleteRange(paymentQuery); _rockContext.SaveChanges(); var transactionDetailQuery = _transactionDetailService.Queryable().Where(fb => fb.ForeignKey == KEY); _transactionDetailService.DeleteRange(transactionDetailQuery); _rockContext.SaveChanges(); var transactionQuery = _transactionService.Queryable().Where(fb => fb.ForeignKey == KEY); _transactionService.DeleteRange(transactionQuery); _rockContext.SaveChanges(); var batchQuery = _batchService.Queryable().Where(fb => fb.ForeignKey == KEY); _batchService.DeleteRange(batchQuery); _rockContext.SaveChanges(); var accountGuid = new List <Guid> { GivingAccountParentGuidString.AsGuid(), GivingAccountChild1GuidString.AsGuid(), GivingAccountChild2GuidString.AsGuid() }; var accountQuery = _accountService.Queryable().Where(fa => accountGuid.Contains(fa.Guid)); _accountService.DeleteRange(accountQuery); _rockContext.SaveChanges(); var achievementType = new AchievementTypeService(_rockContext); achievementType.DeleteRange(achievementType.Queryable().Where(at => _achievementIds.Contains(at.Id) || at.ForeignKey == KEY)); _rockContext.SaveChanges(); }
/// <summary> /// Handles the Delete event of the gAchievements control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gAchievements_Delete(object sender, RowEventArgs e) { var rockContext = new RockContext(); var achievementTypeService = new AchievementTypeService(rockContext); var achievementType = achievementTypeService.Get(e.RowKeyId); if (achievementType != null) { string errorMessage; if (!achievementTypeService.CanDelete(achievementType, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } achievementTypeService.Delete(achievementType); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Processes the specified achievement type cache for the source entity. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="sourceEntity">The source entity.</param> /// <returns>The set of attempts that were created or updated</returns> public override HashSet <AchievementAttempt> Process(RockContext rockContext, AchievementTypeCache achievementTypeCache, IEntity sourceEntity) { var updatedAttempts = new HashSet <AchievementAttempt>(); // If we cannot link the transaction to a person, then there is nothing to do if (!(sourceEntity is FinancialTransaction financialTransaction)) { return(updatedAttempts); } // If the achievement type is not active (or null) then there is nothing to do if (achievementTypeCache?.IsActive != true) { return(updatedAttempts); } // If there are unmet prerequisites, then there is nothing to do var achievementTypeService = new AchievementTypeService(rockContext); var unmetPrerequisites = achievementTypeService.GetUnmetPrerequisites(achievementTypeCache.Id, financialTransaction.AuthorizedPersonAliasId.Value); if (unmetPrerequisites.Any()) { return(updatedAttempts); } // If the transaction is a refund, the person is empty, or less than zero amount, then there is nothing to do. if (null != financialTransaction.RefundDetails || !financialTransaction.AuthorizedPersonAliasId.HasValue || financialTransaction.AuthorizedPersonAliasId == 0 || financialTransaction.TotalAmount <= 0M) { return(updatedAttempts); } // Get all of the attempts for this interaction and achievement combo, ordered by start date DESC so that // the most recent attempts can be found with FirstOrDefault var achievementAttemptService = new AchievementAttemptService(rockContext); var attempts = achievementAttemptService.GetOrderedAchieverAttempts(achievementAttemptService.Queryable(), achievementTypeCache, financialTransaction.AuthorizedPersonAliasId.Value); var mostRecentSuccess = attempts.FirstOrDefault(saa => saa.AchievementAttemptEndDateTime.HasValue && saa.IsSuccessful); var overachievementPossible = achievementTypeCache.AllowOverAchievement; var successfulAttemptCount = attempts.Count(saa => saa.IsSuccessful); var maxSuccessesAllowed = achievementTypeCache.MaxAccomplishmentsAllowed ?? int.MaxValue; // If the most recent success is still open and overachievement is allowed, then update it if (overachievementPossible && mostRecentSuccess != null && !mostRecentSuccess.IsClosed) { UpdateOpenAttempt(mostRecentSuccess, achievementTypeCache, financialTransaction); updatedAttempts.Add(mostRecentSuccess); if (!mostRecentSuccess.IsClosed) { // New records can only be created once the open records are all closed return(updatedAttempts); } } // If the success count limit has been reached, then no more processing should be done if (successfulAttemptCount >= maxSuccessesAllowed) { return(updatedAttempts); } // Everything after the most recent success is on the table for deletion. Successes should not be // deleted. Everything after a success might be recalculated because of data changes. // Try to reuse these attempts if they match for continuity, but if the start date is changed, they // get deleted. var attemptsToDelete = attempts; if (mostRecentSuccess != null) { attemptsToDelete = attemptsToDelete .Where(saa => saa.AchievementAttemptStartDateTime > mostRecentSuccess.AchievementAttemptStartDateTime) .ToList(); } var newAttempts = CreateNewAttempts(achievementTypeCache, financialTransaction, mostRecentSuccess); if (newAttempts != null && newAttempts.Any()) { newAttempts = newAttempts.OrderBy(saa => saa.AchievementAttemptStartDateTime).ToList(); foreach (var newAttempt in newAttempts) { // Keep the old attempt if possible, otherwise add a new one var existingAttempt = attemptsToDelete.FirstOrDefault(saa => saa.AchievementAttemptStartDateTime == newAttempt.AchievementAttemptStartDateTime); if (existingAttempt != null) { attemptsToDelete.Remove(existingAttempt); CopyAttempt(newAttempt, existingAttempt); updatedAttempts.Add(existingAttempt); } else { newAttempt.AchieverEntityId = financialTransaction.AuthorizedPersonAliasId.Value; newAttempt.AchievementTypeId = achievementTypeCache.Id; achievementAttemptService.Add(newAttempt); updatedAttempts.Add(newAttempt); } // If this attempt was successful then make re-check the max success limit if (newAttempt.IsSuccessful) { successfulAttemptCount++; if (successfulAttemptCount >= maxSuccessesAllowed && !overachievementPossible) { break; } } } } if (attemptsToDelete.Any()) { updatedAttempts.RemoveAll(attemptsToDelete); achievementAttemptService.DeleteRange(attemptsToDelete); } return(updatedAttempts); }
/// <summary> /// Processes the specified achievement type cache for the source entity. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="sourceEntity">The source entity.</param> /// <returns>The set of attempts that were created or updated</returns> public override HashSet <AchievementAttempt> Process(RockContext rockContext, AchievementTypeCache achievementTypeCache, IEntity sourceEntity) { var step = sourceEntity as Step; var updatedAttempts = new HashSet <AchievementAttempt>(); // If we cannot link the step to a person, then there is nothing to do if (step == null) { return(updatedAttempts); } // If the achievement type is not active (or null) then there is nothing to do if (achievementTypeCache?.IsActive != true) { return(updatedAttempts); } // If there are unmet prerequisites, then there is nothing to do var achievementTypeService = new AchievementTypeService(rockContext); var unmetPrerequisites = achievementTypeService.GetUnmetPrerequisites(achievementTypeCache.Id, step.PersonAliasId); if (unmetPrerequisites.Any()) { return(updatedAttempts); } // Get all of the attempts for this program and achievement combo, ordered by start date DESC so that // the most recent attempts can be found with FirstOrDefault var achievementAttemptService = new AchievementAttemptService(rockContext); var attempts = achievementAttemptService.Queryable() .Where(aa => aa.AchievementTypeId == achievementTypeCache.Id && aa.AchieverEntityId == step.PersonAliasId) .ToList() .OrderByDescending(aa => aa.AchievementAttemptStartDateTime) .ToList(); var mostRecentSuccess = attempts.FirstOrDefault(saa => saa.AchievementAttemptEndDateTime.HasValue && saa.IsSuccessful); // This component does not allow more than one success if (mostRecentSuccess != null) { return(updatedAttempts); } var currentAttempt = attempts.LastOrDefault(); if (currentAttempt == null) { currentAttempt = new AchievementAttempt { AchieverEntityId = step.PersonAliasId, AchievementTypeId = achievementTypeCache.Id }; achievementAttemptService.Add(currentAttempt); } var attributeMinDate = GetAttributeValue(achievementTypeCache, AttributeKey.StartDateTime).AsDateTime(); var attributeMaxDate = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime(); var completedStepTypeDates = GetCompletedStepTypeDates(achievementTypeCache, step.PersonAliasId, attributeMinDate, attributeMaxDate); var stepProgram = GetStepProgramCache(achievementTypeCache); var stepTypeCount = stepProgram.StepTypes.Count; var progress = CalculateProgress(completedStepTypeDates.Count, stepTypeCount); var isSuccessful = progress >= 1m; currentAttempt.AchievementAttemptStartDateTime = completedStepTypeDates.Any() ? completedStepTypeDates.First() : RockDateTime.Today; currentAttempt.AchievementAttemptEndDateTime = completedStepTypeDates.Any() ? completedStepTypeDates.Last() : RockDateTime.Today; currentAttempt.Progress = progress; currentAttempt.IsClosed = isSuccessful; currentAttempt.IsSuccessful = isSuccessful; return(updatedAttempts); }
/// <summary> /// Save the current record. /// </summary> /// <returns></returns> private void SaveRecord() { var rockContext = GetRockContext(); var achievementType = GetAchievementType(); var achievementTypeService = GetAchievementTypeService(); var isNew = achievementType == null; if (isNew) { achievementType = new AchievementType(); achievementTypeService.Add(achievementType); achievementType.ComponentEntityTypeId = cpAchievementComponent.SelectedEntityTypeId ?? 0; var configuration = GetAchievementConfiguration(); if (configuration != null) { achievementType.SourceEntityTypeId = configuration.SourceEntityTypeCache.Id; achievementType.AchieverEntityTypeId = configuration.AchieverEntityTypeCache.Id; } } achievementType.Name = tbName.Text; achievementType.Description = tbDescription.Text; achievementType.IsActive = cbActive.Checked; achievementType.IsPublic = cbIsPublic.Checked; achievementType.AchievementIconCssClass = tbIconCssClass.Text; achievementType.MaxAccomplishmentsAllowed = cbAllowOverachievement.Checked ? 1 : nbMaxAccomplishments.IntegerValue; achievementType.AllowOverAchievement = cbAllowOverachievement.Checked; achievementType.AchievementStartWorkflowTypeId = wtpStartWorkflowType.SelectedValueAsInt(); achievementType.AchievementSuccessWorkflowTypeId = wtpSuccessWorkflowType.SelectedValueAsInt(); achievementType.AchievementFailureWorkflowTypeId = wtpFailureWorkflowType.SelectedValueAsInt(); achievementType.BadgeLavaTemplate = ceBadgeLava.Text; achievementType.ResultsLavaTemplate = ceResultsLava.Text; var binaryFileService = new BinaryFileService(rockContext); if (achievementType.ImageBinaryFileId != imgupImageBinaryFile.BinaryFileId) { var oldImageTemplatePreview = binaryFileService.Get(achievementType.ImageBinaryFileId ?? 0); if (oldImageTemplatePreview != null) { // the old image won't be needed anymore, so make it IsTemporary and have it get cleaned up later oldImageTemplatePreview.IsTemporary = true; } } achievementType.ImageBinaryFileId = imgupImageBinaryFile.BinaryFileId; // Ensure that the Image is not set as IsTemporary=True if (achievementType.ImageBinaryFileId.HasValue) { var imageTemplatePreview = binaryFileService.Get(achievementType.ImageBinaryFileId.Value); if (imageTemplatePreview != null && imageTemplatePreview.IsTemporary) { imageTemplatePreview.IsTemporary = false; } } achievementType.CustomSummaryLavaTemplate = ceCustomSummaryLavaTemplate.Text; achievementType.CategoryId = cpCategory.SelectedValueAsInt(); // Both step type and status are required together or neither can be set var stepTypeId = spstStepType.StepTypeId; var stepStatusId = sspStepStatus.SelectedValueAsInt(); if (cbAddStep.Checked && stepTypeId.HasValue && stepStatusId.HasValue) { achievementType.AchievementStepTypeId = stepTypeId; achievementType.AchievementStepStatusId = stepStatusId; } else { achievementType.AchievementStepTypeId = null; achievementType.AchievementStepStatusId = null; } // Upsert Prerequisites var prerequisiteService = new AchievementTypePrerequisiteService(rockContext); var selectedPrerequisiteAchievementTypeIds = cblPrerequsities.SelectedValuesAsInt; // Remove existing prerequisites that are not selected var removePrerequisiteAchievementTypes = achievementType.Prerequisites .Where(statp => !selectedPrerequisiteAchievementTypeIds.Contains(statp.PrerequisiteAchievementTypeId)).ToList(); foreach (var prerequisite in removePrerequisiteAchievementTypes) { achievementType.Prerequisites.Remove(prerequisite); prerequisiteService.Delete(prerequisite); } // Add selected achievement types prerequisites that are not existing var addPrerequisiteAchievementTypeIds = selectedPrerequisiteAchievementTypeIds .Where(statId => !achievementType.Prerequisites.Any(statp => statp.PrerequisiteAchievementTypeId == statId)); foreach (var prerequisiteAchievementTypeId in addPrerequisiteAchievementTypeIds) { achievementType.Prerequisites.Add(new AchievementTypePrerequisite { AchievementTypeId = achievementType.Id, PrerequisiteAchievementTypeId = prerequisiteAchievementTypeId }); } // Validate Prerequisites. // This is necessary because other Achievement Types may have been modified after this record edit was started. if (!isNew) { var achievementTypeCache = GetAchievementTypeCache(); var eligibleAchievementTypes = AchievementTypeService.GetEligiblePrerequisiteAchievementTypeCaches(achievementTypeCache); foreach (var prerequisite in achievementType.Prerequisites) { if (!eligibleAchievementTypes.Any(stat => stat.Id == prerequisite.PrerequisiteAchievementTypeId)) { cvCustomValidator.IsValid = false; cvCustomValidator.ErrorMessage = string.Format( "This achievement type cannot have prerequisite \"{0}\" because it would create a circular dependency.", prerequisite.PrerequisiteAchievementType.Name); return; } } } if (!achievementType.IsValid) { // Controls will render the error messages return; } try { rockContext.SaveChanges(); if (!achievementType.IsAuthorized(Authorization.VIEW, CurrentPerson)) { achievementType.AllowPerson(Authorization.VIEW, CurrentPerson, rockContext); } if (!achievementType.IsAuthorized(Authorization.EDIT, CurrentPerson)) { achievementType.AllowPerson(Authorization.EDIT, CurrentPerson, rockContext); } if (!achievementType.IsAuthorized(Authorization.ADMINISTRATE, CurrentPerson)) { achievementType.AllowPerson(Authorization.ADMINISTRATE, CurrentPerson, rockContext); } } catch (Exception ex) { ShowBlockException(nbEditModeMessage, ex); return; } achievementType.LoadAttributes(rockContext); avcComponentAttributes.GetEditValues(achievementType); achievementType.SaveAttributeValues(rockContext); // Now that the component attributes are saved, generate the config JSON from the component var updatedCacheItem = AchievementTypeCache.Get(achievementType.Id); var component = updatedCacheItem.AchievementComponent; var configDictionary = component.GenerateConfigFromAttributeValues(updatedCacheItem); achievementType.ComponentConfigJson = configDictionary.ToJson(); rockContext.SaveChanges(); // If the save was successful, reload the page using the new record Id. NavigateToPage(RockPage.Guid, new Dictionary <string, string> { { PageParameterKey.AchievementTypeId, achievementType.Id.ToString() } }); }