Skip to content

Commit

Permalink
- Update background check action to prompt for needed attributes, and…
Browse files Browse the repository at this point in the history
… protect my ministry provider to create any needed attributes
  • Loading branch information
azturner committed Dec 2, 2014
1 parent 793ba68 commit 0d86049
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 46 deletions.
Binary file modified Dev Tools/Sql/CodeGen_WorkflowTypeMigration.sql
Binary file not shown.
28 changes: 19 additions & 9 deletions Rock.Migrations/Migrations/201411101915314_BackgroundCheck.cs

Large diffs are not rendered by default.

126 changes: 93 additions & 33 deletions Rock/Security/BackgroundCheck/ProtectMyMinistry.cs
Expand Up @@ -50,25 +50,29 @@ public class ProtectMyMinistry : BackgroundCheckComponent
/// <summary>
/// Sends a background request to Protect My Ministry
/// </summary>
/// <remarks>
/// Note: This method looks for attributes with the following keys on the workflow parameter:
/// Person (Person): The person who request should be initiated for.
/// Campus (Campus): If included, the campus name will be used as the Billing Reference Code for the request (optional)
/// SSN (EncryptedText): The SSN of the person that the reqeust if for (it is not part of their person record)
/// PackageType: Value should be the type of PMM package to request ('Basic' will be used by default)
/// ReportStatus: The status returned by PMM
/// ReportLink: The location of the background report on PMM server
/// ReportRecommendation: PMM's recomendataion
/// Report (BinaryFile): The downloaded background report
/// </remarks>
/// <param name="rockContext">The rock context.</param>
/// <param name="workflow">The Workflow initiating the request.</param>
/// <param name="personAttribute">The person attribute.</param>
/// <param name="ssnAttribute">The SSN attribute.</param>
/// <param name="requestTypeAttribute">The request type attribute.</param>
/// <param name="billingCodeAttribute">The billing code attribute.</param>
/// <param name="errorMessages">The error messages.</param>
/// <returns>
/// True/False value of whether the request was successfully sent or not
/// </returns>
/// <exception cref="System.NotImplementedException"></exception>
public override bool SendRequest( RockContext rockContext, Model.Workflow workflow, out List<string> errorMessages )
/// <remarks>
/// Note: If the associated workflow type does not have attributes with the following keys, they
/// will automatically be added to the workflow type configuration in order to store the results
/// of the PMM background check request
/// ReportStatus: The status returned by PMM
/// ReportLink: The location of the background report on PMM server
/// ReportRecommendation: PMM's recomendataion
/// Report (BinaryFile): The downloaded background report
/// </remarks>
public override bool SendRequest( RockContext rockContext, Model.Workflow workflow,
AttributeCache personAttribute, AttributeCache ssnAttribute, AttributeCache requestTypeAttribute,
AttributeCache billingCodeAttribute, out List<string> errorMessages )
{
errorMessages = new List<string>();

Expand All @@ -83,13 +87,16 @@ public override bool SendRequest( RockContext rockContext, Model.Workflow workfl

// Get the person that the request is for
Person person = null;
Guid? personAliasGuid = workflow.GetAttributeValue( "Person" ).AsGuidOrNull();
if ( personAliasGuid.HasValue )
if ( personAttribute != null )
{
person = new PersonAliasService( rockContext ).Queryable()
.Where( p => p.Guid.Equals( personAliasGuid.Value ) )
.Select( p => p.Person )
.FirstOrDefault();
Guid? personAliasGuid = workflow.GetAttributeValue( personAttribute.Key ).AsGuidOrNull();
if ( personAliasGuid.HasValue )
{
person = new PersonAliasService( rockContext ).Queryable()
.Where( p => p.Guid.Equals( personAliasGuid.Value ) )
.Select( p => p.Person )
.FirstOrDefault();
}
}

if ( person == null )
Expand Down Expand Up @@ -118,13 +125,16 @@ public override bool SendRequest( RockContext rockContext, Model.Workflow workfl
XElement orderElement = new XElement( "Order" );
rootElement.Add( orderElement );

Guid? campusGuid = workflow.GetAttributeValue( "Campus" ).AsGuidOrNull();
if ( campusGuid.HasValue)
if ( billingCodeAttribute != null )
{
var campus = CampusCache.Read( campusGuid.Value );
if ( campus != null )
Guid? campusGuid = workflow.GetAttributeValue( billingCodeAttribute.Key ).AsGuidOrNull();
if ( campusGuid.HasValue )
{
orderElement.Add( new XElement( "BillingReferenceCode", campus.Name ) );
var campus = CampusCache.Read( campusGuid.Value );
if ( campus != null )
{
orderElement.Add( new XElement( "BillingReferenceCode", campus.Name ) );
}
}
}

Expand All @@ -140,10 +150,13 @@ public override bool SendRequest( RockContext rockContext, Model.Workflow workfl
subjectElement.Add( new XElement( "DOB", person.BirthDate.Value.ToString( "MM/dd/yyyy" ) ) );
}

string ssn = Encryption.DecryptString( workflow.GetAttributeValue( "SSN" ) );
if ( !string.IsNullOrWhiteSpace( ssn ) )
if ( ssnAttribute != null )
{
subjectElement.Add( new XElement( "SSN", ssn ) );
string ssn = Encryption.DecryptString( workflow.GetAttributeValue( ssnAttribute.Key ) );
if ( !string.IsNullOrWhiteSpace( ssn ) )
{
subjectElement.Add( new XElement( "SSN", ssn ) );
}
}

if ( person.Gender == Gender.Male )
Expand Down Expand Up @@ -190,7 +203,7 @@ public override bool SendRequest( RockContext rockContext, Model.Workflow workfl
subjectElement.Add( aliasesElement );
}

string packageType = workflow.GetAttributeValue("PackageType");
string packageType = requestTypeAttribute != null ? workflow.GetAttributeValue( requestTypeAttribute.Key ) : string.Empty;
if ( string.IsNullOrWhiteSpace(packageType) )
{
packageType = "Basic";
Expand All @@ -209,7 +222,7 @@ public override bool SendRequest( RockContext rockContext, Model.Workflow workfl
{
if ( xResult.Root.Descendants().Count() > 0 )
{
SaveResults( xResult, workflow );
SaveResults( xResult, workflow, rockContext );
}
return true;
}
Expand Down Expand Up @@ -306,7 +319,7 @@ private string GetResponseMessage( Stream responseStream )
/// </summary>
/// <param name="xResult">The x result.</param>
/// <param name="workflow">The workflow.</param>
public static void SaveResults( XDocument xResult, Rock.Model.Workflow workflow)
public static void SaveResults( XDocument xResult, Rock.Model.Workflow workflow, RockContext rockContext )
{
var xOrderDetail = xResult.Descendants( "OrderDetail" ).FirstOrDefault();
if ( xOrderDetail != null )
Expand All @@ -317,27 +330,74 @@ public static void SaveResults( XDocument xResult, Rock.Model.Workflow workflow)
// Request has been completed

// Save the status
workflow.SetAttributeValue( "ReportStatus", status == "NO RECORD" ? "Pass" : "Review" );
SaveAttributeValue( workflow, "ReportStatus", status == "NO RECORD" ? "Pass" : "Review",
FieldTypeCache.Read( Rock.SystemGuid.FieldType.SINGLE_SELECT.AsGuid() ), rockContext,
new Dictionary<string, string> { { "fieldtype", "ddl" }, { "values", "Pass,Fail,Review" } } );

// Save the report link
string reportLink = ( from o in xResult.Descendants( "ReportLink" ) select o.Value ).FirstOrDefault();
workflow.SetAttributeValue( "ReportLink", reportLink );
SaveAttributeValue( workflow, "ReportLink", reportLink,
FieldTypeCache.Read( Rock.SystemGuid.FieldType.URL_LINK.AsGuid() ), rockContext );

// Save the recommendation
string recommendation = ( from o in xResult.Descendants( "Recommendation" ) select o.Value ).FirstOrDefault();
workflow.SetAttributeValue( "ReportRecommendation", recommendation );
SaveAttributeValue( workflow, "ReportRecommendation", recommendation,
FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ), rockContext,
new Dictionary<string, string> { { "ispassword", "false" } } );

// Save the report
Guid? binaryFileGuid = SaveFile( workflow.Attributes["Report"], reportLink, workflow.Id.ToString() + ".pdf" );
if ( binaryFileGuid.HasValue )
{
workflow.SetAttributeValue( "Report", binaryFileGuid.Value.ToString() );
SaveAttributeValue( workflow, "Report", binaryFileGuid.Value.ToString(),
FieldTypeCache.Read( Rock.SystemGuid.FieldType.BINARY_FILE.AsGuid() ), rockContext,
new Dictionary<string, string> { { "binaryFileType", "" } } );
}

}
}
}

private static void SaveAttributeValue( Rock.Model.Workflow workflow, string key, string value,
FieldTypeCache fieldType, RockContext rockContext, Dictionary<string, string> qualifiers = null )
{
if (workflow.Attributes.ContainsKey(key))
{
workflow.SetAttributeValue( key, value );
}
else
{
// If workflow attribute doesn't exist, create it
// ( should only happen first time a background check is processed for given workflow type)
var attribute = new Rock.Model.Attribute();
attribute.EntityTypeId = workflow.WorkflowType.TypeId;
attribute.EntityTypeQualifierColumn = "WorkflowTypeId";
attribute.EntityTypeQualifierValue = workflow.WorkflowTypeId.ToString();
attribute.Name = key.SplitCase();
attribute.Key = key;
attribute.FieldTypeId = fieldType.Id;

if ( qualifiers != null )
{
foreach( var keyVal in qualifiers )
{
var qualifier = new Rock.Model.AttributeQualifier();
qualifier.Key = keyVal.Key;
qualifier.Value = keyVal.Value;
attribute.AttributeQualifiers.Add( qualifier );
}
}

// Set the value for this action's instance to the current time
var attributeValue = new Rock.Model.AttributeValue();
attributeValue.Attribute = attribute;
attributeValue.EntityId = workflow.Id;
attributeValue.Value = value;
new AttributeValueService( rockContext ).Add( attributeValue );
}

}

private static Guid? SaveFile( AttributeCache binaryFileAttribute, string url, string fileName )
{
// get BinaryFileType info
Expand Down
9 changes: 8 additions & 1 deletion Rock/Security/BackgroundCheckComponent.cs
Expand Up @@ -18,6 +18,7 @@

using Rock.Data;
using Rock.Extension;
using Rock.Web.Cache;

namespace Rock.Security
{
Expand All @@ -34,11 +35,17 @@ public abstract class BackgroundCheckComponent : Component
/// </summary>
/// <param name="rockContext">The rock context.</param>
/// <param name="workflow">The Workflow initiating the request.</param>
/// <param name="personAttribute">The person attribute.</param>
/// <param name="ssnAttribute">The SSN attribute.</param>
/// <param name="requestTypeAttribute">The request type attribute.</param>
/// <param name="billingCodeAttribute">The billing code attribute.</param>
/// <param name="errorMessages">The error messages.</param>
/// <returns>
/// True/False value of whether the request was successfully sent or not
/// </returns>
public abstract bool SendRequest( RockContext rockContext, Rock.Model.Workflow workflow, out List<string> errorMessages );
public abstract bool SendRequest( RockContext rockContext, Rock.Model.Workflow workflow,
AttributeCache personAttribute, AttributeCache ssnAttribute, AttributeCache requestTypeAttribute,
AttributeCache billingCodeAttribute, out List<string> errorMessages );
}

}
13 changes: 12 additions & 1 deletion Rock/Workflow/Action/BackgroundCheckRequest.cs
Expand Up @@ -23,6 +23,7 @@
using Rock.Data;
using Rock.Model;
using Rock.Security;
using Rock.Web.Cache;

namespace Rock.Workflow.Action
{
Expand All @@ -36,6 +37,10 @@ namespace Rock.Workflow.Action
[ComponentField( "Rock.Security.BackgroundCheckContainer, Rock", "Background Check Provider", "The Background Check provider to use", false, "", "", 0, "Provider" )]
[WorkflowAttribute("Person Attribute", "The Person attribute that contains the person who the background check should be submitted for.", true, "", "", 1, null,
new string[] { "Rock.Field.Types.PersonFieldType" } )]
[WorkflowAttribute( "SSN Attribute", "The attribute that contains the Social Security Number of the person who the background check should be submitted for ( Must be an 'Encrypted Text' attribute )", false, "", "", 2, null,
new string[] { "Rock.Field.Types.EncryptedTextFieldType" } )]
[WorkflowAttribute( "Request Type Attribute", "The attribute that contains the type of background check to submit (Specific to provider).", false, "", "", 3, null)]
[WorkflowAttribute( "Billing Code Attribute", "The attribute that contains the billing code to use when submitting background checkk.", false, "", "", 4 )]
public class BackgroundCheckRequest : ActionComponent
{
/// <summary>
Expand All @@ -56,7 +61,13 @@ public override bool Execute( RockContext rockContext, WorkflowAction action, Ob
var provider = BackgroundCheckContainer.GetComponent( providerGuid );
if ( provider != null )
{
return provider.SendRequest( rockContext, action.Activity.Workflow, out errorMessages );
var personAttribute = AttributeCache.Read( GetAttributeValue( action, "PersonAttribute" ).AsGuid() );
var ssnAttribute = AttributeCache.Read( GetAttributeValue( action, "SSNAttribute" ).AsGuid() );
var requestTypeAttribute = AttributeCache.Read( GetAttributeValue( action, "RequestTypeAttribute" ).AsGuid() );
var billingCodeAttribute = AttributeCache.Read( GetAttributeValue( action, "BillingCodeAttribute" ).AsGuid() );

return provider.SendRequest( rockContext, action.Activity.Workflow, personAttribute,
ssnAttribute, requestTypeAttribute, billingCodeAttribute, out errorMessages );
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion RockWeb/Blocks/WorkFlow/WorkflowDetail.ascx.cs
Expand Up @@ -462,7 +462,7 @@ void rptrActivities_ItemDataBound(object sender, RepeaterItemEventArgs e)
var group = _groupService.Get( activity.AssignedGroupId.Value);
if ( group != null )
{
tdAssignedToGroup.Description = activity.AssignedGroup.Name;
tdAssignedToGroup.Description = group.Name;
}
}

Expand Down
16 changes: 15 additions & 1 deletion RockWeb/Webhooks/ProtectMyMinistry.ashx
Expand Up @@ -20,6 +20,7 @@ using System;
using System.Web;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Xml.Linq;

Expand Down Expand Up @@ -63,13 +64,26 @@ namespace RockWeb.Webhooks

if ( !string.IsNullOrEmpty( orderId ) && orderId != "OrderIdUnknown" )
{
// Save a copy of the XML to the App_Data/PMMOrders subdirectory
DirectoryInfo dir = new DirectoryInfo( context.Server.MapPath( "~/App_Data/PMMOrders" ) );
if ( !dir.Exists )
dir.Create();
int version = 0;
FileInfo file = new FileInfo( Path.Combine( dir.FullName, orderId + ".xml" ) );
while ( file.Exists )
{
version++;
file = new FileInfo( Path.Combine( dir.FullName, string.Format( "{0}_{1}.xml", orderId, version ) ) );
}
xResult.Save( file.FullName );

// Find and update the associated workflow
var workflowService = new WorkflowService( rockContext );
var workflow = new WorkflowService( rockContext ).Get( orderId.AsInteger() );
if ( workflow != null && workflow.IsActive )
{
workflow.LoadAttributes();
Rock.Security.BackgroundCheck.ProtectMyMinistry.SaveResults( xResult, workflow );
Rock.Security.BackgroundCheck.ProtectMyMinistry.SaveResults( xResult, workflow, rockContext );
rockContext.SaveChanges();
}
}
Expand Down

0 comments on commit 0d86049

Please sign in to comment.