There was an issue in
SouceDocumentLineItem class, that I had to fix recently.
The failing scenario looked something like this:
- Create a direct delivery SO with inter-company chain, with one order line
- Set the line sales qty to 10
- Set the line property Completed to No, so it may be partially delivered
- After the IC chain is there, go to the IC SO and post a packing slip for qty 5
- Verify that the IC PO is also partially delivered with the same qty
- Go to the original SO and change the line qty from 10 to 7 (in our customization, this is done in the code)
- Check the IC PO accounting distributions
In our case, there was one distribution line broken (click to enlarge the picture):
Apparently, the main account for the tax amount was not found.
Because of the broken accounting distribution, the PO could not be processed, and the following error message popped up:
- One or more accounting distribution is missing a ledger account or contains a ledger account that is not valid. Use the Accounting distribution form or the Posting profile to update the ledger account.
- The state of the source document or source document line could not be updated.
Pressing Reset button did help, but our customer was not very happy about that workaround, as there were may POs broken like this.
After some hours of debugging, I found that everything starts in this method:
Here, we have a "
select forupdate", that loops through
TaxUncommitted table records and calls
submitSourceDocumentLine instance method:
The
taxUncommitted.submitSourceDocumentLine call ends up here:
In this constructor method, the
sourceDocumentLineItem class instance is first initialized from the
_sourceDocumentLineImplementation parameter (which is actually a
TaxUncommitted record buffer), and then put to cache (see
SysTransactionScopeCache::set call).
Let's look closer at the
sourceDocumentLineItem.initialize method in the debugger. The
sourceDocumentLineItem variable (which is actually
TaxSourceDocSublineItem class instance), has a member-variable of Map type, which is initialized with the
TaxUncommitted record buffer (selected for update in the while-loop, as we have seen before!):
The problem is that by the time the
sourceDocumentLineItem class instance is fetched from the cache later in the business logic, the
TaxUncommitted cursor is null, so the taxMap member-variable in the cached instance is empty and things like tax code cannot be determined anymore.
The fix was to use xRecord.data() call to separate the map from the original table buffer:
I will report the issue to MS Support.