[IMP] Move sale_stock_workflow towards sale_workflow and make sure project_mrp tests pass

bzr revid: jco@openerp.com-20130910154822-u2if98d4r32rtibi
This commit is contained in:
Josse Colpaert 2013-09-10 17:48:22 +02:00
parent 83f30b55dc
commit d207edc369
16 changed files with 278 additions and 212 deletions

View File

@ -32,7 +32,7 @@ This application supports complete integration and production scheduling for sto
-->
<record id="route_warehouse0_manufacture" model='stock.location.route'>
<field name="name">Manufacture</field>
<field name="name">Your Company Manufacture</field>
<field name="sequence">5</field>
</record>

View File

@ -49,7 +49,7 @@ 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.state == 'done':
if self._is_procurement_task(cr, uid, procurement, context=context) and procurement.task_id and procurement.task_id.stage_id.closed:
return True
return super(procurement_order, self)._check(cr, uid, procurement, context=context)
@ -70,6 +70,35 @@ class procurement_order(osv.osv):
account = procurement.sale_line_id.order_id.project_id
project_ids = project_project.search(cr, uid, [('analytic_account_id', '=', account.id)])
projects = project_project.browse(cr, uid, project_ids, context=context)
project = projects and projects[0] or False
return project
def _create_service_task(self, cr, uid, procurement, context=None):
project_task = self.pool.get('project.task')
project = self._get_project(cr, uid, procurement, context=context)
planned_hours = self._convert_qty_company_hours(cr, uid, procurement, context=context)
task_id = project_task.create(cr, uid, {
'name': '%s:%s' % (procurement.origin or '', procurement.product_id.name),
'date_deadline': procurement.date_planned,
'planned_hours': planned_hours,
'remaining_hours': planned_hours,
'partner_id': procurement.sale_line_id and procurement.sale_line_id.order_id.partner_id.id or False,
'user_id': procurement.product_id.product_manager.id,
'procurement_id': procurement.id,
'description': procurement.name + '\n',
'project_id': project and project.id or False,
'company_id': procurement.company_id.id,
},context=context)
self.write(cr, uid, [procurement.id], {'task_id': task_id, 'message':_('Task created.')}, context=context)
self.project_task_create_note(cr, uid, [procurement.id], context=context)
return task_id
def project_task_create_note(self, cr, uid, ids, context=None):
for procurement in self.browse(cr, uid, ids, context=context):
body = _("Task created")
self.message_post(cr, uid, [procurement.id], body=body, context=context)
if procurement.sale_line_id and procurement.sale_line_id.order_id:
procurement.sale_line_id.order_id.message_post(body=body)
@ -98,10 +127,10 @@ class project_task(osv.osv):
}
def _validate_subflows(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
for task in self.browse(cr, uid, ids):
proc_obj = self.pool.get("procurement.order")
for task in self.browse(cr, uid, ids, context=context):
if task.procurement_id:
wf_service.trg_write(uid, 'procurement.order', task.procurement_id.id, cr)
proc_obj.check(cr, uid, [task.procurement_id.id], context=context)
def write(self, cr, uid, ids, values, context=None):
""" When closing tasks, validate subflows. """
@ -124,9 +153,12 @@ class sale_order(osv.osv):
_inherit = 'sale.order'
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,
if not(line.product_id.type== "service" and not line.product_id.auto_create_task):
proc_data = super(sale_order, self)._prepare_order_line_procurement(cr,
uid, order, line, group_id = group_id, context=context)
proc_data['sale_line_id'] = line.id
proc_data['sale_line_id'] = line.id
else:
proc_data = False
return proc_data
def _picked_rate(self, cr, uid, ids, name, arg, context=None):

View File

@ -10,7 +10,6 @@
<field name="product_uom" ref="product.product_uom_day"/>
<field name="price_unit">150.0</field>
<field name="product_uom_qty">5.0</field>
<field name="type">make_to_order</field>
</record>
<record id="project.project_tt_deployment" model="project.task.type">

View File

@ -14,11 +14,14 @@
<record id="view_product_task_form" model="ir.ui.view">
<field name="name">product.form.view.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.view_normal_procurement_locations_form"/>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="project_id" attrs="{'invisible':[('type','!=','service')]}" />
</field>
<field name="standard_price" position="after">
<field name="auto_create_task"/>
</field>
</field>
</record>
<record id="task_type_edit_mrp_inherit" model="ir.ui.view">

View File

@ -1,18 +1,43 @@
-
Update product to automatically create tasks
-
!record {model: product.product, id: auto_task_service}:
auto_create_task: True
name: Advanced auto task Service
type: service
list_price: 150.0
standard_price: 100.0
uom_id: product.product_uom_day
uom_po_id: product.product_uom_day
-
Create a new sales order with a service product
-
!record {model: sale.order, id: sale_order_service}:
partner_id: base.res_partner_2
pricelist_id: product.list0
-
Associate a sale order line
-
!record {model: sale.order.line, id: service_line}:
product_id: auto_task_service
product_uom_qty: 50.0
name: Fixing the bugs
order_id: sale_order_service
-
In order to test process to generate task automatic from procurement, I confirm sale order to sale service product.
-
!workflow {model: sale.order, action: order_confirm, ref: sale.sale_order_3}
!workflow {model: sale.order, action: order_confirm, ref: sale_order_service}
-
I run the scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
Now I check that task details after run procurement
Now I check the details of the generated task
-
!python {model: procurement.order}: |
from datetime import datetime
procurement_ids = self.search(cr, uid, [('sale_line_id', '=', ref('line_services'))])
procurement_ids = self.search(cr, uid, [('sale_line_id', '=', ref('service_line'))])
assert procurement_ids, "Procurement is not generated for Service Order Line."
procurement = self.browse(cr, uid, procurement_ids[0], context=context)
assert procurement.state != 'done' , "Procurement should not be closed."
@ -34,14 +59,14 @@
I close that task.
-
!python {model: project.task}: |
task_ids = self.search(cr, uid, [('sale_line_id', '=', ref('line_services'))])
task_ids = self.search(cr, uid, [('sale_line_id', '=', ref('service_line'))])
assert task_ids, "Task is not generated for Service Order Line."
self.write(cr, uid, task_ids, {'stage_id': ref('project.project_tt_deployment')}, context=context)
-
I check procurement of Service Order Line after closed task.
-
!python {model: procurement.order}: |
procurement_ids = self.search(cr, uid, [('sale_line_id', '=', ref('line_services'))])
procurement_ids = self.search(cr, uid, [('sale_line_id', '=', ref('service_line'))])
assert procurement_ids, "Procurement is not generated for Service Order Line."
procurement = self.browse(cr, uid, procurement_ids[0], context=context)
assert procurement.state == 'done' , "Procurement should be closed."

View File

@ -152,7 +152,7 @@ class purchase_order(osv.osv):
def _get_picking_in(self, cr, uid, context=None):
obj_data = self.pool.get('ir.model.data')
return obj_data.get_object_reference(cr, uid, 'stock','picking_type_in')[1]
return obj_data.get_object_reference(cr, uid, 'stock','picking_type_in') and obj_data.get_object_reference(cr, uid, 'stock','picking_type_in')[1] or False
STATE_SELECTION = [
('draft', 'Draft PO'),

View File

@ -71,7 +71,7 @@
-->
<record id="route_warehouse0_buy" model='stock.location.route'>
<field name="name">Buy</field>
<field name="name">Your Company Buy</field>
<field name="sequence">5</field>
</record>

View File

@ -144,6 +144,7 @@ class purchase_requisition(osv.osv):
def _prepare_purchase_order(self, cr, uid, requisition, supplier, context=None):
supplier_pricelist = supplier.property_product_pricelist_purchase and supplier.property_product_pricelist_purchase.id or False
picking_type_in = self.pool.get("purchase.order")._get_picking_in(cr, uid, context=context)
return {
'origin': requisition.name,
'date_order': requisition.date_end or fields.date.context_today(self, cr, uid, context=context),
@ -154,6 +155,7 @@ class purchase_requisition(osv.osv):
'fiscal_position': supplier.property_account_position and supplier.property_account_position.id or False,
'requisition_id': requisition.id,
'notes': requisition.description,
'picking_type_id': picking_type_in,
}
def _prepare_purchase_order_line(self, cr, uid, requisition, requisition_line, purchase_id, supplier, context=None):

View File

@ -169,10 +169,13 @@ class sale_order(osv.osv):
('waiting_date', 'Waiting Schedule'),
('progress', 'Sales Order'),
('manual', 'Sale to Invoice'),
('shipping_except', 'Shipping Exception'),
('invoice_except', 'Invoice Exception'),
('done', 'Done'),
], 'Status', readonly=True, track_visibility='onchange',
help="Gives the status of the quotation or sales order. \nThe exception status is automatically set when a cancel operation occurs in the processing of a document linked to the sales order. \nThe 'Waiting Schedule' status is set when the invoice is confirmed but waiting for the scheduler to run on the order date.", select=True),
], 'Status', readonly=True, help="Gives the status of the quotation or sales order.\
\nThe exception status is automatically set when a cancel operation occurs \
in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception).\nThe 'Waiting Schedule' status is set when the invoice is confirmed\
but waiting for the scheduler to run on the order date.", select=True),
'date_order': fields.datetime('Date', required=True, readonly=True, select=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}),
'create_date': fields.datetime('Creation Date', readonly=True, select=True, help="Date on which sales order is created."),
'date_confirm': fields.date('Confirmation Date', readonly=True, select=True, help="Date on which sales order is confirmed."),
@ -668,9 +671,11 @@ class sale_order(osv.osv):
for line in order.order_line:
if (line.state == 'done') or not line.product_id:
continue
proc_id = procurement_obj.create(cr, uid, self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context))
proc_ids.append(proc_id)
vals = self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
if vals:
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)
@ -688,6 +693,61 @@ 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':
# returns True if there is at least one canceled line, False otherwise
def test_state(self, cr, uid, ids, mode, *args):
assert mode in ('finished', 'canceled'), _("invalid mode for test_state")
finished = True
canceled = False
write_done_ids = []
write_cancel_ids = []
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])
doneorcancel = all([x in ('done', 'cancel') for x in states])
if cancel:
canceled = True
if line.state != 'exception':
write_cancel_ids.append(line.id)
if not doneorcancel:
finished = False
if doneorcancel and not cancel:
write_done_ids.append(line.id)
if write_done_ids:
self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'})
if write_cancel_ids:
self.pool.get('sale.order.line').write(cr, uid, write_cancel_ids, {'state': 'exception'})
if mode == 'finished':
return finished
elif mode == 'canceled':
return canceled
def procurement_lines_get(self, cr, uid, ids, *args):
res = []
for order in self.browse(cr, uid, ids, context={}):
for line in order.order_line:
res += [x.id for x in line.procurement_ids]
return res
# TODO add a field price_unit_uos
# - update it on change product and unit price
# - use it in report if there is a uos
@ -743,8 +803,6 @@ class sale_order_line(osv.osv):
'sale.order.line': (lambda self,cr,uid,ids,ctx=None: ids, ['invoice_lines'], 10)
}),
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price'), readonly=True, states={'draft': [('readonly', False)]}),
'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft': [('readonly', False)]},
help="From stock: When needed, the product is taken from the stock or we wait for replenishment.\nOn order: When needed, the product is purchased or produced."),
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft': [('readonly', False)]}),
'address_allotment_id': fields.many2one('res.partner', 'Allotment Partner',help="A partner to whom the particular product needs to be allotted."),
@ -774,7 +832,6 @@ class sale_order_line(osv.osv):
'product_uos_qty': 1,
'sequence': 10,
'state': 'draft',
'type': 'make_to_stock',
'price_unit': 0.0,
'delay': 0.0,
}

View File

@ -150,7 +150,6 @@
</group>
<group>
<field name="tax_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','&lt;&gt;','purchase')]"/>
<field name="type"/>
<field name="th_weight"/>
<!-- we should put a config wizard for these two fields -->
<field name="address_allotment_id"/>

View File

@ -162,5 +162,124 @@
<field name="act_to" ref="act_done"/>
</record>
<!--
Procurements creation and checking branch
-->
<!-- Activity -->
<record id="act_wait_ship" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">wait_ship</field>
</record>
<record id="act_cancel3" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">cancel3</field>
<field name="flow_stop">True</field>
<field name="kind">stopall</field>
<field name="action">action_cancel()</field>
</record>
<record id="act_ship" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship</field>
<field name="kind">function</field>
<field name="action">action_ship_create()</field>
</record>
<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>
</record>
<record id="act_ship_cancel" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship_cancel</field>
<field name="flow_stop">True</field>
<field name="kind">stopall</field>
<field name="action">action_cancel()</field>
</record>
<record id="act_ship_except" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship_except</field>
<field name="kind">function</field>
<field name="action">write({'state':'shipping_except'})</field>
</record>
<!-- Transition -->
<record id="trans_router_wait_ship" model="workflow.transition">
<field name="act_from" ref="sale.act_router"/>
<field name="act_to" ref="act_wait_ship"/>
</record>
<record id="trans_router_wait_invoice_shipping" model="workflow.transition">
<field name="act_from" ref="sale.act_wait_invoice"/>
<field name="act_to" ref="sale.act_invoice_end"/>
<field name="condition">(order_policy=='picking')</field>
</record>
<record id="trans_wait_invoice_invoice" model="workflow.transition">
<field name="act_from" ref="sale.act_wait_invoice"/>
<field name="act_to" ref="sale.act_invoice"/>
<field name="condition">order_policy=='prepaid'</field>
</record>
<record id="trans_wait_ship_cancel3" model="workflow.transition">
<field name="act_from" ref="act_wait_ship"/>
<field name="act_to" ref="act_cancel3"/>
<field name="signal">cancel</field>
</record>
<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>
</record>
<record id="trans_ship_end_done" model="workflow.transition">
<field name="act_from" ref="act_ship_end"/>
<field name="act_to" ref="sale.act_done"/>
</record>
<record id="trans_ship_ship_end" model="workflow.transition">
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_end"/>
<field name="trigger_model">procurement.order</field>
<field name="trigger_expr_id">procurement_lines_get()</field>
<field name="condition">test_state('finished')</field>
</record>
<record id="trans_ship_ship_except" model="workflow.transition">
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_except"/>
<field name="condition">test_state('canceled')</field>
</record>
<record id="trans_ship_except_ship" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship"/>
<field name="signal">ship_recreate</field>
</record>
<record id="trans_ship_except_ship_end" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship_end"/>
<field name="signal">ship_corrected</field>
</record>
<record id="trans_ship_except_ship_cancel" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship_cancel"/>
<field name="signal">ship_cancel</field>
</record>
</data>
</openerp>

View File

@ -91,20 +91,6 @@ class sale_order(osv.osv):
return vals
_columns = {
'state': fields.selection([
('draft', 'Draft Quotation'),
('sent', 'Quotation Sent'),
('cancel', 'Cancelled'),
('waiting_date', 'Waiting Schedule'),
('progress', 'Sales Order'),
('manual', 'Sale to Invoice'),
('shipping_except', 'Shipping Exception'),
('invoice_except', 'Invoice Exception'),
('done', 'Done'),
], 'Status', readonly=True, help="Gives the status of the quotation or sales order.\
\nThe exception status is automatically set when a cancel operation occurs \
in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception).\nThe 'Waiting Schedule' status is set when the invoice is confirmed\
but waiting for the scheduler to run on the order date.", select=True),
'incoterm': fields.many2one('stock.incoterms', 'Incoterm', help="International Commercial Terms are a series of predefined commercial terms used in international transactions."),
'picking_policy': fields.selection([('direct', 'Deliver each product when available'), ('one', 'Deliver all products at once')],
'Shipping Policy', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
@ -212,41 +198,7 @@ class sale_order(osv.osv):
self.write(cr, uid, [o.id], {'order_policy': 'manual'}, context=context)
return res
# if mode == 'finished':
# returns True if all lines are done, False otherwise
# if mode == 'canceled':
# returns True if there is at least one canceled line, False otherwise
def test_state(self, cr, uid, ids, mode, *args):
assert mode in ('finished', 'canceled'), _("invalid mode for test_state")
finished = True
canceled = False
write_done_ids = []
write_cancel_ids = []
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])
doneorcancel = all([x in ('done', 'cancel') for x in states])
if cancel:
canceled = True
if line.state != 'exception':
write_cancel_ids.append(line.id)
if not doneorcancel:
finished = False
if doneorcancel and not cancel:
write_done_ids.append(line.id)
if write_done_ids:
self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'})
if write_cancel_ids:
self.pool.get('sale.order.line').write(cr, uid, write_cancel_ids, {'state': 'exception'})
if mode == 'finished':
return finished
elif mode == 'canceled':
return canceled
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)
@ -258,8 +210,8 @@ class sale_order(osv.osv):
res.update({'move_type': order.picking_policy})
return res
def action_ship_end(self, cr, uid, ids, context=None):
super(sale_order, self).action_ship_end(cr, uid, ids, context=context)
for order in self.browse(cr, uid, ids, context=context):
val = {'shipped': True}
if order.state == 'shipping_except':
@ -269,15 +221,12 @@ class sale_order(osv.osv):
if (not line.invoiced) and (line.state not in ('cancel', 'draft')):
val['state'] = 'manual'
break
for line in order.order_line:
towrite = []
if line.state == 'exception':
towrite.append(line.id)
if towrite:
self.pool.get('sale.order.line').write(cr, uid, towrite, {'state': 'done'}, context=context)
res = self.write(cr, uid, [order.id], val)
return True
def has_stockable_products(self, cr, uid, ids, *args):
for order in self.browse(cr, uid, ids):
for order_line in order.order_line:
@ -285,12 +234,7 @@ class sale_order(osv.osv):
return True
return False
def procurement_lines_get(self, cr, uid, ids, *args):
res = []
for order in self.browse(cr, uid, ids, context={}):
for line in order.order_line:
res += [x.id for x in line.procurement_ids]
return res
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
@ -397,7 +341,6 @@ class sale_order_line(osv.osv):
#update of result obtained in super function
product_obj = product_obj.browse(cr, uid, product, context=context)
res['value']['delay'] = (product_obj.sale_delay or 0.0)
#res['value']['type'] = product_obj.procure_method
#check if product is available, and if not: raise an error
uom2 = False

View File

@ -45,7 +45,7 @@
<field name="shipped"/>
<field name="invoice_exists" invisible="1"/>
</field>
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='type']" position="before">
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='tax_id']" position="after">
<label for="delay"/>
<div>
<field name="delay" class="oe_inline"/> days

View File

@ -1,119 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Activity -->
<record id="act_wait_ship" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">wait_ship</field>
</record>
<record id="act_cancel3" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">cancel3</field>
<field name="flow_stop">True</field>
<field name="kind">stopall</field>
<field name="action">action_cancel()</field>
</record>
<record id="act_ship" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship</field>
<field name="kind">function</field>
<field name="action">action_ship_create()</field>
</record>
<record id="act_ship_except" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship_except</field>
<field name="kind">function</field>
<field name="action">write({'state':'shipping_except'})</field>
</record>
<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>
</record>
<record id="act_ship_cancel" model="workflow.activity">
<field name="wkf_id" ref="sale.wkf_sale"/>
<field name="name">ship_cancel</field>
<field name="flow_stop">True</field>
<field name="kind">stopall</field>
<field name="action">action_cancel()</field>
</record>
<!-- Transistion -->
<record id="trans_router_wait_ship" model="workflow.transition">
<field name="act_from" ref="sale.act_router"/>
<field name="act_to" ref="act_wait_ship"/>
</record>
<record id="trans_router_wait_invoice_shipping" model="workflow.transition">
<field name="act_from" ref="sale.act_wait_invoice"/>
<field name="act_to" ref="sale.act_invoice_end"/>
<field name="condition">(order_policy=='picking')</field>
</record>
<record id="trans_wait_invoice_invoice" model="workflow.transition">
<field name="act_from" ref="sale.act_wait_invoice"/>
<field name="act_to" ref="sale.act_invoice"/>
<field name="condition">order_policy=='prepaid'</field>
</record>
<record id="trans_wait_ship_cancel3" model="workflow.transition">
<field name="act_from" ref="act_wait_ship"/>
<field name="act_to" ref="act_cancel3"/>
<field name="signal">cancel</field>
</record>
<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>
</record>
<record id="trans_ship_end_done" model="workflow.transition">
<field name="act_from" ref="act_ship_end"/>
<field name="act_to" ref="sale.act_done"/>
</record>
<record id="trans_ship_ship_end" model="workflow.transition">
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_end"/>
<field name="trigger_model">procurement.order</field>
<field name="trigger_expr_id">procurement_lines_get()</field>
<field name="condition">test_state('finished')</field>
</record>
<record id="trans_ship_ship_except" model="workflow.transition">
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_except"/>
<field name="condition">test_state('canceled')</field>
</record>
<record id="trans_ship_except_ship" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship"/>
<field name="signal">ship_recreate</field>
</record>
<record id="trans_ship_except_ship_end" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship_end"/>
<field name="signal">ship_corrected</field>
</record>
<record id="trans_ship_except_ship_cancel" model="workflow.transition">
<field name="act_from" ref="act_ship_except"/>
<field name="act_to" ref="act_ship_cancel"/>
<field name="signal">ship_cancel</field>
</record>
</data>
</openerp>

View File

@ -1599,18 +1599,19 @@
<field name="name">Orderpoints</field>
<field name="res_model">stock.warehouse.orderpoint</field>
</record>
<!-->
<record model="ir.ui.view" id="product_template_form_view_procurement">
<field name="name">product.template.procurement</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type']" position="after">
<field name="route_ids" widget="many2many_tags"/>
<xpath expr="//field[@name='standard_price']" position="after" >
<group name="procurement_help" col="1" groups="base.group_user">
<field name="route_ids" widget="many2many_tags"/>
</group>
</xpath>
</field>
</record>
</record>-->
<record id="product_search_form_view_procurment" model="ir.ui.view">
<field name="name">product.search.procurment.form</field>
<field name="model">product.product</field>
@ -1628,9 +1629,11 @@
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='general']" position="after" >
<group name="procurement_help" class="oe_grey" col="1" groups="base.group_user">
<!--TODO: Should write explanation for different routes-->
<newline/>
<group>
<field name="route_ids" widget="many2many_tags"/>
</group>
<newline/>
</xpath>
<xpath expr="//div[@name='buttons']" position="inside">
@ -1639,10 +1642,6 @@
<button string="Orderpoints" name="%(product_open_orderpoint)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}"/>
</xpath>
<xpath expr="//field[@name='type']" position="after">
<field name="route_ids" widget="many2many_tags"/>
</xpath>
<group name="procurement_uom" position="before">
<group name="delay" string="Delays">
<label for="produce_delay" attrs="{'invisible':[('type','=','service')]}"/>

View File

@ -190,6 +190,7 @@ class stock_picking(osv.osv):
company = move.company_id
origin = move.picking_id.name
partner, user_id, currency_id = move_obj._get_master_data(cr, uid, move, company, context=context)
key = (partner.id, currency_id, company.id, user_id)
if key not in invoices: