[IMP] Move route_ids from product from stock_location to stock and remove supply_method (change with route)

bzr revid: jco@openerp.com-20130909115515-7z6ixaxe7bpxxe73
This commit is contained in:
Josse Colpaert 2013-09-09 13:55:15 +02:00
parent bfafdbc990
commit 30f27b8cbb
34 changed files with 297 additions and 274 deletions

View File

@ -27,7 +27,7 @@
<field name="res_model">product.product</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context" eval="'{\'default_type\':\'service\',\'default_procure_method\':\'make_to_stock\',\'default_supply_method\':\'buy\',\'default_purchase_ok\':True, \'default_sale_ok\':False, \'default_hr_expense_ok\':True,\'default_categ_id\': ' + str(ref('cat_expense')) +'}'"/>
<field name="context" eval="'{\'default_type\':\'service\',\'default_purchase_ok\':True, \'default_sale_ok\':False, \'default_hr_expense_ok\':True,\'default_categ_id\': ' + str(ref('cat_expense')) +'}'"/>
<field name="domain">[('hr_expense_ok','=',True)]</field>
<field name="view_id" ref="product_expense_installer_tree_view"/>
<field name="help">Define one product for each expense type allowed for an employee (travel by car, hostel, restaurant, etc). If you reimburse the employees at a fixed rate, set a cost and a unit of measure on the product. If you reimburse based on real costs, set the cost at 0.00. The user will set the real price when recording his expense sheet.</field>

View File

@ -187,7 +187,7 @@ class mrp_bom(osv.osv):
result[bom.id] = []
if bom.bom_lines:
continue
ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
ok = ((name=='child_complete_ids'))
if (bom.type=='phantom' or ok):
sids = bom_obj.search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
if sids:
@ -209,11 +209,10 @@ class mrp_bom(osv.osv):
continue
if line.bom_lines or line.type == 'phantom':
continue
if line.product_id.supply_method == 'produce':
if line.product_id.procure_method == 'make_to_stock':
res[line.id] = 'stock'
else:
res[line.id] = 'order'
if line.product_id.procure_method == 'make_to_stock':
res[line.id] = 'stock'
else:
res[line.id] = 'order'
return res
_columns = {

View File

@ -27,5 +27,21 @@ This application supports complete integration and production scheduling for sto
<field name="number_increment">1</field>
</record>
<!--
Procurement rules and routes
-->
<record id="route_warehouse0_manufacture" model='stock.location.route'>
<field name="name">Manufacture</field>
<field name="sequence">5</field>
</record>
<record id="procurement_rule_supply_stock" model="procurement.rule">
<field name="name">Manufacture to stock</field>
<field name="action">manufacture</field>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_in"/>
<field name="route_id" ref="route_warehouse0_manufacture"/>
</record>
</data>
</openerp>

View File

@ -347,7 +347,7 @@
<form string="Bill of Material" version="7.0">
<group>
<group>
<field name="product_id" on_change="onchange_product_id(product_id, name, context)" context="{'default_supply_method':'produce'}" class="oe_inline"/>
<field name="product_id" on_change="onchange_product_id(product_id, name, context)" class="oe_inline"/>
<label for="product_qty" string="Quantity"/>
<div>
<field name="product_qty" class="oe_inline"/>
@ -380,7 +380,7 @@
<page string="Components">
<field name="bom_lines" widget="one2many_list">
<tree string="Components" editable="bottom">
<field name="product_id" context="{'default_supply_method':'produce'}" on_change="onchange_product_id(product_id, name)"/>
<field name="product_id" on_change="onchange_product_id(product_id, name)"/>
<field name="product_qty"/>
<field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
<field name="name" invisible="1"/>
@ -517,7 +517,7 @@
<field name="res_model">product.product</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="context">{'search_default_filter_supply_method_produce' : 1}</field>
<field name="context">{}</field>
<field name="search_view_id" ref="product.product_search_form_view"/>
</record>
<!-- BOM menus -->
@ -634,7 +634,7 @@
</div>
<group>
<group>
<field name="product_id" on_change="product_id_change(product_id)" domain="[('bom_ids','!=',False),('bom_ids.bom_id','=',False)]" class="oe_inline" context='{"default_supply_method":"produce", "default_type": "product"}'/>
<field name="product_id" on_change="product_id_change(product_id)" domain="[('bom_ids','!=',False),('bom_ids.bom_id','=',False)]" class="oe_inline" context='{"default_type": "product"}'/>
<label for="product_qty"/>
<div>
<field name="product_qty" class="oe_inline"/>
@ -950,20 +950,7 @@
</data>
</field>
</record>
<record id="product_product_normal_form_supply_view" model="ir.ui.view">
<field name="name">product.normal.form.mrp.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='supply_method']" position="attributes">
<attribute name="invisible">False</attribute>
</xpath>
<group name="procurement_help" position="inside">
<!-- TODO: create help with routes -->
<p>Here should come some help about manufacturing routes</p>
</group>
</field>
</record>
<!-- Menu for Resource for MRP-->

View File

@ -44,9 +44,8 @@ class procurement_order(osv.osv):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
#if there isn't any specific procurement.rule defined for the product, we try to directly supply it from a supplier
if procurement.product_id.supply_method == 'manufacture':
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'manufacture'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'manufacture'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
return rule_id
def _run(self, cr, uid, procurement, context=None):
@ -92,7 +91,7 @@ class procurement_order(osv.osv):
def get_phantom_bom_id(self, cr, uid, ids, context=None):
for procurement in self.browse(cr, uid, ids, context=context):
if procurement.move_dest_id and procurement.move_dest_id.product_id.supply_method=='produce':
if procurement.move_dest_id:
phantom_bom_id = self.pool.get('mrp.bom').search(cr, uid, [
('product_id', '=', procurement.move_dest_id.product_id.id),
('bom_id', '=', False),

View File

@ -41,57 +41,57 @@ class StockMove(osv.osv):
procurement_obj = self.pool.get('procurement.order')
product_obj = self.pool.get('product.product')
processed_ids = [move.id]
if move.product_id.supply_method == 'produce':
bis = bom_obj.search(cr, uid, [
('product_id','=',move.product_id.id),
('bom_id','=',False),
('type','=','phantom')])
if bis:
factor = move.product_qty
bom_point = bom_obj.browse(cr, uid, bis[0], context=context)
res = bom_obj._bom_explode(cr, uid, bom_point, factor, [])
state = 'confirmed'
if move.state == 'assigned':
state = 'assigned'
for line in res[0]:
valdef = {
'picking_id': move.picking_id.id,
'product_id': line['product_id'],
'product_uom': line['product_uom'],
'product_qty': line['product_qty'],
'product_uos': line['product_uos'],
'product_uos_qty': line['product_uos_qty'],
'move_dest_id': move.id,
'state': state,
'name': line['name'],
'procurements': [],
}
mid = move_obj.copy(cr, uid, move.id, default=valdef)
processed_ids.append(mid)
prodobj = product_obj.browse(cr, uid, line['product_id'], context=context)
proc_id = procurement_obj.create(cr, uid, {
'name': (move.picking_id.origin or ''),
'origin': (move.picking_id.origin or ''),
'date_planned': move.date,
'product_id': line['product_id'],
'product_qty': line['product_qty'],
'product_uom': line['product_uom'],
'product_uos_qty': line['product_uos'] and line['product_uos_qty'] or False,
'product_uos': line['product_uos'],
'location_id': move.location_id.id,
'procure_method': prodobj.procure_method,
'move_id': mid,
})
procurement_obj.signal_button_confirm(cr, uid, [proc_id])
move_obj.write(cr, uid, [move.id], {
'location_dest_id': move.location_id.id, # dummy move for the kit
'picking_id': False,
'state': 'confirmed'
bis = bom_obj.search(cr, uid, [
('product_id','=',move.product_id.id),
('bom_id','=',False),
('type','=','phantom')])
if bis:
factor = move.product_qty
bom_point = bom_obj.browse(cr, uid, bis[0], context=context)
res = bom_obj._bom_explode(cr, uid, bom_point, factor, [])
state = 'confirmed'
if move.state == 'assigned':
state = 'assigned'
for line in res[0]:
valdef = {
'picking_id': move.picking_id.id,
'product_id': line['product_id'],
'product_uom': line['product_uom'],
'product_qty': line['product_qty'],
'product_uos': line['product_uos'],
'product_uos_qty': line['product_uos_qty'],
'move_dest_id': move.id,
'state': state,
'name': line['name'],
'procurements': [],
}
mid = move_obj.copy(cr, uid, move.id, default=valdef)
processed_ids.append(mid)
prodobj = product_obj.browse(cr, uid, line['product_id'], context=context)
proc_id = procurement_obj.create(cr, uid, {
'name': (move.picking_id.origin or ''),
'origin': (move.picking_id.origin or ''),
'date_planned': move.date,
'product_id': line['product_id'],
'product_qty': line['product_qty'],
'product_uom': line['product_uom'],
'product_uos_qty': line['product_uos'] and line['product_uos_qty'] or False,
'product_uos': line['product_uos'],
'location_id': move.location_id.id,
'procure_method': prodobj.procure_method,
'move_id': mid,
})
procurement_ids = procurement_obj.search(cr, uid, [('move_id','=',move.id)], context)
procurement_obj.signal_button_confirm(cr, uid, procurement_ids)
procurement_obj.signal_button_wait_done(cr, uid, procurement_ids)
procurement_obj.signal_button_confirm(cr, uid, [proc_id])
move_obj.write(cr, uid, [move.id], {
'location_dest_id': move.location_id.id, # dummy move for the kit
'picking_id': False,
'state': 'confirmed'
})
procurement_ids = procurement_obj.search(cr, uid, [('move_id','=',move.id)], context)
procurement_obj.signal_button_confirm(cr, uid, procurement_ids)
procurement_obj.signal_button_wait_done(cr, uid, procurement_ids)
return processed_ids
def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None):

View File

@ -150,7 +150,6 @@
</record>
<record id="product_product_odoo1" model="product.product">
<field name="default_code">ODOO</field>
<field name="supply_method">produce</field>
<field name="list_price">35.0</field>
<field name="standard_price">10.0</field>
<field name="uom_id" ref="product.product_uom_unit"/>

View File

@ -2,7 +2,6 @@
<data noupdate="1">
<record id="product_product_jambon" model="product.product">
<field name="supply_method">buy</field>
<field name="list_price">7.0</field>
<field name="standard_price">5.0</field>
<field name="uom_id" ref="product.product_uom_unit"/>
@ -32,7 +31,6 @@
</record>
<record id="product_product_from" model="product.product">
<field name="supply_method">buy</field>
<field name="list_price">8.0</field>
<field name="standard_price">6.0</field>
<field name="uom_id" ref="product.product_uom_unit"/>
@ -62,7 +60,6 @@
</record>
<record id="product_product_pain" model="product.product">
<field name="supply_method">buy</field>
<field name="list_price">8.0</field>
<field name="standard_price">6.0</field>
<field name="uom_id" ref="product.product_uom_unit"/>
@ -92,7 +89,6 @@
</record>
<record id="product_product_lait" model="product.product">
<field name="supply_method">buy</field>
<field name="list_price">8.0</field>
<field name="standard_price">6.0</field>
<field name="uom_id" ref="product.product_uom_unit"/>

View File

@ -41,16 +41,6 @@
</field>
</field>
</record>
<record id="product_product_normal_form_supply_view" model="ir.ui.view">
<field name="name">product.normal.form.project_mrp.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='supply_method']" position="attributes">
<attribute name="invisible">False</attribute>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -16,7 +16,6 @@
mes_type: fixed
name: HR Manager
standard_price: 1.0
supply_method: buy
type: service
uom_id: product.product_uom_hour
uom_po_id: product.product_uom_hour

View File

@ -1122,9 +1122,8 @@ class procurement_order(osv.osv):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
#if there isn't any specific procurement.rule defined for the product, we try to directly supply it from a supplier
if procurement.product_id.supply_method == 'buy' and self._check_supplier_info(cr, uid, [procurement.id], context=context):
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'buy'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'buy'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
return rule_id
def _run(self, cr, uid, procurement, context=None):

View File

@ -67,14 +67,20 @@
</record>
<!--
Procurement rules
Procurement rules and routes
-->
<record id="route_warehouse0_buy" model='stock.location.route'>
<field name="name">Buy</field>
<field name="sequence">5</field>
</record>
<record id="procurement_rule_supply_stock" model="procurement.rule">
<field name="name">Buy to refill stock</field>
<field name="name">Buy to stock</field>
<field name="action">buy</field>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_in"/>
<field name="route_id" ref="route_warehouse0_buy"/>
</record>
</data>

View File

@ -573,18 +573,6 @@
</field>
</record>
<record id="product_product_normal_form_procurement_help_view" model="ir.ui.view">
<field name="name">product.normal.form.procurement.help.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
<field name="arch" type="xml">
<group name="procurement_help" position="inside">
<!--TODO: Should add some procurement help here (something like route.description)-->
<p> Procurement help </p>
</group>
</field>
</record>
<record id="product_search_form_view_purchase" model="ir.ui.view">
<field name="name">product.search.purchase.form</field>
<field name="model">product.product</field>

View File

@ -1,14 +1,18 @@
-
In order to test the scheduler to generate RFQ, I create a new product
-
!record {model: product.product, id: scheduler_product}:
name: scheduler prod
type: product
supply_method: buy
seller_ids:
- delay: 1
name: base.res_partner_2
min_qty: 5.0
!record {model: product.product, id: scheduler_product}:
name: scheduler prod
type: product
seller_ids:
- delay: 1
name: base.res_partner_2
min_qty: 5.0
-
Add Buy route
-
!python {model: product.product, id: scheduler_product}: |
self.write(cr, uid, [ref("scheduler_product")], {"route_ids": [(4, ref("purchase.route_warehouse0_buy"))]})
-
I create a procurement order.
-

View File

@ -197,7 +197,7 @@
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
<field name="arch" type="xml">
<field name="supply_method" position="after">
<field name="route_ids" position="after">
<field name="purchase_requisition"/>
</field>
</field>

View File

@ -640,9 +640,13 @@ class sale_order(osv.osv):
def _get_date_planned(self, cr, uid, order, line, start_date, context=None):
date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta(days=line.delay or 0.0)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
return date_planned
def _prepare_procurement_group(self, cr, uid, order, context=None):
return {
'name': order.name, 'partner_id': order.partner_shipping_id.id,
}
def action_ship_create(self, cr, uid, ids, context=None):
"""Create the required procurements to supply sales order lines, also connecting
the procurements to appropriate stock moves in order to bring the goods to the
@ -657,9 +661,9 @@ class sale_order(osv.osv):
procurement_obj = self.pool.get('procurement.order')
for order in self.browse(cr, uid, ids, context=context):
proc_ids = []
group_id = self.pool.get("procurement.group").create(cr, uid, {
'name': order.name, 'partner_id': order.partner_shipping_id.id, 'move_type': order.picking_policy
}, context=context)
vals = self._prepare_procurement_group(cr, uid, order, 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:

View File

@ -325,7 +325,6 @@ Thanks!</field>
<field name="type">service</field>
<field name="list_price">150.0</field>
<field name="standard_price">100.0</field>
<field name="supply_method">produce</field> <!-- TODO this is a procurement field, which is not a sale dependency -->
<field name="uom_id" ref="product.product_uom_day"/>
<field name="uom_po_id" ref="product.product_uom_day"/>
<field name="company_id" eval="[]"/>

View File

@ -64,9 +64,9 @@ class mrp_production(osv.osv):
if parent_move_line:
move = move_obj.browse(cr, uid, parent_move_line)
if field_name == 'name':
res[production.id] = move.sale_line_id and move.sale_line_id.order_id.name or False
res[production.id] = move.procurement_id and move.procurement_id.sale_line_id and move.procurement_id.sale_line_id.order_id.name or False
if field_name == 'client_order_ref':
res[production.id] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
res[production.id] = move.procurement_id and move.procurement_id.sale_line_id and move.procurement_id.sale_line_id.order_id.client_order_ref or False
return res
_columns = {

View File

@ -19,7 +19,6 @@
mes_type: fixed
name: Slider Mobile
standard_price: 189.0
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
@ -38,10 +37,14 @@
min_qty: 2.0
qty: 5.0
standard_price: 189.0
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
-
I add the routes manufacture and mto to the product
-
!python {model: product.product, id: scheduler_product}: |
self.write(cr, uid, [ref("product_product_slidermobile0")], {"route_ids": [(4, ref("mrp.route_warehouse0_manufacture")), (4, ref("stock.route_warehouse0_mto"))]})
-
I create a Bill of Material record for Slider Mobile
-
@ -97,7 +100,7 @@
sale_order_obj = self.pool.get('sale.order')
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
proc_ids = self.search(cr, uid, [('origin','=',so.name)])
self.signal_button_check(cr, uid, proc_ids)
self.run(cr, uid, proc_ids)
-
I verify that a procurement state is "running"
-
@ -105,14 +108,14 @@
sale_order_obj = self.pool.get('sale.order')
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
proc_ids = self.search(cr, uid, [('origin','=',so.name) and ('state','=','running')])
assert proc_ids, 'Procurement is not in the running state!'
assert len(proc_ids) == 2, 'Not both procurements are in the running state!'
-
I verify that a manufacturing order has been generated, and that its name and reference are correct
-
!python {model: sale.order}: |
mnf_obj = self.pool.get('mrp.production')
so = self.browse(cr, uid, ref("sale_order_so0"))
mnf_id = mnf_obj.search(cr, uid, [('origin','=',so.name)])
mnf_id = mnf_obj.search(cr, uid, [('origin','like',so.name)])
assert mnf_id, 'Manufacturing order has not been generated'
mo = mnf_obj.browse(cr, uid, mnf_id)[0]
assert mo.sale_name == so.name, 'Wrong Name for the Manufacturing Order. Expected %s, Got %s' % (so.name, mo.name)

View File

@ -246,6 +246,17 @@ class sale_order(osv.osv):
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)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
return date_planned
def _prepare_procurement_group(self, cr, uid, order, context=None):
res = super(sale_order, self)._prepare_procurement_group(cr, uid, order, context=None)
res.update({'move_type': order.picking_policy})
return res
def action_ship_end(self, cr, uid, ids, context=None):

View File

@ -41,7 +41,7 @@
<record id="stock_location_route_form_view_inherit" model="ir.ui.view">
<field name="name">stock.location.route.form</field>
<field name="inherit_id" ref="stock_location.stock_location_route_form_view"/>
<field name="inherit_id" ref="stock.stock_location_route_form_view"/>
<field name="model">stock.location.route</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">

View File

@ -40,14 +40,29 @@ class procurement_rule(osv.osv):
result = super(procurement_rule, self)._get_action(cr, uid, context=context)
return result + [('move', 'Move From Another Location')]
def _get_rules(self, cr, uid, ids, context=None):
res = []
for route in self.browse(cr, uid, ids):
res += [x.id for x in route.pull_ids]
return res
_columns = {
'location_id': fields.many2one('stock.location', 'Destination Location'),
'location_src_id': fields.many2one('stock.location', 'Source Location',
help="Source location is action=move"),
'route_id': fields.many2one('stock.location.route', 'Route',
help="If route_id is False, the rule is global"),
'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procure Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until re-supplying. 'Make to Order': When needed, purchase or produce for the procurement request."),
'route_sequence': fields.related('route_id', 'sequence', string='Route Sequence', store={'stock.location.route': (_get_rules, ['sequence'], 10)}),
'sequence': fields.integer('Sequence'),
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type',
help="Picking Type determines the way the picking should be shown in the view, reports, ...")
}
_defaults = {
'procure_method': 'make_to_stock',
}
class procurement_order(osv.osv):
_inherit = "procurement.order"
_columns = {
@ -57,13 +72,18 @@ class procurement_order(osv.osv):
}
def _search_suitable_rule(self, cr, uid, procurement, domain, context=None):
'''method overwritten in stock_location that is used to search the best suitable rule'''
return self.pool.get('procurement.rule').search(cr, uid, domain, context=context)
'''we try to first find a rule among the ones defined on the procurement order group and if none is found, we try on the routes defined for the product, and finally we fallback on the default behavior'''
route_ids = [x.id for x in procurement.product_id.route_ids]
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', route_ids)], order = 'route_sequence, sequence', context=context)
if not res:
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', '=', False)], order='sequence', context=context)
return res
def _find_suitable_rule(self, cr, uid, procurement, context=None):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
rule_id = self._search_suitable_rule(cr, uid, procurement, [('location_id', '=', procurement.location_id.id)], context=context) #action=move
rule_id = self._search_suitable_rule(cr, uid, procurement, [('location_id', 'child_of', procurement.location_id.id)], context=context) #action=move
rule_id = rule_id and rule_id[0] or False
return rule_id
@ -88,6 +108,7 @@ class procurement_order(osv.osv):
'move_dest_id': procurement.move_dest_id and procurement.move_dest_id.id or False,
'procurement_id': procurement.id,
'rule_id': procurement.rule_id.id,
'procure_method': procurement.rule_id.procure_method,
'origin': procurement.origin,
'picking_type_id': procurement.rule_id.picking_type_id.id,
}
@ -203,12 +224,9 @@ class procurement_order(osv.osv):
continue
product = product_obj.browse(cr, uid, [product_read['id']], context=context)[0]
if product.supply_method == 'buy':
location_id = warehouse.lot_stock_id.id
elif product.supply_method == 'produce':
location_id = warehouse.lot_stock_id.id
else:
continue
location_id = warehouse.lot_stock_id.id
proc_id = proc_obj.create(cr, uid,
self._prepare_automatic_op_procurement(cr, uid, product, warehouse, location_id, context=context),
context=context)

View File

@ -1,29 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="product.product_product_1" model="product.product">
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_2" model="product.product">
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_3" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_4" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_5" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_6" model="product.product">
@ -68,7 +56,6 @@
<record id="product.product_product_16" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_17" model="product.product">
@ -77,12 +64,10 @@
<record id="product.product_product_18" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_19" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_20" model="product.product">
@ -115,7 +100,6 @@
<record id="product.product_product_27" model="product.product">
<field name="type">product</field>
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_28" model="product.product">
@ -166,9 +150,6 @@
<field name="type">product</field>
</record>
<record id="product.product_product_44" model="product.product">
<field name="supply_method">produce</field>
</record>
<record id="product.product_product_45" model="product.product">
<field name="type">product</field>

View File

@ -211,6 +211,8 @@ class product_product(osv.osv):
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one'),
'warehouse_id': fields.dummy(string='Warehouse', relation='stock.warehouse', type='many2one'),
'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rules'),
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_product', 'product_id', 'route_id', 'Routes',
help="Depending on the modules installed, this will allow you to define the route of the product: whether it will be bought, manufactured, MTO/MTS,..."),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):

View File

@ -33,6 +33,8 @@ import openerp.addons.decimal_precision as dp
import logging
_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# Incoterms
#----------------------------------------------------------
@ -123,6 +125,28 @@ class stock_location(osv.osv):
def get_removal_strategy(self, cr, uid, location, product, context=None):
return None
#----------------------------------------------------------
# Routes
#----------------------------------------------------------
class stock_location_route(osv.osv):
_name = 'stock.location.route'
_description = "Inventory Routes"
_order = 'sequence'
_columns = {
'name': fields.char('Route Name', required=True),
'sequence': fields.integer('Sequence'),
'pull_ids': fields.one2many('procurement.rule', 'route_id', 'Pull Rules'),
}
_defaults = {
'sequence': lambda self,cr,uid,ctx: 0,
}
#----------------------------------------------------------
# Quants
#----------------------------------------------------------
@ -2290,14 +2314,7 @@ class stock_warehouse_orderpoint(osv.osv):
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context=context)
class product_template(osv.osv):
_inherit = "product.template"
_columns = {
'supply_method': fields.selection([('produce', 'Manufacture'), ('buy', 'Buy'), ('wait', 'None')], 'Supply Method', required=True, help="Manufacture: When procuring the product, a manufacturing order or a task will be generated, depending on the product type. \nBuy: When procuring the product, a purchase order will be generated."),
}
_defaults = {
'supply_method': 'buy',
}
class stock_picking_type(osv.osv):
_name = "stock.picking.type"

View File

@ -158,15 +158,30 @@ watch your stock valuation, and track production lots upstream and downstream (b
-->
<record id="procurement_rule_customer0" model="procurement.rule">
<field name="name">Stock > Customer</field>
<field name="name">Stock → Customer</field>
<field name="action">move</field>
<field name="location_src_id" ref="stock_location_stock"/>
<field name="location_id" ref="stock_location_customers"/>
<field name="picking_type_id" ref="picking_type_out"/>
<field name="procure_method">make_to_stock</field>
</record>
<record id="route_warehouse0_mto" model='stock.location.route'>
<field name="name">MTO</field>
<field name="sequence">10</field>
</record>
<record id="procurement_rule_customer_mto" model="procurement.rule">
<field name="name">Stock → Customer</field>
<field name="action">move</field>
<field name="location_id" ref="stock_location_customers"/>
<field name="location_src_id" ref="stock_location_stock"/>
<field name="picking_type_id" ref="picking_type_out"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto"/>
</record>
<!--
Properties
-->

View File

@ -1485,10 +1485,14 @@
<group>
<field name="location_src_id"/>
<field name="location_id"/>
<field name="route_id"/>
<field name="route_sequence"/>
<field name="sequence"/>
</group>
<group>
<field name="action"/>
<field name="picking_type_id" attrs="{'required': [('action', '!=', 'manufacture')]}"/>
<field name="procure_method" attrs="{'invisible': [('action', '!=', 'move')]}"/>
<field name="group_id"/>
</group>
</group>
@ -1602,7 +1606,7 @@
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type']" position="after">
<field name="supply_method"/>
<field name="route_ids" widget="many2many_tags"/>
</xpath>
</field>
</record>
@ -1635,8 +1639,8 @@
<button string="Orderpoints" name="%(product_open_orderpoint)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}"/>
</xpath>
<xpath expr="//field[@name='standard_price']" position="before">
<field name="supply_method" groups="base.group_user"/>
<xpath expr="//field[@name='type']" position="after">
<field name="route_ids" widget="many2many_tags"/>
</xpath>
<group name="procurement_uom" position="before">
@ -1801,5 +1805,22 @@
<field name="res_model">stock.quant.package</field>
</record>
<menuitem id="menu_package" name="Packages" parent="menu_stock_product" action="action_package_view"/>
<!--Routes-->
<record id="stock_location_route_form_view" model="ir.ui.view">
<field name="name">stock.location.route.form</field>
<field name="model">stock.location.route</field>
<field eval="7" name="priority" />
<field name="arch" type="xml">
<form string="Route">
<field name="name"/>
<field name="sequence" groups="base.group_no_one"/>
<group string="Pull Rules" colspan="4" >
<field name="pull_ids" colspan="4" nolabel="1"/>
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -24,6 +24,7 @@
<field name="name">Drop Shipping</field>
<field name="sequence">3</field>
<field name="sale_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="product_categ_selectable" eval="True"/>
</record>

View File

@ -25,21 +25,17 @@ from dateutil.relativedelta import relativedelta
from openerp.tools.translate import _
class stock_location_route(osv.osv):
_name = 'stock.location.route'
_inherit = 'stock.location.route'
_description = "Inventory Routes"
_order = 'sequence'
_columns = {
'name': fields.char('Route Name', required=True),
'sequence': fields.integer('Sequence'),
'pull_ids': fields.one2many('procurement.rule', 'route_id', 'Pull Rules'),
'push_ids': fields.one2many('stock.location.path', 'route_id', 'Push Rules'),
'product_selectable': fields.boolean('Selectable on Product'),
'product_categ_selectable': fields.boolean('Selectable on Product Category'),
'warehouse_selectable': fields.boolean('Selectable on Warehouse'),
}
_defaults = {
'sequence': lambda self,cr,uid,ctx: 0,
'product_selectable': True
}
class stock_warehouse(osv.osv):
@ -115,33 +111,18 @@ class stock_location_path(osv.osv):
class procurement_rule(osv.osv):
_inherit = 'procurement.rule'
def _get_rules(self, cr, uid, ids, context=None):
res = []
for route in self.browse(cr, uid, ids):
res += [x.id for x in route.pull_ids]
return res
_columns = {
'route_id': fields.many2one('stock.location.route', 'Route',
help="If route_id is False, the rule is global"),
'delay': fields.integer('Number of Hours'),
'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procure Method', required=True, help="'Make to Stock': When needed, take from the stock or wait until re-supplying. 'Make to Order': When needed, purchase or produce for the procurement request."),
'partner_address_id': fields.many2one('res.partner', 'Partner Address'),
'route_sequence': fields.related('route_id', 'sequence', string='Route Sequence', store={'stock.location.route': (_get_rules, ['sequence'], 10)}),
'sequence': fields.integer('Sequence'),
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when the previous move of the move (which was generated by a next procurement) is cancelled or split, the move generated by this move will too'),
}
_defaults = {
'procure_method': 'make_to_stock',
'propagate': True,
'delay': 0,
}
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
@ -157,7 +138,6 @@ class procurement_order(osv.osv):
newdate = (datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.rule_id.delay or 0)).strftime('%Y-%m-%d %H:%M:%S')
d.update({
'date': newdate,
'procure_method': procurement.rule_id.procure_method or 'make_to_stock',
'propagate': procurement.rule_id.propagate,
})
return d

View File

@ -25,44 +25,45 @@
<field name="name">Sale: Ship only</field>
<field name="sequence">20</field>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
</record>
<record id="procurement_rule_customer0_mts" model="procurement.rule">
<field name="name">Stock → output</field>
<field name="name">Stock → customer</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_mts"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="procurement_rule_customer1_mts" model="procurement.rule">
<field name="name">Output → Customer</field>
<!-- Override from stock-->
<!--<record id="procurement_rule_customer_mto" model="procurement.rule">
<field name="name">Stock → Customer</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_output"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mts"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
</record>
<record id="route_warehouse0_mto" model='stock.location.route'>
<field name="name">MTO</field>
<field name="sequence">10</field>
<field name="product_selectable" eval="True"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="stock.route_warehouse0_mto"/>
<field name="product_categ_selectable" eval="True"/>
</record>
<record id="route_warehouse0_mto" model='stock.location.route'>
<field name="name">MTO</field>
<field name="sequence">10</field>
<field name="product_categ_selectable" eval="True"/>
</record>-->
<record id="procurement_rule_customer0_mto" model="procurement.rule">
<field name="name">Stock → output</field>
<field name="name">Stock → Customer</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto"/>
<field name="route_id" ref="stock.route_warehouse0_mto"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
@ -71,6 +72,8 @@
<field name="sequence">9</field>
<field name="product_categ_selectable" eval="True"/>
<field name="sale_selectable" eval="True"/>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
</record>
<record id="procurement_rule_customer0_xdock" model="procurement.rule">
@ -87,13 +90,18 @@
<field name="name">Sale: Pack + Ship</field>
<field name="sequence">15</field>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
</record>
<record id="route_warehouse0_mto_pack" model='stock.location.route'>
<field name="name">MTO pack</field>
<field name="sequence">10</field>
</record>
<record id="procurement_rule_customer0_pack" model="procurement.rule">
<field name="name">Stock → Pack</field>
<field name="name">Stock → Output</field>
<field name="action">move</field>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_pack"/>
@ -109,25 +117,15 @@
<field name="route_id" ref="route_warehouse0_pack"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
</record>
<record id="procurement_rule_customer2_pack" model="procurement.rule">
<field name="name">Pack → Output</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="location_pack_zone"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_pack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="procurement_rule_customer0_mto_pack" model="procurement.rule">
<field name="name">Stock → pack</field>
<field name="name">Stock → Output MTO</field>
<field name="action">move</field>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto"/>
<field name="route_id" ref="route_warehouse0_mto_pack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
@ -137,30 +135,20 @@
<field name="name">Sale: Pick + Pack + Ship</field>
<field name="sequence">20</field>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
</record>
<record id="procurement_rule_customer0_pickpack" model="procurement.rule">
<field name="name">Stock → Pick</field>
<field name="name">Stock → Pack</field>
<field name="action">move</field>
<field name="location_id" ref="location_pick_zone"/>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="procurement_rule_customer3_pickpack" model="procurement.rule">
<field name="name">Pick → Pack</field>
<field name="action">move</field>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_src_id" ref="location_pick_zone"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="procurement_rule_customer1_pickpack" model="procurement.rule">
<field name="name">Output → Customer</field>
<field name="action">move</field>
@ -181,14 +169,18 @@
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="route_warehouse0_mto_pick" model='stock.location.route'>
<field name="name">MTO pick</field>
<field name="sequence">10</field>
</record>
<record id="procurement_rule_customer0_mto_pack" model="procurement.rule">
<field name="name">Stock → Pick</field>
<record id="procurement_rule_customer0_mto_pick" model="procurement.rule">
<field name="name">Stock → Pack MTO</field>
<field name="action">move</field>
<field name="location_id" ref="location_pick_zone"/>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto"/>
<field name="route_id" ref="route_warehouse0_mto_pick"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
</data>

View File

@ -6,17 +6,12 @@
<field name="name">stock.procurement.rule.inherit.form</field>
<field name="model">procurement.rule</field>
<field name="inherit_id" ref="stock.view_procurement_rule_form"/>
<field name="arch" type="xml">
<field name="location_id" position="after">
<field name="route_id"/>
<field name="route_sequence"/>
<field name="sequence"/>
<field name="delay"/>
<field name="propagate"/>
</field>
<field name="group_id" position="before">
<field name="procure_method"/>
<field name="partner_address_id"/>
</field>
</field>
@ -166,33 +161,28 @@
<tree string="Routes">
<field name="sequence" widget="handle" />
<field name="name"/>
<field name="product_categ_selectable"/>
<field name="product_selectable"/>
<field name="product_categ_selectable"/>
<field name="warehouse_selectable"/>
</tree>
</field>
</record>
<record id="stock_location_route_form_view" model="ir.ui.view">
<record id="stock_location_route_form_view_inherit" model="ir.ui.view">
<field name="name">stock.location.route.form</field>
<field name="model">stock.location.route</field>
<field eval="7" name="priority" />
<field name="inherit_id" ref="stock.stock_location_route_form_view"/>
<field name="arch" type="xml">
<form string="Route">
<field name="name" />
<field name="sequence" groups="base.group_no_one"/>
<group>
<field name="product_categ_selectable"/>
<field name="product_selectable"/>
<field name="warehouse_selectable"/>
</group>
<group string="Push Rules" colspan="4" >
<field name="push_ids" colspan="4" nolabel="1"/>
<xpath expr="//field[@name='sequence']" position="after">
<group>
<field name="product_categ_selectable"/>
<field name="product_selectable"/>
<field name="warehouse_selectable"/>
</group>
<group string="Pull Rules" colspan="4" >
<field name="pull_ids" colspan="4" nolabel="1"/>
</group>
</form>
<group string="Push Rules" colspan="4" >
<field name="push_ids" colspan="4" nolabel="1"/>
</group>
</xpath>
</field>
</record>

View File

@ -47,7 +47,6 @@
name: res_partner_microlinktechnologies0
min_qty: 5.0
route_ids: [stock_location_route_push]
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit

View File

@ -33,9 +33,9 @@ It creates 3 warehouses
'author': 'OpenERP SA',
'images': [],
'depends': ['stock_complex_routes'],
'data': ['stock_multi_warehouse.yml'],
'data': [],
'demo': [
'stock_multi_warehouse.yml'
],
'installable': True,
'test': [

View File

@ -1,3 +1,6 @@
-
!context
noupdate: 0
-
Create Two Customers
-
@ -180,6 +183,8 @@
-
!record {model: stock.location.route, id: route_wh_panama_main_ship}:
name: Ship main panama
warehouse_selectable: True
product_selectable: False
pull_ids:
- invoice_state: none
location_id: location_panama_main_output
@ -200,6 +205,8 @@
-
!record {model: stock.location.route, id: route_wh_panama_santiago_ship}:
name: Ship panama santiago
warehouse_selectable: True
product_selectable: False
pull_ids:
- invoice_state: none
location_id: location_panama_santiago_output
@ -215,7 +222,8 @@
picking_type_id: picking_type_santiago_out
procure_method: make_to_order
action: move
-
Add routes to warehouses
-
!python {model: stock.warehouse}: |
self.write(cr, uid, [ref('wh_panama_main')], {'route_id': ref('route_wh_panama_main_ship')}, context=context)