[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:
parent
4e25eccad5
commit
e12c9ab5ec
|
@ -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 {}
|
||||
|
|
|
@ -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'),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue