[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:
parent
83f30b55dc
commit
d207edc369
|
@ -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>
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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."
|
|
@ -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'),
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -150,7 +150,6 @@
|
|||
</group>
|
||||
<group>
|
||||
<field name="tax_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','<>','purchase')]"/>
|
||||
<field name="type"/>
|
||||
<field name="th_weight"/>
|
||||
<!-- we should put a config wizard for these two fields -->
|
||||
<field name="address_allotment_id"/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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')]}"/>
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue