Title Insurance Calculations/Underwriter

Discussions concerning general integration topics.

Moderator: Phil Barton

dlerickson
Posts: 80
Joined: Tue Jan 21, 2014 11:35 am
Location: Austin, TX

Title Insurance Calculations/Underwriter

Post by dlerickson »

Hi, I have a request from the business to run a process that will inspect the Title Insurance Calculations entries for a particular order, and wherever the Underwriter is missing or the Underwriter.Code is not "U" (including being null), set the Underwriter accordingly. I've included some code snippets illustrating the process (edited to remove irrelevant bits). Here's the main process:

Code: Select all

            dynamic title = order["Title"];
            dynamic calcs = title.TitleInsuranceCalculations;
            var underwriterContact = OrderContactHelper.GetByType(order, "U").FirstOrDefault();  // details in snippet below

            foreach (var calc in calcs)
            {
                dynamic underwriter = calc.Underwriter;

                if (underwriter == null)
                {
                    dynamic newUnderwriter = (dynamic)order.CreateNew("Underwriter");
                    newUnderwriter.LookupCode = "FA";  // NOTE: not sure this needs to be here; was using another Underwriter instance as a guide
                    calc.Underwriter = newUnderwriter;

                }
                else if (underwriter.Code == null && underwriter.Code != "U")
                {
                    if (underwriterContact != null)
                    {
                        underwriter.Contact = underwriterContact;
                    }
                }
            }
Here's OrderContactHelper.GetByType, which does what you probably suspect:

Code: Select all

        
        public static IEnumerable<IOrderItem> GetByType(IOrder order, string contactType)
        {
            var returnList = new List<IOrderItem>();
            dynamic contacts = (dynamic) order["Contacts"];

            if (contacts != null)
            {
                foreach (var contact in contacts)
                {
                    if (((string)contact.Code).Equals(contactType))
                    {
                        returnList.Add(contact);
                    }
                }
            }

            return returnList;
        }
When I run this code, a couple of different errors are generated, depending on the order that I use. A couple examples of return messages/stack traces/etc. below. I'll reference these by order number, which is mostly irrelevant to the problem, but included just in case you have questions about a specific error.

Order 140-140200231
Exception Message: The specified value violates the SoftPro.ClientModel.Validations.AllowedValuesAttribute constraint.
Stack Trace:

Code: Select all

   at SoftPro.EntityModel.ValidationConstraintInstance.Check(Object value)
   at SoftPro.EntityModel.Field`1.OnValueChanging(T oldValue, T newValue)
   at SoftPro.EntityModel.Field`1.set_Value(T value)
   at TitleInsuranceCalculation.set_Underwriter(Underwriter )
   at CallSite.Target(Closure , CallSite , Object , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at Title.ClientIntegration.Application.APIServices.UnderwriterSetHandler.Execute(IOrderQuery query, IOrder order) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\UnderwriterSetHandler.cs:line 32
   at Title.ClientIntegration.Application.APIServices.APIRequestProcessor.ExecuteQueryBatch(IOrderOperationBatch operationBatch, IOrder order) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\APIRequestProcessor.cs:line 153
   at Title.ClientIntegration.Application.APIServices.APIRequestProcessor.ExecuteQueryBatch(IOrderOperationBatch batch, IOrderStore orderStore) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\APIRequestProcessor.cs:line 99
Order 140-140203850
Exception Message: Cannot access member.
Stack Trace:

Code: Select all

   at SoftPro.EntityModel.Field`1.set_Value(T value)
   at TitleInsuranceCalculation.set_Underwriter(Underwriter )
   at CallSite.Target(Closure , CallSite , Object , Object )
   at Title.ClientIntegration.Application.APIServices.UnderwriterSetHandler.Execute(IOrderQuery query, IOrder order) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\UnderwriterSetHandler.cs:line 32
   at Title.ClientIntegration.Application.APIServices.APIRequestProcessor.ExecuteQueryBatch(IOrderOperationBatch operationBatch, IOrder order) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\APIRequestProcessor.cs:line 153
   at Title.ClientIntegration.Application.APIServices.APIRequestProcessor.ExecuteQueryBatch(IOrderOperationBatch batch, IOrderStore orderStore) in C:\Development\SVN\DHISource\DHI\trunk\WebApps\SoftPro.Administration\Title.ClientIntegration.Application\APIServices\APIRequestProcessor.cs:line 99
I'm assuming I'm making a mistake somewhere in the code that's responsible for setting the values. Any help or guidance on this? Thanks.
John Morris
Posts: 411
Joined: Thu Sep 11, 2008 11:35 am
Location: Raleigh, NC, USA
Contact:

Re: Title Insurance Calculations/Underwriter

Post by John Morris »

A few comments about your code.

1. In your code, you create the Underwriter, but don't add it to the Contacts collection before using it. You need to create and then add the new contact to the Order.Contacts collection. Then you should be able to assign other properties to that reference. Like so:

Code: Select all

                if (underwriter == null)
                {
                    dynamic newUnderwriter = (dynamic)order.CreateNew("Underwriter");
                    ((IList)order.Contacts).Add(newUnderwriter); //THIS IS THE CODE YOU NEED
                    newUnderwriter.LookupCode = "FA";  // NOTE: not sure this needs to be here; was using another Underwriter instance as a guide
                    calc.Underwriter = newUnderwriter;
                }
That issue most likely explains your first error (constraint violation).

2. As for the second error (access denied), you should make sure the field is not read only.

3. When and where does this code run?
John Morris
Sr. Software Architect
SoftPro
dlerickson
Posts: 80
Joined: Tue Jan 21, 2014 11:35 am
Location: Austin, TX

Re: Title Insurance Calculations/Underwriter

Post by dlerickson »

1. Thanks for the clarification. Question on that: this code, which is previous to the block you highlighted, pulls whatever it can find for a contact of type "U", which is separate from the logic used to find the Underwriter for a specific TitleInsuranceCalculation. If that contact is already in the order, is it OK to just use that one for setting the property instead of creating a new one for that instance? I'm assuming that it would be from previous experience, but it's worth asking anyway.

Code: Select all

var underwriterContact = OrderContactHelper.GetByType(order, "U").FirstOrDefault();
2. Is there a way of overriding read-only status and forcing a write in that situation? If so, is that available at the module level or the order level or both? (Note: this entire chunk of code only executes if the order itself can be opened in write mode).

3. Right now, this code is being executed from a web application. It's in Windows Authentication mode, so I've been letting the SelectServer handle the credentials internally. That part seems to be working fine. This is all part of the process of refactoring a previous codebase I had with the intention of modularizing the handling of order manipulation, and allowing the code to be run from either a standalone app or within the Select Shell environment.

Code: Select all

...
                using (var server = new SelectServer(DHIConfigurationManager.GetAppSetting("SelectServerURL")))
                {
                    string authMessage;

                    if (!server.TryAuthenticate(out authMessage))
                    {
                        throw new ApplicationException(authMessage);
                    }

                    ExecuteAsync(batches, server.GetService<IOrderStore>());
                }
...
One other thing you may have noticed, and I had forgotten to ask about in the original post, is the 'ExecuteAsync' call. This basically uses the Task Parallel Library to run jobs for multiple orders on separate threads. Is this [officially supported | unsupported but may work | destined to fail miserably] in 3.x+?
John Morris
Posts: 411
Joined: Thu Sep 11, 2008 11:35 am
Location: Raleigh, NC, USA
Contact:

Re: Title Insurance Calculations/Underwriter

Post by John Morris »

1. Yes, that's ok.

2.You cannot bypass the readonly state of a field from that API. Only Custom Order Rules (in IronPython) can set a value that appears read only to the user. This isn't about readonly orders. The field is getting locked down, probably because of some status flag (closed, sent, etc.).

3. It is perfectly ok to work with multiple orders with multiple threads. Just make sure you do not have MULITPLE threads working against the SAME order instance. That isn't supported.
John Morris
Sr. Software Architect
SoftPro
dlerickson
Posts: 80
Joined: Tue Jan 21, 2014 11:35 am
Location: Austin, TX

Re: Title Insurance Calculations/Underwriter

Post by dlerickson »

Back to this after a bit of a lull. What are all of the conditions that would lock the Underwriter property on a TitleInsuranceCalculation, and how can these be mitigated? The specific instance that I'm running into problems with is trying to reconcile entries on Closed/Cancelled/etc. orders that show a null for the Underwriter property, and in that case, trying to set it to a contact of type Underwriter. In trying to address this via the API, I've taken the following steps:

1. Ensure that the OrderStatus is set to OrderStatus.InProcess
2. Ensure that the EscrowStatus on the order is set to EscrowStatus.InProcess
3. Ensure that the LockStatus on the Escrow object is set to LockStatus.Unlocked

Following this, for each existing TitleInsuranceCalculation entry that shows null for its Underwriter property, I'll either attempt to retrieve and set it using the existing Underwriter contact, or, if it doesn't exist, create a new Underwriter contact, add it to the Contacts collection, and then attempt to set the Underwriter property on the TitleInsuranceCalculation entry using that instance.

This invariably fails, with the cause almost always being that a check of the IsLocked method on the TitleInsuranceCalculation indicates that the Underwriter field is locked (there was one instance where it failed due to a check of IsCalculated, which I can't explain). I can only conclude one of the following:

1. There are additional steps to be taken, outside of the ones listed above, in order to ensure that the Underwriter field is unlocked, or,
2. Once an order is set to Closed or Cancelled status, the Underwriter field is irreversably locked, regardless of changes to Order- or Escrow-level status.

Any assistance is appreciated, as we're on the verge of abandoning the API project and going through the grueling task of changing hundreds of orders manually via the UI.
BobRichards
Posts: 1376
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Title Insurance Calculations/Underwriter

Post by BobRichards »

If you have successfully done this operation from the Select UI (since you are contemplating doing this manually), you should be able to perform all steps programmatically. How does your manual process differ from you API approach?
Bob Richards, Senior Software Developer, SoftPro
dlerickson
Posts: 80
Joined: Tue Jan 21, 2014 11:35 am
Location: Austin, TX

Re: Title Insurance Calculations/Underwriter

Post by dlerickson »

OK. One thing I realized after going through the manual process is that I was not calling [OrderStore].ApplyChanges after changing the status entries. However, while this did unlock the Underwriter property, it's now showing as a calculated field. Any reason for this?
BobRichards
Posts: 1376
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Title Insurance Calculations/Underwriter

Post by BobRichards »

Is there a formula embedded in the field or a Custom Order Rule?
Bob Richards, Senior Software Developer, SoftPro
cgriffin
Posts: 22
Joined: Mon Nov 17, 2014 6:14 pm

Re: Title Insurance Calculations/Underwriter

Post by cgriffin »

Hi Bob,

I work with Dave, the answer to your question is - no.

Thanks,
Colin.
BobRichards
Posts: 1376
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Title Insurance Calculations/Underwriter

Post by BobRichards »

Is this impeding you? I assume you can simply overwrite the field since everything is unlocked.
Bob Richards, Senior Software Developer, SoftPro
Post Reply