I ended the previous message on this subject by discussing the inventdim and stating that the introduction of this element had caused quite a lot of heartache in many installations.
In the previous product (XAL) the fields constituting the stock keeping unit as well as the stocking dimensions were found in all the relevant tables, from the sales order lines through the invoice lines down to the inventory transactions themselves.
When Benny was designing the database for the new model some smart Db developer suggested normalising this structure by creating a reference to a new table that contained the information.
This would significantly reduce the amount of data stored in the database, as now the transaction files would only contain a reference id (inventdimid) rather than all the fields (ConfigurationId, SizeID, ColourId, etc). Another thing that this simplified was the ability to add more dimensions to the table seemingly effortlessly, or at least with minimal effort.
So now inventdimid was added to
InventSum (Summary Table containing sum of inventTrans for that dimension combination or inventdimId)
InventSumLogTTS (Used by MRP when doing reduced calculations and also by IMTS)
SalesLine (Sales order lines default values for InventDimId)
PurchLine (Purchase order lines default values for InventDimId)
CustConfirmTrans
CustPickingListTrans
CustPackingSlipTrans
CustInvoiceTrans (Sales order flow lines note could be different InventDimId’s attached to lines in inventTrans that are attached to each document line)
VendPurchOrderTrans
VendReceiptListTrans
VendPackingSlipTrans
VendInvoiceTrans (Similar to above flow except this time purchase related, again same comment applies that the InventdimID of the line could be different on the linked InventTrans)
InventTrans
Are some of the main tables containing our new InventDimId field, I have not mentioned the MRP, Warehouse management, project, requirement planning tables that also include it but you can easily add those your self if you wish.
Note some notable additions in V4
InventSumDelta
InventSumDeltaDim
And
InventSumDateTable
InventSumDateTrans
Because of the nature of inventory valuation reports and their dependence upon the data contained in the above and 2 further tables that are intrinsically linked to the valuation of stock
InventSettlement (Contains all the inventory re-evaluations that have been carried out against any given transaction)
InventTransPosting (Contains the accounts on which valuation and re-valuation has posted values pertaining to a given inventory transaction)
It is given the data structure necessary to create a report using InventTrans joined to Inventdim through the InventDimId joined to InventSettlements in best case and in worst case with a search on the settlements in order to populate a report with correct values.
And if the report is as of a date it is even worse as it has to then first look at inventsum, deduct the inventtrans and or invensettlements that it has done after the date, trusting the user to have carried them out correctly and then present the resulting information as it’s version of the truth.
The Select statement looks like some version of the below taken directly from some of the classes doing this:
select forceplaceholders sum(CostAmountPhysical) from inventTrans
where inventTrans.StatusReceipt == StatusReceipt::None &&
inventTrans.StatusIssue == StatusIssue::Deducted &&
inventTrans.ItemId == itemId
exists join inventTransPosting
where inventTrans.VoucherPhysical == inventTransPosting.Voucher &&
inventTrans.DatePhysical == inventTransPosting.TransDate &&
inventTrans.InventTransId == inventTransPosting.InventTransId &&
inventTransPosting.InventTransPostingType == InventTransPostingType::Physical &&
inventTransPosting.IsPosted == NoYes::Yes
#inventDimExistsJoin(inventTrans.InventDimId,inventDim,inventDimCriteria,inventDimParm);
postedPhysicalValue += inventTrans.CostAmountPhysical;
select forceplaceholders sum(CostAmountAdjustment) from inventSettlement
index hint ItemDateIdx
where inventSettlement.ItemId == itemId &&
inventSettlement.Cancelled == NoYes::No &&
inventSettlement.Posted == NoYes::Yes &&
inventSettlement.TransDate > perDate &&
inventSettlement.SettleModel == InventSettleModel::PhysicalValue
exists join inventTrans
index hint RecId
where inventTrans.RecId == inventSettlement.TransRecId &&
inventTrans.StatusIssue == StatusIssue::Deducted
#inventDimExistsJoin(inventTrans.InventDimId,inventDim2,inventDimCriteria,inventDimParm)
exists join inventTransPostingPhysical
index hint DateVoucherTransIdx
where inventTrans.VoucherPhysical == inventTransPostingPhysical.Voucher &&
inventTrans.DatePhysical == inventTransPostingPhysical.TransDate &&
inventTrans.InventTransId == inventTransPostingPhysical.InventTransId &&
inventTransPostingPhysical.InventTransPostingType == InventTransPostingType::Physical &&
inventTransPostingPhysical.IsPosted == NoYes::Yes;
postedPhysicalValue -= inventSettlement.CostAmountAdjustment;
Regardless of how much you may update / optimise your SQL server given that there are a large number of rows in InventTrans, double that in InventTransPosting and at least double that in InventSettlements (if using average costing) the above query is deadly for the database in terms of performance.
In order to counter this Benny has developed his fast reporting tool which you will find advertised on his web site, and MS have added the InventSumDateTable and the InventSumDateTrans tables which basically do the above queries but store the results in a table which is then consultable.
Unfortunately again the table does not contain a simple date rather they have chosen to have just a parmId reference stipulating the reference number of the calculation having been carried out, and then to use adjustments based on this so again if you want the values as of a date you are stuck doing a subsequent query to get back to a situation back in time.
Enough about InventDim & InventDimId.
InventSum as stated earlier contains a summary of the linked InventTransactions based on the InventdimID associated broken down by the StatusIssue and StatusReceipt fields the transaction is summarized in this table.
This action is carried out based on any change to the inventTrans table, that is the simple fact of doing an update or insert on a record in that table will automatically be reflected in the InventSum table, if it is an update 2 inventsum records could be affected (if the inventdimid changes).
The InventTransPosting table contains the Ledger accounts that have been impacted (posted on) during the update of either a physical transaction or a financial transaction. The reason for having this table is to allow subsequent revaluations of the inventory transactions to be posted in the GL using the same account numbers as the original transaction.
Example:
We introduce a new item in the catalogue, and purchase 100 pieces with an assumed price of 1 units / piece, we receive the items in stock and start selling the items.
When we have sold half the lot of 100 we receive the purchase invoice which is for 90 cents / piece only as we have already had COGS (Cost of Goods Sold) recognized as 50 * 1 unit or 50 Units on the total of 90 (90 cents * 100) there are only 40 units left to share on the remaining 50 units this makes the COGS / piece = 40/50 or 80 cents on the remaining 50 units.
To correct the above Ax has an inventory costing mechanism that allows the system to recalculate a more accurate valuation and correct the COGS of the already sold transactions.
The InventSettlement table will contain the corrections to the existing transactions which would deduct 10 cents / piece for the old invoices and add 10 cents to any new ones.In order to ensure the right accounts and financial dimensions are impacted the account numbers as well as the financial dimensions are stored in the InventTransPosting table.
Sound complicated well not really compared to others it is quite simple but meethinks I will continue later.
/Sven
Tuesday, 8 May 2007
Subscribe to:
Post Comments (Atom)
3 comments:
Thanks for your posts about data sharing in AX.
But I desperately need an information pour one of my customers : It is a group constituted of 10 companies, and they need to share all basic info (customers, vendors, accounts...).
But when I share CustTable, it is mandatory to share all Setup tables linked to the CustTable.
And there is no way to find an exhustive list of these Setup tables (level 1, level 2, level n).
Any help ?
Thanks in advance
Unfortunately in a way you are right, there are some toools that can help in V3 using the morphx Explorer and in V4 the retro function in order to find what tables may need to be shared.
Based on the pour in your comment you are either from France or Canada. If it is France then C2A may have a solution for you. They have developped a solution where they syncronize other tables (such as setup tables) across a configurable number of companies.
You may want to speak to them, I believe I started them along the path in that I had created an automated set of tools to create entries in the InventTableModule and InventItemLocation Tables in other companies when sharing the InventTable.
I will probably add this limited utility here soon as freeware.
It is not mandatory to share all linked tables however certain tables are of necessity present in the other companies if certain things are to function.
f.ex. the VAT / Tax Group ensuring VAT being correctly posted or the Customer group ensuring the debtor control accounts are properly posted.
Hi Sven and Anon.
FYI, we recently used the C2A module on a project to create a multi-logistics/mono-finance company setup.
We even enhanced so that individual records could be shared (or not) acording to user decision. e.g. a customer is duplicated to companies X and Y but not Z, but only selected fields will be kept updated... all managed by coded strategies (schema) to allow it to be user-friendly (usable!)
You can contact me at ncram@prodware.fr for more information.
Thanks Sven for the interesting information concerning InventSumDateTable/Trans, surely it would not require a VAST amount of programming for MS to include the date, bet I could do it in an evening (but I'll let MS do it)
Cheers
Nick
Post a Comment