[REF] mrp, stock: refactoring made during code review
bzr revid: qdp-launchpad@openerp.com-20140205104324-5h5hu0fv71omhigf
This commit is contained in:
parent
2c101e9432
commit
0afb7076d4
|
@ -772,6 +772,8 @@ class mrp_production(osv.osv):
|
|||
return 1
|
||||
|
||||
def _get_produced_qty(self, cr, uid, production, context=None):
|
||||
''' returns the produced quantity of product 'production.product_id' for the given production, in the product UoM
|
||||
'''
|
||||
produced_qty = 0
|
||||
for produced_product in production.move_created_ids2:
|
||||
if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id):
|
||||
|
@ -780,6 +782,8 @@ class mrp_production(osv.osv):
|
|||
return produced_qty
|
||||
|
||||
def _get_consumed_data(self, cr, uid, production, context=None):
|
||||
''' returns a dictionary containing for each raw material of the given production, its quantity already consumed (in the raw material UoM)
|
||||
'''
|
||||
consumed_data = {}
|
||||
# Calculate already consumed qtys
|
||||
for consumed in production.move_lines2:
|
||||
|
@ -790,71 +794,68 @@ class mrp_production(osv.osv):
|
|||
consumed_data[consumed.product_id.id] += consumed.product_qty
|
||||
return consumed_data
|
||||
|
||||
def _calculate_qty(self, cr, uid, production, product_qty = 0.0, context=None):
|
||||
def _calculate_qty(self, cr, uid, production, product_qty=0.0, context=None):
|
||||
"""
|
||||
Calculates the quantity still needed to produce an extra number of products
|
||||
"""
|
||||
quant_obj = self.pool.get("stock.quant")
|
||||
#In case no product qty is given, take product qty of
|
||||
if product_qty == 0.0:
|
||||
done = 0.0
|
||||
for move in production.move_created_ids2:
|
||||
if move.product_id == production.product_id:
|
||||
if not move.scrapped:
|
||||
done += move.product_qty
|
||||
product_qty = production.product_qty - done
|
||||
|
||||
produced_qty = self._get_produced_qty(cr, uid, production, context=context)
|
||||
consumed_data = self._get_consumed_data(cr, uid, production, context=context)
|
||||
|
||||
#In case no product_qty is given, take the remaining qty to produce for the given production
|
||||
if not product_qty:
|
||||
product_qty = production.product_qty - produced_qty
|
||||
|
||||
dicts = {}
|
||||
# Find product qty to be consumed and consume it
|
||||
for scheduled in production.product_lines:
|
||||
if not dicts.get(scheduled.product_id.id):
|
||||
dicts[scheduled.product_id.id] = {}
|
||||
# total qty of consumed product we need after this consumption
|
||||
total_consume = ((product_qty + produced_qty) * scheduled.product_qty / production.product_qty)
|
||||
|
||||
consumed_qty = consumed_data.get(scheduled.product_id.id, 0.0)
|
||||
# qty available for consume and produce
|
||||
qty_avail = scheduled.product_qty - consumed_data.get(scheduled.product_id.id, 0.0)
|
||||
|
||||
qty_avail = scheduled.product_qty - consumed_qty
|
||||
if qty_avail <= 0.0:
|
||||
# there will be nothing to consume for this raw material
|
||||
continue
|
||||
|
||||
qty = total_consume - consumed_data.get(scheduled.product_id.id, 0.0)
|
||||
|
||||
if not dicts.get(scheduled.product_id.id):
|
||||
dicts[scheduled.product_id.id] = {}
|
||||
|
||||
# total qty of consumed product we need after this consumption
|
||||
total_consume = ((product_qty + produced_qty) * scheduled.product_qty / production.product_qty)
|
||||
qty = total_consume - consumed_qty
|
||||
|
||||
# Search for quants related to this related move
|
||||
move = [x for x in production.move_lines if x.product_id.id == scheduled.product_id.id]
|
||||
#TODO: check if not already in dict_new
|
||||
if move:
|
||||
for move in production.move_lines:
|
||||
if qty <= 0.0:
|
||||
break
|
||||
if move.product_id.id != scheduled.product_id.id:
|
||||
continue
|
||||
product_id = scheduled.product_id.id
|
||||
move = move[0]
|
||||
quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, scheduled.product_id, qty, domain=[('qty', '>', 0.0)],
|
||||
|
||||
q = min(move.product_qty, qty)
|
||||
quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, scheduled.product_id, q, domain=[('qty', '>', 0.0)],
|
||||
prefered_domain=[('reservation_id', '=', move.id)], fallback_domain=[('reservation_id', '=', False)], context=context)
|
||||
for quant in quants:
|
||||
if quant[0]:
|
||||
lot_id = quant[0].lot_id.id
|
||||
prod_qty = quant[1]
|
||||
for quant, quant_qty in quants:
|
||||
if quant:
|
||||
lot_id = quant.lot_id.id
|
||||
if not product_id in dicts.keys():
|
||||
dicts[product_id] = {lot_id : prod_qty}
|
||||
dicts[product_id] = {lot_id : quant_qty}
|
||||
elif lot_id in dicts[product_id].keys():
|
||||
dicts[product_id][lot_id] += prod_qty
|
||||
dicts[product_id][lot_id] += quant_qty
|
||||
else:
|
||||
dicts[product_id][lot_id] = prod_qty
|
||||
qty -= quant[1]
|
||||
if qty > 0:
|
||||
if dicts[product_id].get(False):
|
||||
dicts[product_id][False] += qty
|
||||
else:
|
||||
dicts[product_id][False] = qty
|
||||
dicts[product_id][lot_id] = quant_qty
|
||||
qty -= quant_qty
|
||||
if qty > 0:
|
||||
if dicts[product_id].get(False):
|
||||
dicts[product_id][False] += qty
|
||||
else:
|
||||
dicts[product_id][False] = qty
|
||||
|
||||
consume_lines = []
|
||||
for prod in dicts.keys():
|
||||
for lot in dicts[prod].keys():
|
||||
consume_lines.append({'product_id': prod, 'product_qty':dicts[prod][lot], 'lot_id': lot})
|
||||
for lot, qty in dicts[prod].items():
|
||||
consume_lines.append({'product_id': prod, 'product_qty': qty, 'lot_id': lot})
|
||||
return consume_lines
|
||||
|
||||
|
||||
|
||||
def action_produce(self, cr, uid, production_id, production_qty, production_mode, wiz=False, context=None):
|
||||
""" To produce final product based on production mode (consume/consume&produce).
|
||||
If Production mode is consume, all stock move lines of raw materials will be done/consumed.
|
||||
|
@ -863,11 +864,9 @@ class mrp_production(osv.osv):
|
|||
@param production_id: the ID of mrp.production object
|
||||
@param production_qty: specify qty to produce
|
||||
@param production_mode: specify production mode (consume/consume&produce).
|
||||
@param wizard: the mrp produce product wizard, which will tell the amount of consumed products needed
|
||||
@param wiz: the mrp produce product wizard, which will tell the amount of consumed products needed
|
||||
@return: True
|
||||
"""
|
||||
|
||||
|
||||
stock_mov_obj = self.pool.get('stock.move')
|
||||
production = self.browse(cr, uid, production_id, context=context)
|
||||
if not production.move_lines and production.state == 'ready':
|
||||
|
@ -902,36 +901,33 @@ class mrp_production(osv.osv):
|
|||
lot_id = False
|
||||
if wiz:
|
||||
lot_id = wiz.lot_id.id
|
||||
new_moves = stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), location_id = produce_product.location_id.id, restrict_lot_id = lot_id, context=context)
|
||||
new_moves = stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), location_id=produce_product.location_id.id, restrict_lot_id=lot_id, context=context)
|
||||
if produce_product.product_id.id == production.product_id.id and new_moves:
|
||||
main_production_move = new_moves[0]
|
||||
|
||||
if production_mode in ['consume','consume_produce']:
|
||||
consume_lines = []
|
||||
if wiz:
|
||||
consume_lines = []
|
||||
for cons in wiz.consume_lines:
|
||||
consume_lines.append({'product_id': cons.product_id.id, 'lot_id': cons.lot_id.id, 'product_qty': cons.product_qty})
|
||||
else:
|
||||
consume_lines = self._calculate_qty(cr, uid, production, production_qty, context=context)
|
||||
for consume in consume_lines:
|
||||
# Search move for the product
|
||||
corresponding_move = [x for x in production.move_lines if x.product_id.id == consume['product_id']]
|
||||
if corresponding_move:
|
||||
corresponding_move = corresponding_move[0]
|
||||
default_values = {}
|
||||
if corresponding_move.product_qty > consume['product_qty']:
|
||||
stock_mov_obj.action_consume(cr, uid, [corresponding_move.id], consume['product_qty'], corresponding_move.location_id.id,
|
||||
restrict_lot_id = consume['lot_id'], consumed_for = main_production_move, context=context)
|
||||
else:
|
||||
stock_mov_obj.action_consume(cr, uid, [corresponding_move.id], corresponding_move.product_qty, corresponding_move.location_id.id,
|
||||
restrict_lot_id = consume['lot_id'], consumed_for = main_production_move, context=context)
|
||||
remaining_qty = consume['product_qty']
|
||||
for raw_material_line in production.move_lines:
|
||||
if remaining_qty <= 0:
|
||||
break
|
||||
if consume[product_id] != raw_material.product_id.id:
|
||||
continue
|
||||
consumed_qty = min(remaining_qty, raw_material_line.product_qty)
|
||||
stock_mov_obj.action_consume(cr, uid, [corresponding_move.id], consumed_qty, corresponding_move.location_id.id,
|
||||
restrict_lot_id=consume['lot_id'], consumed_for=main_production_move, context=context)
|
||||
remaining_qty -= consumed_qty
|
||||
|
||||
self.message_post(cr, uid, production_id, body=_("%s produced") % self._description, context=context)
|
||||
self.signal_button_produce_done(cr, uid, [production_id])
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def _costs_generate(self, cr, uid, production):
|
||||
""" Calculates total costs at the end of the production.
|
||||
@param production: Id of production order.
|
||||
|
|
|
@ -113,6 +113,8 @@ class StockMove(osv.osv):
|
|||
@param consumed_for: optionnal parameter given to this function to make the link between raw material consumed and produced product, for a better traceability
|
||||
@return: Consumed lines
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
res = []
|
||||
production_obj = self.pool.get('mrp.production')
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
attrs="{'required': [('track_production', '=', True), ('mode', '=', 'consume_produce')]}"
|
||||
groups="stock.group_tracking_lot"/>
|
||||
</group>
|
||||
<separator/>
|
||||
<group string="To Consume">
|
||||
<field name="consume_lines">
|
||||
<tree string="Consume Lines" editable="top">
|
||||
|
|
|
@ -285,17 +285,17 @@ class stock_quant(osv.osv):
|
|||
|
||||
def quants_reserve(self, cr, uid, quants, move, link=False, context=None):
|
||||
'''This function reserves quants for the given move (and optionally given link). If the total of quantity reserved is enough, the move's state
|
||||
is also set to 'assigned' Please do not pass negative quants.
|
||||
is also set to 'assigned'
|
||||
|
||||
:param quants: list of tuple(quant browse record or None, qty to reserve). If None is given as first tuple element, the item will be ignored
|
||||
:param quants: list of tuple(quant browse record or None, qty to reserve). If None is given as first tuple element, the item will be ignored. Negative quants should not be received as argument
|
||||
:param move: browse record
|
||||
:param link: browse record (stock.move.operation.link)
|
||||
'''
|
||||
toreserve = []
|
||||
#split quants if needed
|
||||
for quant, qty in quants:
|
||||
if qty < 0.0:
|
||||
raise osv.except_osv(_('Error!'), _('You can not reserve negative quants. '))
|
||||
if qty <= 0.0 or quant.qty <= 0.0:
|
||||
raise osv.except_osv(_('Error!'), _('You can not reserve a negative quantity or a negative quant.'))
|
||||
if not quant:
|
||||
continue
|
||||
self._quant_split(cr, uid, quant, qty, context=context)
|
||||
|
@ -1997,7 +1997,6 @@ class stock_move(osv.osv):
|
|||
return new_move
|
||||
|
||||
|
||||
|
||||
class stock_inventory(osv.osv):
|
||||
_name = "stock.inventory"
|
||||
_description = "Inventory"
|
||||
|
|
Loading…
Reference in New Issue