Here is a bit of context as to what I'm doing: I have an XML-based configuration document that dictates the drill-through at runtime. Here's the relevant snippet:
Code: Select all
<Node name="CDFs" active="true">
<Handler type="EscrowCollection" target="CDFs" method="Index" />
<Nodes>
<Node name="CDF" active="true" index="0">
<Handler type="Generic" target="CDF" />
<Nodes>
<Node name="OriginationCharge" active="true">
<Handler type="Generic" target="OriginationChargeSection" />
<Nodes>
<Node name="Lines" active="true">
<Handler type="Collection" target="Lines" method="Match" matchField="Description" />
<Nodes>
<Node name="A01Line" active="true" index="1" matchField="Number">
<Handler type="CdfLine" active="true" target="OriginationChargeDetailLine" />
<Fields>
<Field key="TestNumber" target="Number" rule="Optional" readOnly="true" active="true" description="CDF Line Number (Testing purposes only)" />
</Fields>
<Nodes>
<Node name="A01Charges" active="true">
<Handler type="Collection" target="Charges" method="Index" />
<Nodes>
<Node name="A01Charge1" active="true" index="0">
<Handler type="Generic" target="" />
<Nodes>
<Node name="A01Calculation" active="true">
<Handler type="Generic" target="Calculation" />
<Fields>
<Field key="PercentOfLoanAmt" target="Percent" rule="Optional" readOnly="true" active="true" description="Percent of Loan Amount" />
</Fields>
</Node>
</Nodes>
</Node>
</Nodes>
</Node>
</Nodes>
</Node>
The engine we have deserializes this document into an object tree, and each node instantiates and contains a Handler subtype, which is responsible for finding and mapping the appropriate IOrderItem instance in the tree. The code is this for the "Generic" handler:
Code: Select all
APIObject = ((IOrderItem)Parent.APIObject).GetProperty(Node.Handler.Target);
In this snippet, "Node.Handler.Target" is just a string in the config document that defines the name of the property to get. For collections, it's a bit more complex, as the child nodes to the collection can be set up either by straight Index, or by field match (XPath definition: //Handler[@method='Index|Match']). the matchField then dictates what IOrderItem field to perform the match on.
So, all that having been said, here is the yield of the drill-through, to the CDF Line level, with the object name and type:
CDF (type CDF) ->
OriginationChargeDetailSection (type OriginationChargeDetailSection) ->
Lines (full type name is SoftPro.EntityModel.Collections.Set`1[[OriginationChargeDetailLine, SoftPro.OrderTracking.Order_ab58e2dfbb0280044a25794465b4fb6f, Version=4.3.60108.11, Culture=neutral, PublicKeyToken=8ae96314b6bae08d]]) ->
(Target line), type OriginationChargeDetailLine.
------
In the particular order that's giving me trouble, I'm not instantiating any IOrderItem objects, just polling over what already exists in the order. One complication with CDF lines is that we're trying to match the Description field to an existing line (except in the case of A.01, which matches on number), and if that fails, iterating through the Lines collection to find the next available line without a description, and attempting to set the Description field there. This is where the problem lies: the field is marked as calculated. The template that I'm using has plenty of CDF lines for that section already set, and only the A.01 one has the Description pre-set. So, I should not have to create a new Line at any time for our purposes.