[FIX] sale, project_mrp, sale_stock: fixed problems related to the procurement workflow

bzr revid: qdp-launchpad@openerp.com-20130917064359-jwque36uwouac61p
This commit is contained in:
Quentin (OpenERP) 2013-09-17 08:43:59 +02:00
parent 4e25eccad5
commit e12c9ab5ec
5 changed files with 60 additions and 67 deletions

View File

@ -20,7 +20,6 @@
##############################################################################
from openerp.osv import fields, osv
from openerp import netsvc
from openerp.tools.translate import _
class procurement_order(osv.osv):
@ -49,8 +48,8 @@ class procurement_order(osv.osv):
return super(procurement_order, self)._run(cr, uid, procurement, context=context)
def _check(self, cr, uid, procurement, context=None):
if self._is_procurement_task(cr, uid, procurement, context=context) and procurement.task_id and procurement.task_id.stage_id.closed:
return True
if self._is_procurement_task(cr, uid, procurement, context=context):
return procurement.task_id and procurement.task_id.stage_id.closed or False
return super(procurement_order, self)._check(cr, uid, procurement, context=context)
def _convert_qty_company_hours(self, cr, uid, procurement, context=None):
@ -149,25 +148,20 @@ class product_product(osv.osv):
}
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
def need_procurement(self, cr, uid, ids, context=None):
#when sale is installed alone, there is no need to create procurements, but with project_mrp
#we must create a procurement for each service that has the auto_create_task boolean set to True.
for line in self.browse(cr, uid, ids, context=context):
if line.product_id and line.product_id.type == 'service' and line.product_id.auto_create_task:
return True
return super(sale_order_line, self).need_procurement(cr, uid, ids, context=context)
class sale_order(osv.osv):
_inherit = 'sale.order'
def _can_create_procurement(self, cr, uid, ids, context=None):
return True
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
proc_data = super(sale_order, self)._prepare_order_line_procurement(cr,
uid, order, line, group_id = group_id, context=context)
if not(line.product_id.type== "service" and not line.product_id.auto_create_task):
proc_data['sale_line_id'] = line.id
return proc_data
def _check_create_procurement(self, cr, uid, order, line, context=None):
create = super(sale_order, self)._check_create_procurement(cr, uid, order, line, context=context)
if (line.product_id.type== "service" and not line.product_id.auto_create_task):
create = False
return create
def _picked_rate(self, cr, uid, ids, name, arg, context=None):
if not ids:
return {}

View File

@ -622,6 +622,8 @@ class sale_order(osv.osv):
}
def action_done(self, cr, uid, ids, context=None):
for order in self.browse(cr, uid, ids, context=context):
self.pool.get('sale.order.line').write(cr, uid, [line.id for line in order.order_line], {'state': 'done'}, context=context)
return self.write(cr, uid, ids, {'state': 'done'}, context=context)
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
@ -646,15 +648,16 @@ class sale_order(osv.osv):
return date_planned
def _prepare_procurement_group(self, cr, uid, order, context=None):
return {
'name': order.name, 'partner_id': order.partner_shipping_id.id,
}
return {'name': order.name, 'partner_id': order.partner_shipping_id.id}
def _check_create_procurement(self, cr, uid, order, line, context=None):
return True
def _can_create_procurement(self, cr, uid, ids, context=None):
return False
def procurement_needed(self, cr, uid, ids, context=None):
#when sale is installed only, there is no need to create procurements, that's only
#further installed modules (project_mrp, sale_stock) that will change this.
sale_line_obj = self.pool.get('sale.order.line')
res = []
for order in self.browse(cr, uid, ids, context=context):
res.append(sale_line_obj.need_procurement(cr, uid, [line.id for line in order.order_line], context=context))
return any(res)
def action_ship_create(self, cr, uid, ids, context=None):
"""Create the required procurements to supply sales order lines, also connecting
@ -668,21 +671,23 @@ class sale_order(osv.osv):
:return: True
"""
procurement_obj = self.pool.get('procurement.order')
sale_line_obj = self.pool.get('sale.order.line')
for order in self.browse(cr, uid, ids, context=context):
proc_ids = []
vals = self._prepare_procurement_group(cr, uid, order, context=context)
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
order.write({'procurement_group_id': group_id}, context=context)
for line in order.order_line:
if (line.state == 'done') or not line.product_id:
continue
if self._can_create_procurement(cr, uid, ids, context=context) and self._check_create_procurement(cr, uid, order, line, context=context):
if sale_line_obj.need_procurement(cr, uid, [line.id], context=context):
if (line.state == 'done') or not line.product_id:
continue
vals = self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
proc_id = procurement_obj.create(cr, uid, vals, context=context)
proc_ids.append(proc_id)
#Confirm procurement order such that rules will be applied on it
procurement_obj.run(cr, uid, proc_ids, context=context)
#Confirm procurement order such that rules will be applied on it
#note that the workflow ensure proc_ids isn't an empty list
procurement_obj.run(cr, uid, proc_ids, context=context)
# FP NOTE: do we need this? isn't it the workflow that should set this
val = {}
if order.state == 'shipping_except':
@ -697,14 +702,6 @@ class sale_order(osv.osv):
order.write(val)
return True
def action_ship_end(self, cr, uid, ids, context=None):
for order in self.browse(cr, uid, ids, context=context):
for line in order.order_line:
if line.state == 'exception':
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'state': 'done'}, context=context)
# if mode == 'finished':
# returns True if all lines are done, False otherwise
# if mode == 'canceled':
@ -715,18 +712,12 @@ class sale_order(osv.osv):
canceled = False
write_done_ids = []
write_cancel_ids = []
if not self._can_create_procurement(cr, uid, ids, context={}):
for order in self.browse(cr, uid, ids, context={}):
for line in order.order_line:
write_done_ids.append(line.id)
self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'})
return True
for order in self.browse(cr, uid, ids, context={}):
#TODO: Need to rethink what happens when cancelling
for line in order.order_line:
states = [x.state for x in line.procurement_ids]
cancel = all([x == 'cancel' for x in states])
cancel = states and all([x == 'cancel' for x in states])
doneorcancel = all([x in ('done', 'cancel') for x in states])
if cancel:
canceled = True
@ -764,6 +755,11 @@ class sale_order(osv.osv):
# - use it in report if there is a uos
class sale_order_line(osv.osv):
def need_procurement(self, cr, uid, ids, context=None):
#when sale is installed only, there is no need to create procurements, that's only
#further installed modules (project_mrp, sale_stock) that will change this.
return False
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
tax_obj = self.pool.get('account.tax')
cur_obj = self.pool.get('res.currency')
@ -1145,4 +1141,4 @@ class procurement_order(osv.osv):
_columns = {
'sale_line_id': fields.many2one('sale.order.line', string='Sale Order Line'),
}

View File

@ -191,8 +191,7 @@
<record id="act_ship_end" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship_end</field>
<field name="kind">function</field>
<field name="action">action_ship_end()</field>
<field name="kind">dummy</field>
</record>
<record id="act_ship_cancel" model="workflow.activity">
@ -240,7 +239,12 @@
<record id="trans_wait_ship_ship" model="workflow.transition">
<field name="act_from" ref="act_wait_ship"/>
<field name="act_to" ref="act_ship"/>
<field name="condition">(order_policy!='prepaid') or invoiced</field>
<field name="condition">procurement_needed() and ((order_policy!='prepaid') or invoiced)</field>
</record>
<record id="trans_wait_ship_done" model="workflow.transition">
<field name="act_from" ref="act_wait_ship"/>
<field name="act_to" ref="act_ship_end"/>
<field name="condition">not procurement_needed()</field>
</record>
<record id="trans_ship_end_done" model="workflow.transition">

View File

@ -31,9 +31,6 @@ from openerp import SUPERUSER_ID
class sale_order(osv.osv):
_inherit = "sale.order"
def _can_create_procurement(self, cr, uid, ids, context=None):
return True
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
@ -203,8 +200,6 @@ class sale_order(osv.osv):
self.write(cr, uid, [o.id], {'order_policy': 'manual'}, context=context)
return res
def _get_date_planned(self, cr, uid, order, line, start_date, context=None):
date_planned = super(sale_order, self)._get_date_planned(cr, uid, order, line, start_date, context=context)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
@ -240,10 +235,17 @@ class sale_order(osv.osv):
return False
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
def need_procurement(self, cr, uid, ids, context=None):
#when sale is installed alone, there is no need to create procurements, but with sale_stock
#we must create a procurement for each product that is not a service.
for line in self.browse(cr, uid, ids, context=context):
if line.product_id and line.product_id.type != 'service':
return True
return super(sale_order_line, self).need_procurement(cr, uid, ids, context=context)
def _number_packages(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for line in self.browse(cr, uid, ids, context=context):
@ -262,7 +264,6 @@ class sale_order_line(osv.osv):
'product_packaging': False,
}
def button_cancel(self, cr, uid, ids, context=None):
res = super(sale_order_line, self).button_cancel(cr, uid, ids, context=context)
for line in self.browse(cr, uid, ids, context=context):
@ -407,4 +408,4 @@ class stock_move(osv.osv):
res['account_analytic_id'] = sale_line.order_id.project_id and sale_line.order_id.project_id.id or False
res['price_unit'] = sale_line.price_unit
res['discount'] = sale_line.discount
return res
return res

View File

@ -64,9 +64,7 @@
Check one quant was created in Customers location with 200 pieces and one move in the history_ids
-
!python {model: stock.quant}: |
quant_id = self.search(cr, uid, [('product_id', '=', ref("drop_shop_product"))])
print quant_id, [(x.qty, x.product_id.name) for x in self.browse(cr, uid, quant_id)]
quant_id = self.search(cr, uid, [('location_id', '=', ref('stock.stock_location_customers')),('qty', '=', 200), ('product_id', '=', ref("drop_shop_product"))])
print quant_id, [(x.qty, x.product_id.name) for x in self.browse(cr, uid, quant_id)]
assert len(self.browse(cr, uid, quant_id)[0].history_ids) == 1
assert len(quant_id) == 1
quant_ids = self.search(cr, uid, [('location_id', '=', ref('stock.stock_location_customers')),('qty', '=', 200), ('product_id', '=', ref("drop_shop_product"))])
assert quant_ids, 'No Quant found'
assert len(quant_ids) == 1
assert len(self.browse(cr, uid, quant_ids)[0].history_ids) == 1