[FIX] stock_account: account/valuation inconsistencies
When the product price is divided per product unit, inconsistencies may arise between the real stock valuation and the stock valuation account. This is likely to happen when a product is bought in a UoM different from the standard UoM of the product. A numerical example is the following: a box of 13 is bought for 15.00. An amount of 15.00 is recorded when the products enter the stock. If the product leave the stock one at a time, 13 entries of 1.15 are recorded (15.00/13 = 1.153846... ≈ 1.15), which is then equal to 13 * 1.15 = 14.95. In this case, All the products have left the stock (stock valuation is zero), but 5 cents remain on the account. This is of course even worse the higher the ratio is. For example, a box of 4.00 split into 1000 units sold piece by piece will never be recorded when a product leaves the stock. The fix is to record the rounding difference on a specific quant. In the previous example, instead of adding 1.153846... on the unit cost of the 13 units, we do the following: - 12 units to which we add 1.15 on unit cost - 1 unit to which we add 1.20 on unit cost opw-675222
This commit is contained in:
parent
bd025cda6a
commit
262d98bb69
|
@ -20,6 +20,7 @@
|
|||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools import float_compare, float_round
|
||||
from openerp.tools.translate import _
|
||||
from openerp import SUPERUSER_ID, api
|
||||
import logging
|
||||
|
@ -152,9 +153,33 @@ class stock_quant(osv.osv):
|
|||
self._create_account_move_line(cr, uid, quants, move, acc_valuation, acc_dest, journal_id, context=ctx)
|
||||
|
||||
def _quant_create(self, cr, uid, qty, move, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, force_location_from=False, force_location_to=False, context=None):
|
||||
quant_obj = self.pool.get('stock.quant')
|
||||
quant = super(stock_quant, self)._quant_create(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, src_package_id=src_package_id, dest_package_id=dest_package_id, force_location_from=force_location_from, force_location_to=force_location_to, context=context)
|
||||
if move.product_id.valuation == 'real_time':
|
||||
self._account_entry_move(cr, uid, [quant], move, context)
|
||||
|
||||
# If the precision required for the variable quant cost is larger than the accounting
|
||||
# precision, inconsistencies between the stock valuation and the accounting entries
|
||||
# may arise.
|
||||
# For example, a box of 13 units is bought 15.00. If the products leave the
|
||||
# stock one unit at a time, the amount related to the cost will correspond to
|
||||
# round(15/13, 2)*13 = 14.95. To avoid this case, we split the quant in 12 + 1, then
|
||||
# record the difference on the new quant.
|
||||
# We need to make sure to able to extract at least one unit of the product. There is
|
||||
# an arbitrary minimum quantity set to 2.0 from which we consider we can extract a
|
||||
# unit and adapt the cost.
|
||||
curr_rounding = move.company_id.currency_id.rounding
|
||||
cost_rounded = float_round(quant.cost, precision_rounding=curr_rounding)
|
||||
cost_correct = cost_rounded
|
||||
if float_compare(quant.product_id.uom_id.rounding, 1.0, precision_digits=1) == 0\
|
||||
and float_compare(quant.qty * quant.cost, quant.qty * cost_rounded, precision_rounding=curr_rounding) != 0\
|
||||
and float_compare(quant.qty, 2.0, precision_rounding=quant.product_id.uom_id.rounding) >= 0:
|
||||
qty = quant.qty
|
||||
cost = quant.cost
|
||||
quant_correct = quant_obj._quant_split(cr, uid, quant, quant.qty - 1.0, context=context)
|
||||
cost_correct += (qty * cost) - (qty * cost_rounded)
|
||||
quant_obj.write(cr, SUPERUSER_ID, [quant.id], {'cost': cost_rounded}, context=context)
|
||||
quant_obj.write(cr, SUPERUSER_ID, [quant_correct.id], {'cost': cost_correct}, context=context)
|
||||
return quant
|
||||
|
||||
def move_quants_write(self, cr, uid, quants, move, location_dest_id, dest_package_id, context=None):
|
||||
|
|
Loading…
Reference in New Issue