/// <summary> /// Builds the report definition /// </summary> /// <param name="registeredReport">The registered report</param> /// <param name="queryRepository">The query repository</param> /// <returns>The report definition generated</returns> public ReportDefinition Build ( RegisteredReport registeredReport, IQueryRepository queryRepository ) { Validate.IsNotNull(registeredReport); Validate.IsNotNull(queryRepository); if (registeredReport.SourceType == ReportDefinitionSourceType.Builder) { var builder = _builderRepository.GetBuilder ( registeredReport.BuilderTypeAssemblyQualifiedName ); return(builder.Build ( queryRepository )); } else { throw new NotSupportedException ( "Report definition script language has not been implemented." ); } }
/// <summary> /// Registers a single report with a builder source /// </summary> /// <param name="configuration">The report configuration</param> /// <param name="builderType">The report builder type</param> public void RegisterReport ( RegisteredReportConfiguration configuration, Type builderType ) { Validate.IsNotNull(configuration); var name = configuration.Name; var registered = IsRegistered(name); if (registered) { throw new InvalidOperationException ( $"A report named '{name}' has already been registered." ); } var report = new RegisteredReport ( configuration, builderType ); _reportRepository.AddReport(report); _unitOfWork.SaveChanges(); }
/// <summary> /// Constructs the source revision with the report definition /// </summary> /// <param name="report">The report definition</param> internal RegisteredReportSourceRevision ( RegisteredReport report ) { Validate.IsNotNull(report); this.RevisionId = Guid.NewGuid(); this.Report = report; this.Number = report.SourceRevisions.Count + 1; this.DateOriginallySpecified = report.DateSourceSpecified; this.DateRevised = DateTime.UtcNow; this.SourceType = report.SourceType; this.BuilderTypeName = report.BuilderTypeName; this.ScriptSourceCode = report.ScriptSourceCode; }
/// <summary> /// Auto registers multiple reports /// </summary> /// <param name="configurations">The report configurations</param> public void AutoRegisterReports ( params AutoRegisteredReportConfiguration[] configurations ) { Validate.IsNotNull(configurations); var changesMade = false; // Add any new reports that have not been registered yet foreach (var configuration in configurations) { var alreadyRegistered = _reportRepository.IsRegistered ( configuration.Name ); if (false == alreadyRegistered) { var report = new RegisteredReport ( configuration, configuration.BuilderType ); _reportRepository.AddReport ( report ); changesMade = true; } } if (changesMade) { _unitOfWork.SaveChanges(); } }
/// <summary> /// Compiles filter parameter constraints for the user specified /// </summary> /// <param name="registeredReport">The registered report</param> /// <param name="userInfo">The user information</param> /// <param name="parameterValues">The existing parameter values</param> /// <param name="constrainedParameters">The constrained parameters</param> /// <returns> /// The parameter constraints (parameter name and constrain value) /// </returns> /// <remarks> /// The parameter constraints defined by role assignments force certain /// report filter parameter values to be used over those submitted. /// /// In this method, we ensure any constraints are adhered to. /// </remarks> private Dictionary <string, object> CompileParameterConstraints ( RegisteredReport registeredReport, ReportUserInfo userInfo ) { var constrainedParameters = new Dictionary <string, object>(); // NOTE: // We don't apply constraints when a user has no roles. if (userInfo.Roles.Any()) { var assignments = GetAssignmentsForReport ( registeredReport.Name ); assignments = assignments.Where ( a => userInfo.Roles.Any ( role => role.Equals(a.RoleName, StringComparison.OrdinalIgnoreCase) ) ) .ToList(); if (assignments.Any()) { var constraints = assignments.SelectMany ( assignment => assignment.ParameterConstraints ); foreach (var constraint in constraints.ToList()) { var applyConstraint = assignments.All ( a => a.ParameterConstraints.Any ( c => c.ParameterName.Equals(constraint.ParameterName, StringComparison.OrdinalIgnoreCase) ) ); // Only apply the constraint if all role assignments have it if (applyConstraint) { var parameterName = constraint.ParameterName; var value = constraint.ResolveValue ( userInfo ); constrainedParameters[parameterName] = value; } } } } return(constrainedParameters); }
/// <summary> /// Builds a report filter from the filter values specified /// </summary> /// <param name="registeredReport">The registered report</param> /// <param name="reportDefinition">The report definition</param> /// <param name="filterValues">The filter values</param> /// <param name="userInfo">The user information</param> /// <returns>The report filter</returns> private ReportFilter BuildReportFilter ( RegisteredReport registeredReport, ReportDefinition reportDefinition, SubmittedReportFilterValues filterValues, ReportUserInfo userInfo ) { var submittedParameterValues = filterValues.ParameterValues; var convertedParameterValues = new Dictionary <string, object>(); var filter = new ReportFilter ( reportDefinition.Parameters.ToArray() ); // Process the parameter values submitted and convert them to their expected types if (submittedParameterValues != null && submittedParameterValues.Any()) { var groupedValues = new Dictionary <string, List <object> >(); foreach (var submittedValue in submittedParameterValues) { var parameterName = submittedValue.ParameterName; if (String.IsNullOrEmpty(parameterName)) { throw new InvalidOperationException ( "The submitted parameter name cannot be null." ); } var convertedValue = ConvertParameterValue ( filter, submittedValue ); if (groupedValues.ContainsKey(parameterName)) { groupedValues[parameterName].Add ( convertedValue ); } else { groupedValues.Add ( parameterName, new List <object> { convertedValue } ); } } // Flatten the grouped values into individual parameter values foreach (var pair in groupedValues) { if (pair.Value.Count > 1) { convertedParameterValues.Add ( pair.Key, pair.Value.ToArray() ); } else { convertedParameterValues.Add ( pair.Key, pair.Value.First() ); } } } // Add any missing parameter values by using the definition defaults foreach (var definition in filter.ParameterDefinitions) { var parameter = definition.Parameter; var matchFound = convertedParameterValues.Any ( pair => pair.Key.Equals ( parameter.Name, StringComparison.InvariantCultureIgnoreCase ) ); if (false == matchFound) { convertedParameterValues.Add ( parameter.Name, parameter.DefaultValue ); } } var constrainedParameters = CompileParameterConstraints ( registeredReport, userInfo ); filter.SetParameterValues ( convertedParameterValues, constrainedParameters ); if (filterValues.SortingRules != null) { foreach (var submittedRule in filterValues.SortingRules) { filter.SetSortingRule ( submittedRule.SectionType, submittedRule.ComponentName, submittedRule.ColumnName, submittedRule.Direction ); } } return(filter); }