[IMP] Turn qty_remaining into a calculated field

bzr revid: jco@openerp.com-20130521172627-bgbaj398y5bsg5jo
This commit is contained in:
Josse Colpaert
2013-05-21 19:26:27 +02:00
parent 163730bc31
commit 9c224029fd
3 changed files with 100 additions and 22 deletions
+32 -2
View File
@@ -322,7 +322,7 @@
for move in self.pool.get("stock.move").browse(cr, uid, list):
print move.price_unit, move.product_qty, move.qty_remaining, move.type, move.date
-
Receive purchase order with 200 kgm FIFO Ice Cream I create a draft Purchase Order for second shipment for 30 kg at 80 euro
Receive purchase order with 100 kgm FIFO Ice Cream at 50 euro/kg
-
!record {model: purchase.order, id: purchase_order_fifo_neg}:
partner_id: base.res_partner_3
@@ -330,7 +330,7 @@
pricelist_id: 1
order_line:
- product_id: product_fifo_icecream
product_qty: 200.0
product_qty: 100.0
product_uom: product.product_uom_categ_kgm
price_unit: 50.0
name: 'FIFO Ice Cream'
@@ -345,6 +345,36 @@
pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg")).picking_ids
partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
self.do_partial(cr, uid, [partial_id])
-
Assert price on product is 50
-
!python {model: product.product}: |
assert self.browse(cr, uid, ref("product_fifo_icecream")).standard_price == 50.0
-
Receive purchase order with 100 kgm FIFO Ice Cream at 80 euro/kg
-
!record {model: purchase.order, id: purchase_order_fifo_neg2}:
partner_id: base.res_partner_3
location_id: stock.stock_location_stock
pricelist_id: 1
order_line:
- product_id: product_fifo_icecream
product_qty: 100.0
product_uom: product.product_uom_categ_kgm
price_unit: 80
name: 'FIFO Ice Cream'
-
I confirm the second negative purchase order
-
!workflow {model: purchase.order, action: purchase_confirm, ref: purchase_order_fifo_neg2}
-
Process the reception of purchase order 2
-
!python {model: stock.partial.picking}: |
pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo_neg2")).picking_ids
partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]})
self.do_partial(cr, uid, [partial_id])
-
Print price
-
+2 -6
View File
@@ -2714,14 +2714,11 @@ class stock_move(osv.osv):
match_id = matching_obj.create(cr, uid, matchvals, context=context)
res[move.id].append(match_id)
move_in = self.browse(cr, uid, match[0], context=context)
#Reduce remaining quantity
self.write(cr, uid, match[0], { 'qty_remaining': move_in.qty_remaining - match[3]}, context=context)
price_amount += match[1] * match[2]
amount += match[1]
#Write price on out move
if product.qty_available >= product_uom_qty and product.cost_method in ['fifo', 'lifo']:
self.write(cr, uid, move.id, {'price_unit': price_amount / amount,
'qty_remaining': move.qty_remaining - amount}, context=context)
self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context)
product_obj.write(cr, uid, product.id, {'standard_price': price_amount / product_uom_qty}, context=ctx)
else:
new_price = uom_obj._compute_price(cr, uid, product.uom_id.id, product.standard_price,
@@ -2774,8 +2771,7 @@ class stock_move(osv.osv):
for match in matching_obj.browse(cr, uid, matches, context=context):
in_mov = self.browse(cr, uid, match.move_in_id.id, context=context)
amount += uom_obj._compute_qty(cr, uid, in_mov.product_uom.id, in_mov.product_qty, out_mov.product_uom.id)
total_price += amount * uom_obj._compute_price(cr, uid, in_mov.product_uom.id, in_mov.price_unit,
out_mov.product_uom.id)
total_price += amount * uom_obj._compute_price(cr, uid, in_mov.product_uom.id, in_mov.price_unit, out_mov.product_uom.id)
if amount > 0.0:
self.write(cr, uid, [out_mov.id], {'price_unit': total_price / amount}, context=context)
product_obj.write(cr, uid, [product.id], {'standard_price': total_price / amount}, context=ctx)
+66 -14
View File
@@ -89,23 +89,75 @@ class product_product (osv.osv):
return tuples
class stock_move(osv.osv):
def _get_moves(self, cr, uid, ids, context=None):
res = []
#search_dom = ['|', '&', ('location_id.usage','=', 'internal'), ('location_dest_id.usage','!=', 'internal'), '&', ('location_id.usage', '=')]
#res_ids = self.search(cr, uid, [], context=context)
for move in self.browse(cr, uid, ids, context=context):
move_inorout = move.location_id and move.location_dest_id
move_inorout = move_inorout and ((move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal') or (move.location_id.usage != 'internal' and move.location_dest_id.usage == 'internal' ))
if move_inorout:
res.append(move.id)
return res
def _get_moves_from_matchings(self, cr, uid, ids, context=None):
match_obj = self.pool.get("stock.move.matching")
res = {}
for match in match_obj.browse(cr, uid, ids, context=context):
if match.move_out_id.id not in res:
res[match.move_out_id.id] = True
if match.move_in_id.id not in res:
res[match.move_in_id.id] = True
return res.keys()
def _get_qty_remaining (self, cr, uid, ids, field_names, arg, context=None):
'''
This function calculates how much of the stock move that still needs to be matched
'''
match_obj = self.pool.get("stock.move.matching")
uom_obj = self.pool.get("product.uom")
res = {}
for move in self.browse(cr, uid, ids, context=context):
move_out = move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal'
move_in = move.location_id.usage != 'internal' and move.location_dest_id.usage == 'internal'
if move_in:
#Search all matchings
matches = match_obj.search(cr, uid, [('move_in_id', '=', move.id)], context=context)
qty = move.product_qty
for match in match_obj.browse(cr, uid, matches, context=context):
qty -= uom_obj._compute_qty(cr, uid, match.move_out_id.product_uom.id, match.qty, move.product_uom.id)
res[move.id] = qty
elif move_out:
#Search all matchings, but from the other side
matches = match_obj.search(cr, uid, [('move_out_id', '=', move.id)], context=context)
qty = move.product_qty
for match in match_obj.browse(cr, uid, matches, context=context):
qty -= match.qty
res[move.id] = qty
return res
_inherit = 'stock.move'
_columns = {'qty_remaining': fields.float("Remaining Qty"),
_columns = {'qty_remaining': fields.function(_get_qty_remaining, type="float", string="Remaining quantity to be matched",
store = {'stock.move.matching': (_get_moves_from_matchings, ['qty', 'move_in_id', 'move_out_id'], 10),
'stock.move': (_get_moves, ['product_qty', 'product_uom', 'location_id', 'location_dest_id', 'company_id'], 10)}), #locations and company_id not necessary?
'matching_ids_in': fields.one2many('stock.move.matching', 'move_in_id'),
'matching_ids_out':fields.one2many('stock.move.matching', 'move_out_id'),
}
def create(self, cr, uid, vals, context=None):
if 'product_qty' in vals:
vals['qty_remaining'] = vals['product_qty']
res = super(stock_move, self).create(cr, uid, vals, context=context)
return res
def write(self, cr, uid, ids, vals, context=None):
if 'product_qty' in vals:
vals['qty_remaining'] = vals['product_qty']
res = super(stock_move, self).write(cr, uid, ids, vals, context=context)
return res
# def create(self, cr, uid, vals, context=None):
# if 'product_qty' in vals:
# vals['qty_remaining'] = vals['product_qty']
# res = super(stock_move, self).create(cr, uid, vals, context=context)
# return res
#
# def write(self, cr, uid, ids, vals, context=None):
# if 'product_qty' in vals:
# vals['qty_remaining'] = vals['product_qty']
# res = super(stock_move, self).write(cr, uid, ids, vals, context=context)
# return res
class stock_move_matching(osv.osv):
@@ -114,8 +166,8 @@ class stock_move_matching(osv.osv):
_columns = {
'move_in_id': fields.many2one('stock.move', 'Stock move in', required=True),
'move_out_id': fields.many2one('stock.move', 'Stock move out', required=True),
'qty': fields.float('Quantity', required=True),
'qty': fields.float('Quantity in UoM of out', required=True),
'price_unit':fields.related('move_in_id', 'price_unit', string="Unit price", type="float"),
'price_unit_out': fields.float('Unit price out')
'price_unit_out': fields.float('Unit price out'),
}