Validate data as “unit of work”

Fairly new to Salesforce and come from a non-SFDC enterprise development background. Using FinancialForce framework and enterprise patterns in our development.

Question as it relates to best practice for development given the following:

Requirement Example – A Purchase Order must have at least 1 item and the item must have at least 1 delivery schedule and the SUM(DeliverySchedule.Quantity) must equal the Item.Quantity.

Details – In order to be able to support the above, all data must be “insert”ed at the same time within a single transaction so all UI development is custom VF. The challenge is that if there are more than 200 Delivery Schedule records for an Item, OnBefore/ValidationRules/OnAfter fires in blocks of 200. In this case, we can’t validate yet because there is more data coming and we would fail our “SUM(DeliverySchedule.Quantity)=Item.Quantity rule.

In SFDC, if you “insert List” for 1000 records, you’re validation rule will fire 5 times (if I’m understanding how it works properly). Also, as soon as you insert the header, it’s validation rule would fire and it would fail because it doesn’t have an item yet.

In thinking through the possible solutions, a couple of ideas come to mind but none of which I really like and they all have one shortcoming or another.

Ideas are:

1) Extra field on each SObject that gets “toggled” by API layer, then upsert, then toggle back. This will fire Validation rules multiple times but the last time the validation will be enforced. This has unnecessary extra DML statements, multiple “execution process” iterations, requires an extra field and lots of coordination of the flipping of that field by the API layer.

2) Static variable (request context specific as I understand it) which gets flipped, ValidationRules in APEX onBefore and check static variable. This has downside of transaction coordination across objects that have rollups so it gets messy and likely wouldn’t work.

The only way I can think to do this is to have a true Service API layer that locks records, processes in-memory (including keeping track of rollup values, etc.), calling “IsValid()” on each SObject in unitOfwork and then rollback/commit. The downside to this approach is that we lose a lot of the stock features of SFDC and/or third-party packages because everything MUST go through our API to save. There’s also a data integrity risk if someone didn’t go through our API (e.g. rogue user using REST API, Unsuspecting Admin using Standard Layout page, etc.). We can protect against the data integrity with some of the concepts in #1 or #2 above but it’s not ideal.

Question – What are the best practices for development/architecture in these scenarios on SFDC platform and using FinancialForce?

Thank you for any assistance, greatly appreciated!

-jd

Answer

You can’t generally enforce “rows of child data on insert” in salesforce.com. What I usually recommend is that a particular record can’t progress to another stage until the conditions are satisfied. For example, you might have a Status field on the purchase order. This might be one of “Preparing”, “Ready to Fulfill”, etc. At that point, it becomes trivial to key off of the status field. This is essentially (#1), as you’ve described, except that it’s intentional, and the user can use the UI to enter as much data as they want until the stage is advanced, in which case the record must be in a sane state. The most usual cases for this type of behavior includes opportunities, orders, and quotes, in order to add product line items before attempting to move them to a more defined phase. And, no, your static variable idea generally won’t work for several reasons, including the fact that validation rules can’t see Apex variables, except custom settings, which would bleed across transactions.

Attribution
Source : Link , Question Author : Jon Davis , Answer Author : sfdcfox

Leave a Comment