[IMP] Turn qty_remaining into a calculated field
bzr revid: jco@openerp.com-20130521172627-bgbaj398y5bsg5jo
This commit is contained in:
@@ -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
|
||||
-
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user