Exemple #1
0
        private static BackgroundCheck getBgCheck(RockContext rockContext, Workflow workflow, int personAliasId)
        {
            var backgroundCheckService = new BackgroundCheckService(rockContext);
            var backgroundCheck        = backgroundCheckService.Queryable()
                                         .Where(c =>
                                                c.WorkflowId.HasValue &&
                                                c.WorkflowId.Value == workflow.Id)
                                         .FirstOrDefault();

            if (backgroundCheck == null)
            {
                backgroundCheck = new Rock.Model.BackgroundCheck();
                backgroundCheck.PersonAliasId = personAliasId;
                backgroundCheck.WorkflowId    = workflow.Id;
                backgroundCheck.RequestDate   = RockDateTime.Now;
                backgroundCheckService.Add(backgroundCheck);
                rockContext.SaveChanges();
            }

            return(backgroundCheck);
        }
Exemple #2
0
        /// <summary>
        /// Sends a background request to Protect My Ministry
        /// </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>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <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
        ///     RequestStatus:          The request status returned by PMM request
        ///     RequestMessage:         Any error messages returned by PMM request
        ///     ReportStatus:           The report 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>();

            try
            {
                // Check to make sure workflow is not null
                if (workflow == null)
                {
                    errorMessages.Add("The 'Protect My Ministry' background check provider requires a valid workflow.");
                    return(false);
                }

                // Get the person that the request is for
                Person person = null;
                if (personAttribute != null)
                {
                    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();
                        person.LoadAttributes(rockContext);
                    }
                }

                if (person == null)
                {
                    errorMessages.Add("The 'Protect My Ministry' background check provider requires the workflow to have a 'Person' attribute that contains the person who the background check is for.");
                    return(false);
                }

                string password = Encryption.DecryptString(GetAttributeValue("Password"));

                XElement rootElement = new XElement("OrderXML",
                                                    new XElement("Method", "SEND ORDER"),
                                                    new XElement("Authentication",
                                                                 new XElement("Username", GetAttributeValue("UserName")),
                                                                 new XElement("Password", password)
                                                                 )
                                                    );

                if (GetAttributeValue("TestMode").AsBoolean())
                {
                    rootElement.Add(new XElement("TestMode", "YES"));
                }

                rootElement.Add(new XElement("ReturnResultURL", GetAttributeValue("ReturnURL")));

                XElement orderElement = new XElement("Order");
                rootElement.Add(orderElement);

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

                XElement subjectElement = new XElement("Subject",
                                                       new XElement("FirstName", person.FirstName),
                                                       new XElement("MiddleName", person.MiddleName),
                                                       new XElement("LastName", person.LastName)
                                                       );
                orderElement.Add(subjectElement);

                if (person.SuffixValue != null)
                {
                    subjectElement.Add(new XElement("Generation", person.SuffixValue.Value));
                }
                if (person.BirthDate.HasValue)
                {
                    subjectElement.Add(new XElement("DOB", person.BirthDate.Value.ToString("MM/dd/yyyy")));
                }

                if (ssnAttribute != null)
                {
                    string ssn = Encryption.DecryptString(workflow.GetAttributeValue(ssnAttribute.Key)).AsNumeric();
                    if (!string.IsNullOrWhiteSpace(ssn) && ssn.Length == 9)
                    {
                        subjectElement.Add(new XElement("SSN", ssn.Insert(5, "-").Insert(3, "-")));
                    }
                }

                if (person.Gender == Gender.Male)
                {
                    subjectElement.Add(new XElement("Gender", "Male"));
                }
                if (person.Gender == Gender.Female)
                {
                    subjectElement.Add(new XElement("Gender", "Female"));
                }

                string dlNumber = person.GetAttributeValue("com.sparkdevnetwork.DLNumber");
                if (!string.IsNullOrWhiteSpace(dlNumber))
                {
                    subjectElement.Add(new XElement("DLNumber", dlNumber));
                }

                if (!string.IsNullOrWhiteSpace(person.Email))
                {
                    subjectElement.Add(new XElement("EmailAddress", person.Email));
                }

                var homelocation = person.GetHomeLocation();
                if (homelocation != null)
                {
                    subjectElement.Add(new XElement("CurrentAddress",
                                                    new XElement("StreetAddress", homelocation.Street1),
                                                    new XElement("City", homelocation.City),
                                                    new XElement("State", homelocation.State),
                                                    new XElement("Zipcode", homelocation.PostalCode)
                                                    ));
                }

                XElement aliasesElement = new XElement("Aliases");
                if (person.NickName != person.FirstName)
                {
                    aliasesElement.Add(new XElement("Alias", new XElement("FirstName", person.NickName)));
                }

                foreach (var previousName in person.GetPreviousNames())
                {
                    aliasesElement.Add(new XElement("Alias", new XElement("LastName", previousName.LastName)));
                }

                if (aliasesElement.HasElements)
                {
                    subjectElement.Add(aliasesElement);
                }

                DefinedValueCache pkgTypeDefinedValue = null;
                string            packageName         = "BASIC";
                string            county          = string.Empty;
                string            state           = string.Empty;
                string            mvrJurisdiction = string.Empty;
                string            mvrState        = string.Empty;

                if (requestTypeAttribute != null)
                {
                    pkgTypeDefinedValue = DefinedValueCache.Read(workflow.GetAttributeValue(requestTypeAttribute.Key).AsGuid());
                    if (pkgTypeDefinedValue != null)
                    {
                        if (pkgTypeDefinedValue.Attributes == null)
                        {
                            pkgTypeDefinedValue.LoadAttributes(rockContext);
                        }

                        packageName = pkgTypeDefinedValue.GetAttributeValue("PMMPackageName");
                        county      = pkgTypeDefinedValue.GetAttributeValue("DefaultCounty");
                        state       = pkgTypeDefinedValue.GetAttributeValue("DefaultState");
                        Guid?mvrJurisdictionGuid = pkgTypeDefinedValue.GetAttributeValue("MVRJurisdiction").AsGuidOrNull();
                        if (mvrJurisdictionGuid.HasValue)
                        {
                            var mvrJurisdictionDv = DefinedValueCache.Read(mvrJurisdictionGuid.Value);
                            if (mvrJurisdictionDv != null)
                            {
                                mvrJurisdiction = mvrJurisdictionDv.Value;
                                if (mvrJurisdiction.Length >= 2)
                                {
                                    mvrState = mvrJurisdiction.Left(2);
                                }
                            }
                        }

                        if (homelocation != null)
                        {
                            if (!string.IsNullOrWhiteSpace(homelocation.County) &&
                                pkgTypeDefinedValue.GetAttributeValue("SendHomeCounty").AsBoolean())
                            {
                                county = homelocation.County;
                            }

                            if (!string.IsNullOrWhiteSpace(homelocation.State))
                            {
                                if (pkgTypeDefinedValue.GetAttributeValue("SendHomeState").AsBoolean())
                                {
                                    state = homelocation.State;
                                }
                                if (pkgTypeDefinedValue.GetAttributeValue("SendHomeStateMVR").AsBoolean())
                                {
                                    mvrState = homelocation.State;
                                }
                            }
                        }
                    }
                }

                if (!string.IsNullOrWhiteSpace(packageName))
                {
                    orderElement.Add(new XElement("PackageServiceCode", packageName,
                                                  new XAttribute("OrderId", workflow.Id.ToString())));

                    if (packageName.Trim().Equals("BASIC", StringComparison.OrdinalIgnoreCase) ||
                        packageName.Trim().Equals("PLUS", StringComparison.OrdinalIgnoreCase))
                    {
                        orderElement.Add(new XElement("OrderDetail",
                                                      new XAttribute("OrderId", workflow.Id.ToString()),
                                                      new XAttribute("ServiceCode", "combo")));
                    }
                }

                if (!string.IsNullOrWhiteSpace(county) ||
                    !string.IsNullOrWhiteSpace(state))
                {
                    orderElement.Add(new XElement("OrderDetail",
                                                  new XAttribute("OrderId", workflow.Id.ToString()),
                                                  new XAttribute("ServiceCode", string.IsNullOrWhiteSpace(county) ? "StateCriminal" : "CountyCrim"),
                                                  new XElement("County", county),
                                                  new XElement("State", state),
                                                  new XElement("YearsToSearch", 7),
                                                  new XElement("CourtDocsRequested", "NO"),
                                                  new XElement("RushRequested", "NO"),
                                                  new XElement("SpecialInstructions", ""))
                                     );
                }

                if (!string.IsNullOrWhiteSpace(mvrJurisdiction) && !string.IsNullOrWhiteSpace(mvrState))
                {
                    orderElement.Add(new XElement("OrderDetail",
                                                  new XAttribute("OrderId", workflow.Id.ToString()),
                                                  new XAttribute("ServiceCode", "MVR"),
                                                  new XElement("JurisdictionCode", mvrJurisdiction),
                                                  new XElement("State", mvrState))
                                     );
                }

                XDocument xdoc            = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement);
                var       requestDateTime = RockDateTime.Now;

                XDocument xResult          = PostToWebService(xdoc, GetAttributeValue("RequestURL"));
                var       responseDateTime = RockDateTime.Now;

                int?personAliasId = person.PrimaryAliasId;
                if (personAliasId.HasValue)
                {
                    // Create a background check file
                    using (var newRockContext = new RockContext())
                    {
                        var backgroundCheckService = new BackgroundCheckService(newRockContext);
                        var backgroundCheck        = backgroundCheckService.Queryable()
                                                     .Where(c =>
                                                            c.WorkflowId.HasValue &&
                                                            c.WorkflowId.Value == workflow.Id)
                                                     .FirstOrDefault();

                        if (backgroundCheck == null)
                        {
                            backgroundCheck = new Rock.Model.BackgroundCheck();
                            backgroundCheck.PersonAliasId = personAliasId.Value;
                            backgroundCheck.WorkflowId    = workflow.Id;
                            backgroundCheckService.Add(backgroundCheck);
                        }

                        backgroundCheck.RequestDate = RockDateTime.Now;

                        // Clear any SSN nodes before saving XML to record
                        foreach (var xSSNElement in xdoc.Descendants("SSN"))
                        {
                            xSSNElement.Value = "XXX-XX-XXXX";
                        }
                        foreach (var xSSNElement in xResult.Descendants("SSN"))
                        {
                            xSSNElement.Value = "XXX-XX-XXXX";
                        }

                        backgroundCheck.ResponseXml = string.Format(@"
Request XML ({0}): 
------------------------ 
{1}

Response XML ({2}): 
------------------------ 
{3}

", requestDateTime, xdoc.ToString(), responseDateTime, xResult.ToString());
                        newRockContext.SaveChanges();
                    }
                }

                using (var newRockContext = new RockContext())
                {
                    var handledErrorMessages = new List <string>();

                    bool createdNewAttribute = false;
                    if (_HTTPStatusCode == HttpStatusCode.OK)
                    {
                        var xOrderXML = xResult.Elements("OrderXML").FirstOrDefault();
                        if (xOrderXML != null)
                        {
                            var xStatus = xOrderXML.Elements("Status").FirstOrDefault();
                            if (xStatus != null)
                            {
                                if (SaveAttributeValue(workflow, "RequestStatus", xStatus.Value,
                                                       FieldTypeCache.Read(Rock.SystemGuid.FieldType.TEXT.AsGuid()), newRockContext, null))
                                {
                                    createdNewAttribute = true;
                                }
                            }

                            handledErrorMessages.AddRange(xOrderXML.Elements("Message").Select(x => x.Value).ToList());
                            var xErrors = xOrderXML.Elements("Errors").FirstOrDefault();
                            if (xErrors != null)
                            {
                                handledErrorMessages.AddRange(xOrderXML.Elements("Message").Select(x => x.Value).ToList());
                            }

                            if (xResult.Root.Descendants().Count() > 0)
                            {
                                SaveResults(xResult, workflow, rockContext, false);
                            }
                        }
                    }
                    else
                    {
                        handledErrorMessages.Add("Invalid HttpStatusCode: " + _HTTPStatusCode.ToString());
                    }

                    if (handledErrorMessages.Any())
                    {
                        if (SaveAttributeValue(workflow, "RequestMessage", handledErrorMessages.AsDelimited(Environment.NewLine),
                                               FieldTypeCache.Read(Rock.SystemGuid.FieldType.TEXT.AsGuid()), newRockContext, null))
                        {
                            createdNewAttribute = true;
                        }
                    }

                    newRockContext.SaveChanges();

                    if (createdNewAttribute)
                    {
                        AttributeCache.FlushEntityAttributes();
                    }

                    return(true);
                }
            }

            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, null);
                errorMessages.Add(ex.Message);
                return(false);
            }
        }
Exemple #3
0
        /// <summary>
        /// Saves the results.
        /// </summary>
        /// <param name="xResult">The x result.</param>
        /// <param name="workflow">The workflow.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="saveResponse">if set to <c>true</c> [save response].</param>
        public static void SaveResults(XDocument xResult, Rock.Model.Workflow workflow, RockContext rockContext, bool saveResponse = true)
        {
            bool createdNewAttribute = false;

            var newRockContext  = new RockContext();
            var service         = new BackgroundCheckService(newRockContext);
            var backgroundCheck = service.Queryable()
                                  .Where(c =>
                                         c.WorkflowId.HasValue &&
                                         c.WorkflowId.Value == workflow.Id)
                                  .FirstOrDefault();

            if (backgroundCheck != null && saveResponse)
            {
                // Clear any SSN nodes before saving XML to record
                foreach (var xSSNElement in xResult.Descendants("SSN"))
                {
                    xSSNElement.Value = "XXX-XX-XXXX";
                }

                backgroundCheck.ResponseXml = backgroundCheck.ResponseXml + string.Format(@"
Response XML ({0}): 
------------------------ 
{1}

", RockDateTime.Now.ToString(), xResult.ToString());
            }

            var xOrderXML = xResult.Elements("OrderXML").FirstOrDefault();

            if (xOrderXML != null)
            {
                var xOrder = xOrderXML.Elements("Order").FirstOrDefault();
                if (xOrder != null)
                {
                    bool resultFound = false;

                    // Find any order details with a status element
                    string reportStatus = "Pass";
                    foreach (var xOrderDetail in xOrder.Elements("OrderDetail"))
                    {
                        var xStatus = xOrderDetail.Elements("Status").FirstOrDefault();
                        if (xStatus != null)
                        {
                            resultFound = true;
                            if (xStatus.Value != "NO RECORD")
                            {
                                reportStatus = "Review";
                                break;
                            }
                        }
                    }

                    if (resultFound)
                    {
                        // If no records found, still double-check for any alerts
                        if (reportStatus != "Review")
                        {
                            var xAlerts = xOrder.Elements("Alerts").FirstOrDefault();
                            if (xAlerts != null)
                            {
                                if (xAlerts.Elements("OrderId").Any())
                                {
                                    reportStatus = "Review";
                                }
                            }
                        }

                        // Save the recommendation
                        string recommendation = (from o in xOrder.Elements("Recommendation") select o.Value).FirstOrDefault();
                        if (!string.IsNullOrWhiteSpace(recommendation))
                        {
                            if (SaveAttributeValue(workflow, "ReportRecommendation", recommendation,
                                                   FieldTypeCache.Read(Rock.SystemGuid.FieldType.TEXT.AsGuid()), rockContext,
                                                   new Dictionary <string, string> {
                                { "ispassword", "false" }
                            }))
                            {
                                createdNewAttribute = true;
                            }
                        }

                        // Save the report link
                        Guid?  binaryFileGuid = null;
                        string reportLink     = (from o in xOrder.Elements("ReportLink") select o.Value).FirstOrDefault();
                        if (!string.IsNullOrWhiteSpace(reportLink))
                        {
                            if (SaveAttributeValue(workflow, "ReportLink", reportLink,
                                                   FieldTypeCache.Read(Rock.SystemGuid.FieldType.URL_LINK.AsGuid()), rockContext))
                            {
                                createdNewAttribute = true;
                            }

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

                        // Save the status
                        if (SaveAttributeValue(workflow, "ReportStatus", reportStatus,
                                               FieldTypeCache.Read(Rock.SystemGuid.FieldType.SINGLE_SELECT.AsGuid()), rockContext,
                                               new Dictionary <string, string> {
                            { "fieldtype", "ddl" }, { "values", "Pass,Fail,Review" }
                        }))
                        {
                            createdNewAttribute = true;
                        }

                        // Update the background check file
                        if (backgroundCheck != null)
                        {
                            backgroundCheck.ResponseDate = RockDateTime.Now;
                            backgroundCheck.RecordFound  = reportStatus == "Review";

                            if (binaryFileGuid.HasValue)
                            {
                                var binaryFile = new BinaryFileService(newRockContext).Get(binaryFileGuid.Value);
                                if (binaryFile != null)
                                {
                                    backgroundCheck.ResponseDocumentId = binaryFile.Id;
                                }
                            }
                        }
                    }
                }
            }

            newRockContext.SaveChanges();

            if (createdNewAttribute)
            {
                AttributeCache.FlushEntityAttributes();
            }
        }
Exemple #4
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            string providerGuid = GetAttributeValue(action, "Provider");

            if (!string.IsNullOrWhiteSpace(providerGuid))
            {
                var provider = BackgroundCheckContainer.GetComponent(providerGuid);
                if (provider != null)
                {
                    BackgroundCheckService backgroundCheckService = new BackgroundCheckService(rockContext);
                    var backgroundCheck = backgroundCheckService.Queryable().Where(b => b.WorkflowId == action.Activity.Workflow.Id).FirstOrDefault();
                    if (backgroundCheck == null)
                    {
                        //If for some reason a background check entity isn't available
                        //Add a log and set the report Status To Error.
                        //This allows the workflow to handle issues gracefully
                        action.AddLogEntry("No valid background check exists for this workflow", true);
                        SetWorkflowAttributeValue(action, GetAttributeValue(action, "ReportStatus").AsGuid(), "Error");
                        return(true);
                    }
                    var transactionId = backgroundCheck.RequestId;

                    var statusURL      = provider.GetAttributeValue("StatusURL");
                    var subscriberCode = Encryption.DecryptString(provider.GetAttributeValue("SubscriberCode"));
                    var companyCode    = Encryption.DecryptString(provider.GetAttributeValue("CompanyCode"));

                    Trak1ReportStatus status = null;
                    var resource             = string.Format("/{0}/{1}/{2}", subscriberCode, companyCode, transactionId);

                    using (var client = new HttpClient(new HttpClientHandler()))
                    {
                        client.BaseAddress = new Uri(statusURL + resource);
                        var clientResponse = client.GetAsync("").Result.Content.ReadAsStringAsync().Result;
                        status = JsonConvert.DeserializeObject <Trak1ReportStatus>(clientResponse);
                    }

                    SetWorkflowAttributeValue(action, GetAttributeValue(action, "ReportStatus").AsGuid(), status.ReportStatus);
                    backgroundCheck.Status = status.ReportStatus;

                    SetWorkflowAttributeValue(action, GetAttributeValue(action, "HitColor").AsGuid(), status.HitColor);
                    backgroundCheck.RecordFound = status.HitColor == "Green";

                    var         reportURL = provider.GetAttributeValue("ReportURL");
                    Trak1Report response  = null;
                    using (var client = new HttpClient(new HttpClientHandler()))
                    {
                        client.BaseAddress = new Uri(reportURL + resource);
                        var clientResponse = client.GetAsync("").Result.Content.ReadAsStringAsync().Result;
                        response = JsonConvert.DeserializeObject <Trak1Report>(clientResponse);
                    }

                    SetWorkflowAttributeValue(action, GetAttributeValue(action, "ReportUrl").AsGuid(), response.ReportUrl);
                    backgroundCheck.ResponseDate = Rock.RockDateTime.Now;
                    backgroundCheck.ResponseData = response.ReportUrl;

                    return(true);
                }
                else
                {
                    errorMessages.Add("Invalid Background Check Provider!");
                }
            }
            else
            {
                errorMessages.Add("Invalid Background Check Provider Guid!");
            }

            return(false);
        }
Exemple #5
0
        /// <summary>
        /// Sends a background request to Checkr.  This method is called by the BackgroundCheckRequest action's Execute
        /// method for the Checkr 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 override bool SendRequest(RockContext rockContext, Model.Workflow workflow,
                                         AttributeCache personAttribute, AttributeCache ssnAttribute, AttributeCache requestTypeAttribute,
                                         AttributeCache billingCodeAttribute, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            try
            {
                // Check to make sure workflow is not null
                if (workflow == null)
                {
                    errorMessages.Add("The 'Checkr' background check provider requires a valid workflow.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                // Lock the workflow until we're finished saving so the webhook can't start working on it.
                var lockObject = _lockObjects.GetOrAdd(workflow.Id, new object());
                lock ( lockObject )
                {
                    // Checkr can respond very fast, possibly before the workflow finishes.
                    // Save the workflow now to ensure previously completed activities/actions
                    // are not run again via the checkr webhook. This is not done at the Action
                    // or Activity level for speed reasons.
                    if (workflow.IsPersisted == true)
                    {
                        rockContext.SaveChanges();
                    }

                    Person person;
                    int?   personAliasId;
                    if (!GetPerson(rockContext, workflow, personAttribute, out person, out personAliasId, errorMessages))
                    {
                        errorMessages.Add("Unable to get Person.");
                        UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                        return(true);
                    }

                    string packageName;
                    if (!GetPackageName(rockContext, workflow, requestTypeAttribute, out packageName, errorMessages))
                    {
                        errorMessages.Add("Unable to get Package.");
                        UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                        return(true);
                    }

                    string candidateId;
                    if (!CreateCandidate(person, out candidateId, errorMessages))
                    {
                        errorMessages.Add("Unable to create candidate.");
                        UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                        return(true);
                    }

                    if (!CreateInvitation(candidateId, packageName, errorMessages))
                    {
                        errorMessages.Add("Unable to create invitation.");
                        UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                        return(true);
                    }

                    using (var newRockContext = new RockContext())
                    {
                        var backgroundCheckService = new BackgroundCheckService(newRockContext);
                        var backgroundCheck        = backgroundCheckService.Queryable()
                                                     .Where(c =>
                                                            c.WorkflowId.HasValue &&
                                                            c.WorkflowId.Value == workflow.Id)
                                                     .FirstOrDefault();

                        if (backgroundCheck == null)
                        {
                            backgroundCheck            = new BackgroundCheck();
                            backgroundCheck.WorkflowId = workflow.Id;
                            backgroundCheckService.Add(backgroundCheck);
                        }

                        backgroundCheck.PersonAliasId = personAliasId.Value;
                        backgroundCheck.ForeignId     = 2;
                        backgroundCheck.PackageName   = packageName;
                        backgroundCheck.RequestDate   = RockDateTime.Now;
                        backgroundCheck.RequestId     = candidateId;
                        newRockContext.SaveChanges();
                    }

                    UpdateWorkflowRequestStatus(workflow, rockContext, "SUCCESS");

                    if (workflow.IsPersisted)
                    {
                        // Make sure the AttributeValues are saved to the database immediately because the Checkr WebHook
                        // (which might otherwise get called before they are saved by the workflow processing) needs to
                        // have the correct attribute values.
                        workflow.SaveAttributeValues(rockContext);
                    }

                    _lockObjects.TryRemove(workflow.Id, out _);   // we no longer need that lock for this workflow
                }

                return(true);
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, null);
                errorMessages.Add(ex.Message);
                UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                return(true);
            }
        }
Exemple #6
0
        /// <summary>
        /// Sends a background request to Checkr.
        /// </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 override bool SendRequest(RockContext rockContext, Model.Workflow workflow,
                                         AttributeCache personAttribute, AttributeCache ssnAttribute, AttributeCache requestTypeAttribute,
                                         AttributeCache billingCodeAttribute, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            try
            {
                // Check to make sure workflow is not null
                if (workflow == null)
                {
                    errorMessages.Add("The 'Checkr' background check provider requires a valid workflow.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                Person person;
                int?   personAliasId;
                if (!GetPerson(rockContext, workflow, personAttribute, out person, out personAliasId, errorMessages))
                {
                    errorMessages.Add("Unable to get Person.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                string packageName;
                if (!GetPackageName(rockContext, workflow, requestTypeAttribute, out packageName, errorMessages))
                {
                    errorMessages.Add("Unable to get Package.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                string candidateId;
                if (!CreateCandidate(person, out candidateId, errorMessages))
                {
                    errorMessages.Add("Unable to create candidate.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                if (!CreateInvitation(candidateId, packageName, errorMessages))
                {
                    errorMessages.Add("Unable to create invitation.");
                    UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                    return(true);
                }

                using (var newRockContext = new RockContext())
                {
                    var backgroundCheckService = new BackgroundCheckService(newRockContext);
                    var backgroundCheck        = backgroundCheckService.Queryable()
                                                 .Where(c =>
                                                        c.WorkflowId.HasValue &&
                                                        c.WorkflowId.Value == workflow.Id)
                                                 .FirstOrDefault();

                    if (backgroundCheck == null)
                    {
                        backgroundCheck            = new Rock.Model.BackgroundCheck();
                        backgroundCheck.WorkflowId = workflow.Id;
                        backgroundCheckService.Add(backgroundCheck);
                    }

                    backgroundCheck.PersonAliasId = personAliasId.Value;
                    backgroundCheck.ForeignId     = 2;
                    backgroundCheck.PackageName   = packageName;
                    backgroundCheck.RequestDate   = RockDateTime.Now;
                    backgroundCheck.RequestId     = candidateId;
                    newRockContext.SaveChanges();

                    UpdateWorkflowRequestStatus(workflow, newRockContext, "SUCCESS");
                    return(true);
                }
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, null);
                errorMessages.Add(ex.Message);
                UpdateWorkflowRequestStatus(workflow, rockContext, "FAIL");
                return(true);
            }
        }
Exemple #7
0
        /// <summary>
        /// Sends a background request to Trak-1
        /// </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>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <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 background check request
        ///     RequestStatus:          The request status returned by request
        ///     RequestMessage:         Any error messages returned by request
        ///     ReportStatus:           The report status returned
        ///     ReportLink:             The location of the background report on server
        ///     ReportRecommendation:   Recomendataion
        ///     Report (BinaryFile):    The downloaded background report
        /// </remarks>
        public override bool SendRequest(RockContext rockContext, Rock.Model.Workflow workflow,
                                         AttributeCache personAttribute, AttributeCache ssnAttribute, AttributeCache requestTypeAttribute,
                                         AttributeCache billingCodeAttribute, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            try
            {
                // Check to make sure workflow is not null
                if (workflow == null)
                {
                    errorMessages.Add("Trak-1 background check provider requires a valid workflow.");
                    return(false);
                }

                // Get the person that the request is for
                Person person = null;
                if (personAttribute != null)
                {
                    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();
                        person.LoadAttributes(rockContext);
                    }
                }

                if (person == null)
                {
                    errorMessages.Add("Trak-1 background check provider requires the workflow to have a 'Person' attribute that contains the person who the background check is for.");
                    return(false);
                }

                //Get required fields from workflow
                var packageList = GetPackageList();
                var packageName = workflow.GetAttributeValue(requestTypeAttribute.Key);
                // If this is a defined value, fetch the value
                if (requestTypeAttribute.FieldType.Guid.ToString().ToUpper() == Rock.SystemGuid.FieldType.DEFINED_VALUE)
                {
                    packageName = DefinedValueCache.Get(packageName).Value;
                }
                var package = packageList.Where(p => p.PackageName == packageName).FirstOrDefault();
                if (package == null)
                {
                    errorMessages.Add("Package name not valid");
                    return(false);
                }

                var requiredFields     = package.Components.SelectMany(c => c.RequiredFields).ToList();
                var requiredFieldsDict = new Dictionary <string, string>();
                foreach (var field in requiredFields)
                {
                    if (!workflow.Attributes.ContainsKey(field.Name))
                    {
                        errorMessages.Add("Workflow does not contain attribute for required field " + field.Name);
                        return(false);
                    }
                    requiredFieldsDict[field.Name] = workflow.GetAttributeValue(field.Name);
                }


                //Generate Request
                var authentication = new Trak1Authentication
                {
                    UserName       = GetAttributeValue("UserName"),
                    SubscriberCode = Encryption.DecryptString(GetAttributeValue("SubscriberCode")),
                    CompanyCode    = Encryption.DecryptString(GetAttributeValue("CompanyCode")),
                    BranchName     = "Main"
                };

                var ssn = "";
                if (ssnAttribute != null)
                {
                    ssn = Rock.Field.Types.SSNFieldType.UnencryptAndClean(workflow.GetAttributeValue(ssnAttribute.Key));
                    if (!string.IsNullOrWhiteSpace(ssn) && ssn.Length == 9)
                    {
                        ssn = ssn.Insert(5, "-").Insert(3, "-");
                    }
                }

                Location homeLocation = null;

                var homeAddressDv = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME);
                foreach (var family in person.GetFamilies(rockContext))
                {
                    var loc = family.GroupLocations
                              .Where(l =>
                                     l.GroupLocationTypeValueId == homeAddressDv.Id)
                              .Select(l => l.Location)
                              .FirstOrDefault();
                    if (loc != null)
                    {
                        homeLocation = loc;
                    }
                }

                if (homeLocation == null)
                {
                    errorMessages.Add("A valid home location to submit a Trak-1 background check.");
                    return(false);
                }

                var applicant = new Trak1Applicant
                {
                    SSN            = ssn,
                    FirstName      = person.FirstName,
                    MiddleName     = person.MiddleName,
                    LastName       = person.LastName,
                    DateOfBirth    = (person.BirthDate ?? new DateTime()).ToString("yyyy-MM-dd"),
                    Address1       = homeLocation.Street1,
                    Address2       = homeLocation.Street2,
                    City           = homeLocation.City,
                    State          = homeLocation.State,
                    Zip            = homeLocation.PostalCode,
                    RequiredFields = requiredFieldsDict
                };

                var request = new Trak1Request
                {
                    Authentication = authentication,
                    Applicant      = applicant,
                    PackageName    = packageName
                };


                var content = JsonConvert.SerializeObject(request);

                Trak1Response response = null;

                using (var client = new HttpClient(new HttpClientHandler()))
                {
                    client.BaseAddress = new Uri(GetAttributeValue("RequestURL"));
                    var clientResponse = client.PostAsync("", new StringContent(content, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result;
                    response = JsonConvert.DeserializeObject <Trak1Response>(clientResponse);
                }

                if (!string.IsNullOrWhiteSpace(response.Error?.Message))
                {
                    errorMessages.Add(response.Error.Message);
                    return(false);
                }

                var transactionId = response.TransactionId;


                int?personAliasId = person.PrimaryAliasId;

                if (personAliasId.HasValue)
                {
                    // Create a background check file
                    using (var newRockContext = new RockContext())
                    {
                        var backgroundCheckService = new BackgroundCheckService(newRockContext);
                        var backgroundCheck        = backgroundCheckService.Queryable()
                                                     .Where(c =>
                                                            c.WorkflowId.HasValue &&
                                                            c.WorkflowId.Value == workflow.Id)
                                                     .FirstOrDefault();

                        if (backgroundCheck == null)
                        {
                            backgroundCheck = new Rock.Model.BackgroundCheck();
                            backgroundCheck.PersonAliasId = personAliasId.Value;
                            backgroundCheck.WorkflowId    = workflow.Id;
                            backgroundCheckService.Add(backgroundCheck);
                        }

                        backgroundCheck.RequestDate = RockDateTime.Now;
                        backgroundCheck.RequestId   = transactionId.ToString();
                        backgroundCheck.PackageName = request.PackageName;
                        newRockContext.SaveChanges();
                    }
                }
                return(true);
            }

            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, null);
                errorMessages.Add(ex.Message);
                return(false);
            }
        }
Exemple #8
0
        /// <summary>
        /// Saves the results.
        /// </summary>
        /// <param name="xResult">The x result.</param>
        /// <param name="workflow">The workflow.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="saveResponse">if set to <c>true</c> [save response].</param>
        public static void SaveResults( XDocument xResult, Rock.Model.Workflow workflow, RockContext rockContext, bool saveResponse = true )
        {
            bool createdNewAttribute = false;

            var newRockContext = new RockContext();
            var service = new BackgroundCheckService( newRockContext );
            var backgroundCheck = service.Queryable()
                .Where( c =>
                    c.WorkflowId.HasValue &&
                    c.WorkflowId.Value == workflow.Id )
                .FirstOrDefault();

            if ( backgroundCheck != null && saveResponse )
            {
                // Clear any SSN nodes before saving XML to record
                foreach ( var xSSNElement in xResult.Descendants( "SSN" ) )
                {
                    xSSNElement.Value = "XXX-XX-XXXX";
                }

                backgroundCheck.ResponseXml = backgroundCheck.ResponseXml + string.Format( @"
            Response XML ({0}):
            ------------------------
            {1}

            ", RockDateTime.Now.ToString(), xResult.ToString() );
            }

            var xOrderXML = xResult.Elements( "OrderXML" ).FirstOrDefault();
            if ( xOrderXML != null )
            {
                var xOrder = xOrderXML.Elements( "Order" ).FirstOrDefault();
                if ( xOrder != null )
                {
                    bool resultFound = false;

                    // Find any order details with a status element
                    string reportStatus = "Pass";
                    foreach ( var xOrderDetail in xOrder.Elements( "OrderDetail" ) )
                    {
                        var xStatus = xOrderDetail.Elements( "Status" ).FirstOrDefault();
                        if ( xStatus != null )
                        {
                            resultFound = true;
                            if ( xStatus.Value != "NO RECORD" )
                            {
                                reportStatus = "Review";
                                break;
                            }
                        }
                    }

                    if ( resultFound )
                    {
                        // If no records found, still double-check for any alerts
                        if ( reportStatus != "Review" )
                        {
                            var xAlerts = xOrder.Elements( "Alerts" ).FirstOrDefault();
                            if ( xAlerts != null )
                            {
                                if ( xAlerts.Elements( "OrderId" ).Any() )
                                {
                                    reportStatus = "Review";
                                }
                            }
                        }

                        // Save the recommendation
                        string recommendation = ( from o in xOrder.Elements( "Recommendation" ) select o.Value ).FirstOrDefault();
                        if ( !string.IsNullOrWhiteSpace( recommendation ) )
                        {
                            if ( SaveAttributeValue( workflow, "ReportRecommendation", recommendation,
                                FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ), rockContext,
                                new Dictionary<string, string> { { "ispassword", "false" } } ) )
                            {
                                createdNewAttribute = true;
                            }

                        }

                        // Save the report link
                        Guid? binaryFileGuid = null;
                        string reportLink = ( from o in xOrder.Elements( "ReportLink" ) select o.Value ).FirstOrDefault();
                        if ( !string.IsNullOrWhiteSpace( reportLink ) )
                        {
                            if ( SaveAttributeValue( workflow, "ReportLink", reportLink,
                                FieldTypeCache.Read( Rock.SystemGuid.FieldType.URL_LINK.AsGuid() ), rockContext ) )
                            {
                                createdNewAttribute = true;
                            }

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

                        // Save the status
                        if ( SaveAttributeValue( workflow, "ReportStatus", reportStatus,
                            FieldTypeCache.Read( Rock.SystemGuid.FieldType.SINGLE_SELECT.AsGuid() ), rockContext,
                            new Dictionary<string, string> { { "fieldtype", "ddl" }, { "values", "Pass,Fail,Review" } } ) )
                        {
                            createdNewAttribute = true;
                        }

                        // Update the background check file
                        if ( backgroundCheck != null )
                        {
                            backgroundCheck.ResponseDate = RockDateTime.Now;
                            backgroundCheck.RecordFound = reportStatus == "Review";

                            if ( binaryFileGuid.HasValue )
                            {
                                var binaryFile = new BinaryFileService( newRockContext ).Get( binaryFileGuid.Value );
                                if ( binaryFile != null )
                                {
                                    backgroundCheck.ResponseDocumentId = binaryFile.Id;
                                }
                            }
                        }
                    }
                }
            }

            newRockContext.SaveChanges();

            if ( createdNewAttribute )
            {
                AttributeCache.FlushEntityAttributes();
            }
        }
Exemple #9
0
        /// <summary>
        /// Sends a background request to Protect My Ministry
        /// </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>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <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
        ///     RequestStatus:          The request status returned by PMM request
        ///     RequestMessage:         Any error messages returned by PMM request
        ///     ReportStatus:           The report 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>();

            try
            {
                // Check to make sure workflow is not null
                if ( workflow == null )
                {
                    errorMessages.Add( "The 'Protect My Ministry' background check provider requires a valid workflow." );
                    return false;
                }

                // Get the person that the request is for
                Person person = null;
                if ( personAttribute != null )
                {
                    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();
                        person.LoadAttributes( rockContext );
                    }
                }

                if ( person == null )
                {
                    errorMessages.Add( "The 'Protect My Ministry' background check provider requires the workflow to have a 'Person' attribute that contains the person who the background check is for." );
                    return false;
                }

                string password = Encryption.DecryptString( GetAttributeValue( "Password" ) );

                XElement rootElement = new XElement( "OrderXML",
                    new XElement( "Method", "SEND ORDER" ),
                    new XElement( "Authentication",
                        new XElement( "Username", GetAttributeValue( "UserName" ) ),
                        new XElement( "Password", password )
                    )
                );

                if ( GetAttributeValue( "TestMode" ).AsBoolean() )
                {
                    rootElement.Add( new XElement( "TestMode", "YES" ) );
                }

                rootElement.Add( new XElement( "ReturnResultURL", GetAttributeValue( "ReturnURL" ) ) );

                XElement orderElement = new XElement( "Order" );
                rootElement.Add( orderElement );

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

                XElement subjectElement = new XElement( "Subject",
                    new XElement( "FirstName", person.FirstName ),
                    new XElement( "MiddleName", person.MiddleName ),
                    new XElement( "LastName", person.LastName )
                );
                orderElement.Add( subjectElement );

                if ( person.SuffixValue != null )
                {
                    subjectElement.Add( new XElement( "Generation", person.SuffixValue.Value ) );
                }
                if ( person.BirthDate.HasValue )
                {
                    subjectElement.Add( new XElement( "DOB", person.BirthDate.Value.ToString( "MM/dd/yyyy" ) ) );
                }

                if ( ssnAttribute != null )
                {
                    string ssn = Encryption.DecryptString( workflow.GetAttributeValue( ssnAttribute.Key ) ).AsNumeric();
                    if ( !string.IsNullOrWhiteSpace( ssn ) && ssn.Length == 9 )
                    {
                        subjectElement.Add( new XElement( "SSN", ssn.Insert( 5, "-" ).Insert( 3, "-" ) ) );
                    }
                }

                if ( person.Gender == Gender.Male )
                {
                    subjectElement.Add( new XElement( "Gender", "Male" ) );
                }
                if ( person.Gender == Gender.Female )
                {
                    subjectElement.Add( new XElement( "Gender", "Female" ) );
                }

                string dlNumber = person.GetAttributeValue( "com.sparkdevnetwork.DLNumber" );
                if ( !string.IsNullOrWhiteSpace( dlNumber ) )
                {
                    subjectElement.Add( new XElement( "DLNumber", dlNumber ) );
                }

                var homelocation = person.GetHomeLocation();
                if ( homelocation != null)
                {
                    subjectElement.Add( new XElement( "CurrentAddress",
                        new XElement( "StreetAddress", homelocation.Street1 ),
                        new XElement( "City", homelocation.City ),
                        new XElement( "State", homelocation.State ),
                        new XElement( "Zipcode", homelocation.PostalCode )
                    ) );
                }

                XElement aliasesElement = new XElement( "Aliases" );
                if ( person.NickName != person.FirstName )
                {
                    aliasesElement.Add( new XElement( "Alias", new XElement( "FirstName", person.NickName ) ) );
                }

                foreach ( var previousName in person.GetPreviousNames() )
                {
                    aliasesElement.Add( new XElement( "Alias", new XElement( "LastName", previousName.LastName ) ) );
                }

                if ( aliasesElement.HasElements )
                {
                    subjectElement.Add( aliasesElement );
                }

                DefinedValueCache pkgTypeDefinedValue = null;
                string packageName = "BASIC";
                string county = string.Empty;
                string state = string.Empty;
                string mvrJurisdiction = string.Empty;
                string mvrState = string.Empty;

                if ( requestTypeAttribute != null )
                {
                    pkgTypeDefinedValue = DefinedValueCache.Read( workflow.GetAttributeValue( requestTypeAttribute.Key ).AsGuid() );
                    if ( pkgTypeDefinedValue != null )
                    {
                        if ( pkgTypeDefinedValue.Attributes == null )
                        {
                            pkgTypeDefinedValue.LoadAttributes( rockContext );
                        }

                        packageName = pkgTypeDefinedValue.GetAttributeValue("PMMPackageName");
                        county = pkgTypeDefinedValue.GetAttributeValue( "DefaultCounty" );
                        state = pkgTypeDefinedValue.GetAttributeValue( "DefaultState" );
                        Guid? mvrJurisdictionGuid = pkgTypeDefinedValue.GetAttributeValue( "MVRJurisdiction" ).AsGuidOrNull();
                        if ( mvrJurisdictionGuid.HasValue )
                        {
                            var mvrJurisdictionDv = DefinedValueCache.Read( mvrJurisdictionGuid.Value );
                            if ( mvrJurisdictionDv != null )
                            {
                                mvrJurisdiction = mvrJurisdictionDv.Value;
                                if ( mvrJurisdiction.Length >= 2 )
                                {
                                    mvrState = mvrJurisdiction.Left( 2 );
                                }
                            }
                        }

                        if ( homelocation != null )
                        {
                            if ( !string.IsNullOrWhiteSpace( homelocation.County ) &&
                                pkgTypeDefinedValue.GetAttributeValue("SendHomeCounty").AsBoolean() )
                            {
                                county = homelocation.County;
                            }

                            if ( !string.IsNullOrWhiteSpace( homelocation.State ) )
                            {
                                if ( pkgTypeDefinedValue.GetAttributeValue( "SendHomeState" ).AsBoolean() )
                                {
                                    state = homelocation.State;
                                }
                                if ( pkgTypeDefinedValue.GetAttributeValue( "SendHomeStateMVR" ).AsBoolean() )
                                {
                                    mvrState = homelocation.State;
                                }
                            }
                        }
                    }
                }

                if ( !string.IsNullOrWhiteSpace( packageName ) )
                {
                    orderElement.Add( new XElement( "PackageServiceCode", packageName,
                        new XAttribute( "OrderId", workflow.Id.ToString() ) ) );

                    if ( packageName.Trim().Equals( "BASIC", StringComparison.OrdinalIgnoreCase ) ||
                        packageName.Trim().Equals( "PLUS", StringComparison.OrdinalIgnoreCase ) )
                    {
                        orderElement.Add( new XElement( "OrderDetail",
                            new XAttribute( "OrderId", workflow.Id.ToString() ),
                            new XAttribute( "ServiceCode", "combo" ) ) );
                    }
                }

                if ( !string.IsNullOrWhiteSpace( county ) ||
                    !string.IsNullOrWhiteSpace( state ) )
                {
                    orderElement.Add( new XElement( "OrderDetail",
                        new XAttribute( "OrderId", workflow.Id.ToString() ),
                        new XAttribute( "ServiceCode", string.IsNullOrWhiteSpace(county) ? "StateCriminal" : "CountyCrim" ),
                        new XElement( "County", county ),
                        new XElement( "State", state ),
                        new XElement( "YearsToSearch", 7 ),
                        new XElement( "CourtDocsRequested", "NO" ),
                        new XElement( "RushRequested", "NO" ),
                        new XElement( "SpecialInstructions", "" ) )
                    );
                }

                if ( !string.IsNullOrWhiteSpace( mvrJurisdiction ) && !string.IsNullOrWhiteSpace( mvrState ) )
                {
                    orderElement.Add( new XElement( "OrderDetail",
                        new XAttribute( "OrderId", workflow.Id.ToString() ),
                        new XAttribute( "ServiceCode", "MVR" ),
                        new XElement( "JurisdictionCode", mvrJurisdiction ),
                        new XElement( "State", mvrState ) )
                    );
                }

                XDocument xdoc = new XDocument( new XDeclaration( "1.0", "UTF-8", "yes" ), rootElement );
                var requestDateTime = RockDateTime.Now;

                XDocument xResult = PostToWebService( xdoc, GetAttributeValue("RequestURL") );
                var responseDateTime = RockDateTime.Now;

                int? personAliasId = person.PrimaryAliasId;
                if ( personAliasId.HasValue )
                {
                    // Create a background check file
                    using ( var newRockContext = new RockContext() )
                    {
                        var backgroundCheckService = new BackgroundCheckService( newRockContext );
                        var backgroundCheck = backgroundCheckService.Queryable()
                            .Where( c =>
                                c.WorkflowId.HasValue &&
                                c.WorkflowId.Value == workflow.Id )
                            .FirstOrDefault();

                        if ( backgroundCheck == null )
                        {
                            backgroundCheck = new Rock.Model.BackgroundCheck();
                            backgroundCheck.PersonAliasId = personAliasId.Value;
                            backgroundCheck.WorkflowId = workflow.Id;
                            backgroundCheckService.Add( backgroundCheck );
                        }

                        backgroundCheck.RequestDate = RockDateTime.Now;

                        // Clear any SSN nodes before saving XML to record
                        foreach ( var xSSNElement in xdoc.Descendants( "SSN" ) )
                        {
                            xSSNElement.Value = "XXX-XX-XXXX";
                        }
                        foreach ( var xSSNElement in xResult.Descendants( "SSN" ) )
                        {
                            xSSNElement.Value = "XXX-XX-XXXX";
                        }

                        backgroundCheck.ResponseXml = string.Format( @"
            Request XML ({0}):
            ------------------------
            {1}

            Response XML ({2}):
            ------------------------
            {3}

            ", requestDateTime, xdoc.ToString(), responseDateTime, xResult.ToString() );
                        newRockContext.SaveChanges();
                    }
                }

                if ( _HTTPStatusCode == HttpStatusCode.OK )
                {
                    using ( var newRockContext = new RockContext() )
                    {
                        bool createdNewAttribute = false;
                        var xOrderXML = xResult.Elements( "OrderXML" ).FirstOrDefault();
                        if ( xOrderXML != null )
                        {
                            var xStatus = xOrderXML.Elements( "Status" ).FirstOrDefault();
                            if ( xStatus != null )
                            {
                                if ( SaveAttributeValue( workflow, "RequestStatus", xStatus.Value,
                                    FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ), newRockContext, null ) )
                                {
                                    createdNewAttribute = true;
                                }
                            }

                            var xErrors = xOrderXML.Elements( "Errors" ).FirstOrDefault();
                            if ( xErrors != null )
                            {
                                string errorMsg = xErrors.Elements( "Message" ).Select( x => x.Value ).ToList().AsDelimited( Environment.NewLine );
                                if ( SaveAttributeValue( workflow, "RequestMessage", errorMsg,
                                    FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ), newRockContext, null ) )
                                {
                                    createdNewAttribute = true;
                                }
                            }

                            if ( xResult.Root.Descendants().Count() > 0 )
                            {
                                SaveResults( xResult, workflow, rockContext, false );
                            }
                        }
                        else
                        {
                            if ( SaveAttributeValue( workflow, "RequestMessage", errorMessages.AsDelimited( Environment.NewLine ),
                                FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ), newRockContext, null ) )
                            {
                                createdNewAttribute = true;
                            }

                        }

                        newRockContext.SaveChanges();

                        if ( createdNewAttribute )
                        {
                            AttributeCache.FlushEntityAttributes();
                        }
                    }
                    return true;
                }
                else
                {
                    errorMessages.Add( "Invalid HttpStatusCode: " + _HTTPStatusCode.ToString() );
                    return false;
                }
            }

            catch ( Exception ex )
            {
                ExceptionLogService.LogException( ex, null );
                errorMessages.Add( ex.Message );
                return false;
            }
        }