xTuple.com xTupleU Blog & News Customer Support

Problem With Average Cost

I believe I have found the source of an average cost problem.

Scenario:
Purchase 100 pieces of Item A at $29
Item A has an average cost of $30.
User accidentally receives 1000 parts instead of 100
The we correct the receipt. The correction goes back at $30 instead of $29 Putting $900 Into Purchase Price Variance

It should have returned at the $29 price.

Here is the code that dictates this.

  -- For non-transit related inventory issues, we only accept the current unit cost as the cost at
  -- which to relieve inventory.  However, even then there are some special cases such as returns of
  -- previously received units or correcting transactions which could require a variance booking.
  -- For example purchase order returns should carry a transaction value equal to the original
  -- purchase price of the units returned which very well could differ from the current unit cost.
  -- But even in this scenario we still cannot sensibly relieve inventory at a unit cost that
  -- differs from current unit cost, so our only alternative is to book a variance for the
  -- difference between transaction value and the inventory value being issued.

  IF _contextData.warehous_transit AND pOverrideTransValue IS NOT NULL THEN
    _resolvedUnitCost := pOverrideTransValue / pIssueQty;
  ELSE
    _resolvedUnitCost := _contextData.itemsite_unitcost;
  END IF;

  _varianceAmount := (_resolvedUnitCost * pIssueQty) -
                      COALESCE(pOverrideTransValue, _resolvedUnitCost * pIssueQty);

Reading a the description it clearly states intent.

Purchase order returns should carry a transaction value equal to the original purchase price of the units returned which very well could differ from the current unit cost

It goes on to state that it will not be following that scenario.

But even in this scenario we still cannot sensibly relieve inventory at a unit cost that differs from current unit cost

What I want to know is why? I could easily change the code to

IF _contextData.warehous_transit **OR** pOverrideTransValue IS NOT NULL THEN

But it seems that xTuple staff has already thought of this and chosen not to do it for a specific reason.

Hi Caleb:
You have accurately stated what the process does. I happen to agree that all inventory “out” transactions should come out at the current unit cost. I believe the why was to maintain some consistency and provide a function that could be called to reliably remove inventory without causing a re calculation of current value or requiring any calling program to provide additional information to the function in order to process correctly (that would be the additional part of your code suggestion).

I do think you have a point and it is a reasonable debate. In my opinion is the best for xTuple. It is quite refreshing to see the explanation notes in the function. I have a client that I actually do call this function from an external application and I like to know what the value of the “out” is going to be.

On a related note I have on my “to do” list to trace these transaction completely through because I have a suspicion that we are not getting the right values back in the Univoiced Receipts account. Just a suspicion at this point because I have a client whose Uninvoiced Ledger and detail keep getting out of balance. I hope to get to that next week. Have you looked at that part of this process ?

I have the answer now after consulting with an accountant.

The problem arises when you consume the inventory at the updated average cost before you have a chance to correct the posting

I have not gotten to that part. I was just trying to find a solution to the average cost getting changed unintentionally and incorrectly. But I can see the logic on this function now why we cannot simply change the function to allow for correction at that point.