[MERGE] merged with main branch

bzr revid: qdp-launchpad@openerp.com-20131023122842-d4yxulpthx4qa9q5
This commit is contained in:
Quentin (OpenERP) 2013-10-23 14:28:42 +02:00
commit f2b9d8f05f
13 changed files with 171 additions and 97 deletions

View File

@ -40,6 +40,11 @@ class procurement_order(osv.osv):
'production_id': fields.many2one('mrp.production', 'Manufacturing Order'),
}
def propagate_cancel(self, cr, uid, procurement, context=None):
if procurement.rule_id.action == 'manufacture' and procurement.production_id:
self.pool.get('mrp.production').action_cancel(cr, uid, [procurement.production_id.id], context=context)
return super(procurement_order, self).propagate_cancel(cr, uid, procurement, context=context)
def _run(self, cr, uid, procurement, context=None):
if procurement.rule_id and procurement.rule_id.action == 'manufacture':
#make a manufacturing order for the procurement

View File

@ -102,13 +102,13 @@ class purchase_order(osv.osv):
for id in ids:
res[id] = [0.0,0.0]
cr.execute('''SELECT
p.purchase_id,sum(m.product_qty), m.state
p.order_id, sum(m.product_qty), m.state
FROM
stock_move m
LEFT JOIN
stock_picking p on (p.id=m.picking_id)
purchase_order_line p on (p.id=m.purchase_line_id)
WHERE
p.purchase_id IN %s GROUP BY m.state, p.purchase_id''',(tuple(ids),))
p.order_id IN %s GROUP BY m.state, p.order_id''',(tuple(ids),))
for oid,nbr,state in cr.fetchall():
if state=='cancel':
continue
@ -964,6 +964,12 @@ class purchase_order_line(osv.osv):
supplier_delay = int(supplier_info.delay) if supplier_info else 0
return datetime.strptime(date_order_str, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=supplier_delay)
def action_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
for po_line in self.browse(cr, uid, ids, context=context):
if all([l.state == 'cancel' for l in po_line.order_id.order_line]):
self.pool.get('purchase.order').action_cancel(cr, uid, [po_line.order_id.id], context=context)
def _check_product_uom_group(self, cr, uid, context=None):
group_uom = self.pool.get('ir.model.data').get_object(cr, uid, 'product', 'group_uom')
res = [user for user in group_uom.users if user.id == uid]
@ -1079,12 +1085,16 @@ class procurement_rule(osv.osv):
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'purchase_line_id': fields.many2one('purchase.order.line', 'Purchase Order'),
'purchase_line_id': fields.many2one('purchase.order.line', 'Purchase Order Line'),
'purchase_id': fields.related('purchase_line_id', 'order_id', type='many2one', relation='purchase.order', string='Purchase Order'),
}
def propagate_cancel(self, cr, uid, procurement, context=None):
if procurement.rule_id.action == 'buy' and procurement.purchase_line_id:
self.pool.get('purchase.order.line').action_cancel(cr, uid, [procurement.purchase_line_id.id], context=context)
return super(procurement_order, self).propagate_cancel(cr, uid, procurement, context=context)
def _run(self, cr, uid, procurement, context=None):
if procurement.rule_id:
print procurement.rule_id.action
if procurement.rule_id and procurement.rule_id.action == 'buy':
#make a purchase order for the procurement
return self.make_po(cr, uid, [procurement.id], context=context)[procurement.id]

View File

@ -208,7 +208,7 @@
<notebook>
<page string="Products">
<field name="order_line">
<tree string="Purchase Order Lines" editable="bottom">
<tree string="Purchase Order Lines" editable="bottom" colors="grey:state=='cancel'">
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,parent.state,context)"/>
<field name="name"/>
<field name="date_planned"/>
@ -219,6 +219,7 @@
<field name="price_unit"/>
<field name="taxes_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
<field name="price_subtotal"/>
<field name="state" invisible="1"/>
</tree>
</field>
<group class="oe_subtotal_footer oe_right">
@ -550,7 +551,7 @@
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='origin']" position="after">
<field name="purchase_line_id"/>
<field name="purchase_id"/>
</xpath>
</field>
</record>

View File

@ -40,19 +40,35 @@ class stock_move(osv.osv):
workflow.trg_trigger(uid, 'stock.move', id, cr)
return res
#
# Inherit of picking to add the link to the PO
#
class stock_picking(osv.osv):
_inherit = 'stock.picking'
def _get_to_invoice(self, cr, uid, ids, name, args, context=None):
res = {}
for picking in self.browse(cr, uid, ids, context=context):
res[picking.id] = False
for move in picking.move_lines:
if move.purchase_line_id and move.purchase_line_id.order_id.invoice_method == 'picking':
if not move.move_orig_ids:
res[picking.id] = True
return res
def _get_picking_to_recompute(self, cr, uid, ids, context=None):
picking_ids = set()
for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context):
if move.picking_id:
picking_ids.add(move.picking_id.id)
return list(picking_ids)
_columns = {
'purchase_id': fields.many2one('purchase.order', 'Purchase Order',
ondelete='set null', select=True),
'reception_to_invoice': fields.function(_get_to_invoice, type='boolean', string='Invoiceable on incoming shipment?',
help='Does the picking contains some moves related to a purchase order invoiceable on the reception?',
store={
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 10),
'stock.move': (_get_picking_to_recompute, ['purchase_line_id', 'picking_id'], 10),
}),
}
_defaults = {
'purchase_id': False,
}
# TODO: Invoice based on receptions
# Here is how it should work:

View File

@ -12,24 +12,13 @@
</field>
</record>
<record id="stock_picking_in_inherit_purchase" model="ir.ui.view">
<field name="name">Picking Inherited</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='move_type']" position="before">
<field name="purchase_id" domain="[('invoice_method','=','picking')]" groups="base.group_no_one" context="{'search_default_partner_id':partner_id,'default_partner_id':partner_id, 'default_invoice_method':'picking'}"/>
</xpath>
</field>
</record>
<record id="view_picking_in_search_picking_inherit" model="ir.ui.view">
<field name="name">stock.picking.in.search.inherit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='product_id']" position="before">
<field name="purchase_id"/>
<filter name="reception_to_invoice" string="Incoming Shipments to Invoice" domain="[('reception_to_invoice', '=', True)]"/>
</xpath>
</field>
</record>
@ -71,8 +60,7 @@
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="domain">[('purchase_id.invoice_method','=','picking')]</field>
<field name="context">{"default_type": "in", "contact_display": "partner_address", "search_default_done": 1, "search_default_to_invoice": 1}</field>
<field name="context">{"default_type": "in", "contact_display": "partner_address", "search_default_done": 1, "search_default_reception_to_invoice": 1}</field>
<field name="search_view_id" ref="stock.view_picking_internal_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">

View File

@ -85,15 +85,14 @@ class sale_order(osv.osv):
res[sale.id] = list(picking_ids)
return res
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id = False, context=None):
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
vals = super(sale_order, self)._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
location_id = order.partner_shipping_id.property_stock_customer.id
vals['location_id'] = location_id
routes = []
routes += order.warehouse_id and [(4, x.id) for x in order.warehouse_id.route_ids] or [] #route_ids
routes += line.route_id and [(4, line.route_id.id)] or [] #route_id
vals['route_ids'] = routes
routes = line.route_id and [(4, line.route_id.id)] or []
vals['route_ids'] = routes
vals['warehouse_id'] = order.warehouse_id and order.warehouse_id.id or False
return vals
_columns = {
@ -329,7 +328,7 @@ class sale_order_line(osv.osv):
return {'value': result, 'warning': warning}
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
def product_id_change_with_wh(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, warehouse_id=False, context=None):
context = context or {}

View File

@ -29,16 +29,27 @@
<field name="client_order_ref" position="after">
<field name="warehouse_id" on_change="onchange_warehouse_id(warehouse_id)" widget="selection" groups="stock.group_locations"/>
</field>
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='product_id']" position="replace">
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="replace">
<field name="product_id"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
groups="base.group_user"
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, parent.warehouse_id, context)"/>
on_change="product_id_change_with_wh(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, parent.warehouse_id, context)"/>
</xpath>
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='product_uom_qty']" position="replace">
<xpath expr="//field[@name='order_line']/tree//field[@name='product_uom_qty']" position="replace">
<field context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
name="product_uom_qty"
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, product_packaging, parent.fiscal_position, True, parent.warehouse_id, context)"/>
on_change="product_id_change_with_wh(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, product_packaging, parent.fiscal_position, True, parent.warehouse_id, context)"/>
</xpath>
<xpath expr="//field[@name='order_line']/form//field[@name='product_id']" position="replace">
<field name="product_id"
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
groups="base.group_user"
on_change="product_id_change_with_wh(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, parent.warehouse_id, context)"/>
</xpath>
<xpath expr="//field[@name='order_line']/form//field[@name='product_uom_qty']" position="replace">
<field context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
name="product_uom_qty"
on_change="product_id_change_with_wh(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, False, False, parent.date_order, product_packaging, parent.fiscal_position, True, parent.warehouse_id, context)"/>
</xpath>
<field name='invoiced' position="after">

View File

@ -66,23 +66,23 @@ class procurement_rule(osv.osv):
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."),
'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),
'procurement.rule': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 10),
}),
'sequence': fields.integer('Sequence'),
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type',
'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, ..."),
'active': fields.related('route_id', 'active', type='boolean', string='Active', store={
'stock.location.route': (_get_route, ['active'], 20),
'procurement.rule': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 20),},
help="If the active field is set to False, it will allow you to hide the rule without removing it." ),
'procurement.rule': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 20)},
help="If the active field is set to False, it will allow you to hide the rule without removing it."),
'delay': fields.integer('Number of Days'),
'partner_address_id': fields.many2one('res.partner', 'Partner Address'),
'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'),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
}
_defaults = {
@ -100,9 +100,24 @@ class procurement_order(osv.osv):
'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"),
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"),
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Followed Route', help="Preferred route to be followed by the procurement order"),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', help="Warehouse to consider for the route selection"),
}
def propagate_cancel(self, cr, uid, procurement, context=None):
if procurement.rule_id.action == 'move' and procurement.move_ids:
self.pool.get('stock.move').action_cancel(cr, uid, [m.id for m in procurement.move_ids], context=context)
def cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
ctx = context.copy()
#set the context for the propagation of the procurement cancelation
ctx['cancel_procurement'] = True
for procurement in self.browse(cr, uid, ids, context=ctx):
if procurement.rule_id and procurement.rule_id.propagate:
self.propagate_cancel(cr, uid, procurement, context=ctx)
return super(procurement_order, self).cancel(cr, uid, ids, context=ctx)
def _find_parent_locations(self, cr, uid, procurement, context=None):
location = procurement.location_id
res = [location.id]
@ -111,15 +126,28 @@ class procurement_order(osv.osv):
res.append(location.id)
return res
def change_warehouse_id(self, cr, uid, ids, warehouse_id, context=None):
if warehouse_id:
warehouse = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context=context)
return {'value': {'location_id': warehouse.lot_stock_id.id}}
return {}
def _search_suitable_rule(self, cr, uid, procurement, domain, context=None):
'''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'''
pull_obj = self.pool.get('procurement.rule')
warehouse_route_ids = []
if procurement.warehouse_id:
domain += [('warehouse_id', '=', procurement.warehouse_id.id)]
warehouse_route_ids = [x.id for x in procurement.warehouse_id.route_ids]
product_route_ids = [x.id for x in procurement.product_id.route_ids + procurement.product_id.categ_id.total_route_ids]
procurement_route_ids = [x.id for x in procurement.route_ids]
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', product_route_ids)], order = 'route_sequence, sequence', context=context)
res = pull_obj.search(cr, uid, domain + [('route_id', 'in', procurement_route_ids)], order='route_sequence, sequence', context=context)
if not res:
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', procurement_route_ids)], order = 'route_sequence, sequence', context=context)
res = pull_obj.search(cr, uid, domain + [('route_id', 'in', product_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)
res = warehouse_route_ids and pull_obj.search(cr, uid, domain + [('route_id', 'in', warehouse_route_ids)], order='route_sequence, sequence', context=context) or []
if not res:
res = pull_obj.search(cr, uid, domain + [('route_id', '=', False)], order='sequence', context=context)
return res
def _find_suitable_rule(self, cr, uid, procurement, context=None):
@ -157,6 +185,7 @@ class procurement_order(osv.osv):
'picking_type_id': procurement.rule_id.picking_type_id.id,
'group_id': procurement.group_id and procurement.group_id.id or False,
'route_ids': [(4, x.id) for x in procurement.route_ids],
'warehouse_id': procurement.rule_id.warehouse_id.id,
}
if procurement.rule_id:
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')

View File

@ -664,7 +664,11 @@ class stock_picking(osv.osv):
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),#?
'location_id': fields.related('move_lines', 'location_id', type='many2one', relation='stock.location', string='Location', readonly=True),
'location_dest_id': fields.related('move_lines', 'location_dest_id', type='many2one', relation='stock.location', string='Destination Location', readonly=True),
'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True),
'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True,
store={
'stock.picking': (lambda self, cr, uid, ids, ctx: ids, ['move_lines'], 10),
'stock.move': (_get_pickings, ['group_id', 'picking_id'], 10),
}),
}
_defaults = {
@ -1310,7 +1314,7 @@ class stock_move(osv.osv):
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Optional: next stock move when chaining them", select=True),
'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: previous stock move when chaining them", select=True),
'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
'picking_id': fields.many2one('stock.picking', 'Reference', select=True, states={'done': [('readonly', True)]}),
'picking_priority': fields.related('picking_id','priority', type='selection', selection=[('0','Low'),('1','Normal'),('2','High')], string='Picking Priority'),
'note': fields.text('Notes'),
'state': fields.selection([('draft', 'New'),
@ -1356,6 +1360,7 @@ class stock_move(osv.osv):
'restrict_partner_id': fields.many2one('res.partner', 'Owner ', help="Technical field used to depict a restriction on the ownership of quants to consider when marking this move as 'done'"),
'putaway_ids': fields.one2many('stock.move.putaway', 'move_id', 'Put Away Suggestions'),
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_move', 'move_id', 'route_id', 'Destination route', help="Preferred route to be followed by the procurement order"),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', help="Technical field depicting the warehouse to consider for the route selection on the next procurement (if any)."),
}
def copy(self, cr, uid, id, default=None, context=None):
@ -1420,6 +1425,7 @@ class stock_move(osv.osv):
'move_dest_id': move.id,
'group_id': move.group_id and move.group_id.id or False,
'route_ids' : [(4, x.id) for x in move.route_ids],
'warehouse_id': move.warehouse_id and move.warehouse_id.id or False,
}
def _push_apply(self, cr, uid, moves, context):
@ -1429,7 +1435,10 @@ class stock_move(osv.osv):
routes = [x.id for x in move.product_id.route_ids + move.product_id.categ_id.total_route_ids]
routes = routes or [x.id for x in move.route_ids]
if routes:
rules = push_obj.search(cr, uid, [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)], context=context)
domain = [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)]
if move.warehouse_id:
domain += [('warehouse_id', '=', move.warehouse_id.id)]
rules = push_obj.search(cr, uid, domain, context=context)
if rules:
rule = push_obj.browse(cr, uid, rules[0], context=context)
push_obj._apply(cr, uid, rule, move, context=context)
@ -1591,7 +1600,7 @@ class stock_move(osv.osv):
('group_id', '=', group),
('location_id', '=', move.location_id.id),
('location_dest_id', '=', move.location_dest_id.id),
('state', 'in', ['confirmed', 'waiting'])], context=context)
('state', 'in', ['draft', 'confirmed', 'waiting'])], context=context)
if picks:
pick = picks[0]
else:
@ -1700,6 +1709,7 @@ class stock_move(osv.osv):
""" Cancels the moves and if all moves are cancelled it cancels the picking.
@return: True
"""
procurement_obj = self.pool.get('procurement.order')
context = context or {}
for move in self.browse(cr, uid, ids, context=context):
if move.state == 'done':
@ -1707,7 +1717,12 @@ class stock_move(osv.osv):
_('You cannot cancel a stock move that has been set to \'Done\'.'))
if move.reserved_quant_ids:
self.pool.get("stock.quant").quants_unreserve(cr, uid, move, context=context)
if move.move_dest_id:
if context.get('cancel_procurement'):
if move.propagate:
procurement_ids = procurement_obj.search(cr, uid, [('move_dest_id', '=', move.id)], context=context)
procurement_obj.cancel(cr, uid, procurement_ids, context=context)
elif move.move_dest_id:
#cancel chained moves
if move.propagate:
self.action_cancel(cr, uid, [move.move_dest_id.id], context=context)
elif move.move_dest_id.state == 'waiting':
@ -2236,6 +2251,7 @@ class stock_warehouse(osv.osv):
'name': fields.char('Name', size=128, required=True, select=True),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
'partner_id': fields.many2one('res.partner', 'Address'),
'view_location_id': fields.many2one('stock.location', 'View Location', required=True, domain=[('usage', '=', 'view')]),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]),
'code': fields.char('Short Name', size=5, required=True, help="Short name used to identify your warehouse"),
'route_ids': fields.many2many('stock.location.route', 'stock_route_warehouse', 'warehouse_id', 'route_id', 'Routes', domain="[('warehouse_selectable', '=', True)]", help='Defaults routes through the warehouse'),
@ -2415,6 +2431,7 @@ class stock_warehouse(osv.osv):
'auto': 'manual',
'picking_type_id': pick_type_id,
'active': active,
'warehouse_id': warehouse.id,
})
pull_rules_list.append({
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
@ -2425,6 +2442,7 @@ class stock_warehouse(osv.osv):
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'active': active,
'warehouse_id': warehouse.id,
})
first_rule = False
return push_rules_list, pull_rules_list
@ -2449,6 +2467,7 @@ class stock_warehouse(osv.osv):
'picking_type_id': pick_type_id,
'procure_method': 'make_to_order',
'active': True,
'warehouse_id': warehouse.id,
}
def _get_crossdock_route(self, cr, uid, warehouse, route_name, context=None):
@ -2458,6 +2477,7 @@ class stock_warehouse(osv.osv):
'product_selectable': True,
'product_categ_selectable': True,
'active': warehouse.delivery_steps != 'ship_only' and warehouse.reception_steps != 'one_step',
'sequence': 20,
}
def create_routes(self, cr, uid, ids, warehouse, context=None):
@ -2476,6 +2496,8 @@ class stock_warehouse(osv.osv):
for push_rule in push_rules_list:
push_obj.create(cr, uid, vals=push_rule, context=context)
for pull_rule in pull_rules_list:
#all pull rules in reception route are mto, because we don't won't to wait for the scheduler to trigger an orderpoint on input location
pull_rule['procure_method'] = 'make_to_order'
pull_obj.create(cr, uid, vals=pull_rule, context=context)
#create MTS route and pull rules for delivery a specific route MTO to be set on the product
@ -2580,6 +2602,7 @@ class stock_warehouse(osv.osv):
'usage': 'view',
'location_id': data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_locations')[1]
}, context=context)
vals['view_location_id'] = wh_loc_id
#create all location
reception_steps = vals.get('reception_steps', False)
delivery_steps = vals.get('delivery_steps', False)
@ -2868,6 +2891,7 @@ class stock_location_path(osv.osv):
'stock.location.route': (_get_route, ['active'], 20),
'stock.location.path': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 20),},
help="If the active field is set to False, it will allow you to hide the rule without removing it." ),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
}
_defaults = {
'auto': 'auto',
@ -2899,6 +2923,7 @@ class stock_location_path(osv.osv):
'picking_type_id': rule.picking_type_id and rule.picking_type_id.id or False,
'rule_id': rule.id,
'propagate': rule.propagate,
'warehouse_id': rule.warehouse_id and rule.warehouse_id.id or False,
})
move_obj.write(cr, uid, [move.id], {
'move_dest_id': move_id,

View File

@ -129,9 +129,9 @@
</group>
<group>
<field name="product_id" domain="[('type','=','product')]" attrs="{'invisible': [('filter', 'not in', ('product', 'product_owner'))]}"/>
<field name="lot_id" attrs="{'invisible': [('filter', '!=', 'lot')]}"/>
<field name="partner_id" attrs="{'invisible': [('filter', 'not in', ('owner', 'product_owner'))]}"/>
<field name="package_id" attrs="{'invisible': [('filter', '!=', 'pack')]}"/>
<field name="lot_id" attrs="{'invisible': [('filter', '!=', 'lot')]}" groups="stock.group_production_lot" />
<field name="partner_id" attrs="{'invisible': [('filter', 'not in', ('owner', 'product_owner'))]}" groups="stock.group_tracking_owner"/>
<field name="package_id" attrs="{'invisible': [('filter', '!=', 'pack')]}" groups="stock.group_tracking_lot"/>
</group>
</group>
<notebook attrs="{'invisible':[('state','=','draft')]}">
@ -142,9 +142,9 @@
<field context="{'location':location_id, 'uom':product_uom_id, 'to_date':parent.date}" name="product_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)" domain="[('type','=','product')]"/>
<field name="product_uom_id" groups="product.group_uom" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)"/>
<field domain="[('usage','=','internal')]" name="location_id" groups="stock.group_locations" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)"/>
<field name="prod_lot_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)" domain="[('product_id', '=', product_id)]" context="{'default_product_id': product_id}"/>
<field name="package_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)"/>
<field name="partner_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)"/>
<field name="prod_lot_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)" domain="[('product_id', '=', product_id)]" context="{'default_product_id': product_id}" groups="stock.group_production_lot"/>
<field name="package_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)" groups="stock.group_tracking_lot"/>
<field name="partner_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,partner_id,prod_lot_id,package_id)" groups="stock.group_tracking_owner"/>
<field name="th_qty" readonly="1"/>
<field name="product_qty" string="Checked Quantity"/>
<field name="state" invisible="True"/>
@ -754,6 +754,7 @@
<field name="state"/>
<field name="priority"/>
<field name="picking_type_id" invisible="1"/>
<field name="group_id" invisible="1"/>
</tree>
</field>
</record>
@ -865,6 +866,7 @@
<filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'min_date'}"/>
<filter string="Origin" domain="[]" context="{'group_by':'origin'}"/>
<filter string="Picking Type" domain="[]" context="{'group_by':'picking_type_id'}"/>
<filter string="Procurement Group" domain="[]" context="{'group_by':'group_id'}"/>
</group>
</search>
</field>
@ -1670,7 +1672,8 @@
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='origin']" position="after">
<field name="location_id"/>
<field name="warehouse_id" on_change="change_warehouse_id(warehouse_id, context)"/>
<field name="location_id" domain="[('usage', '=', 'internal')]"/>
</xpath>
<xpath expr="//field[@name='rule_id']" position="after">
<field name="route_ids" widget="many2many_tags"/>
@ -1765,20 +1768,19 @@
<search string="Quants">
<field name="product_id"/>
<field name="location_id"/>
<field name="package_id"/>
<field name="lot_id"/>
<field name="owner_id"/>
<field name="package_id" groups="stock.group_tracking_lot"/>
<field name="lot_id" groups="stock.group_production_lot"/>
<field name="owner_id" groups="stock.group_tracking_owner"/>
<group expand='0' string='Filters'>
<filter name='internal_loc' string="Internal Locations" domain="[('location_id.usage','=', 'internal')]"/>
</group>
<group expand='0' string='Group by...'>
<filter name="productgroup" string='Product' context="{'group_by' : 'product_id'}"/>
<filter string='Owner' context="{'group_by' : 'owner_id'}"/>
<filter string='Lot' context="{'group_by' : 'lot_id'}"/>
<filter string='Owner' context="{'group_by' : 'owner_id'}" groups="stock.group_tracking_owner"/>
<filter string='Lot' context="{'group_by' : 'lot_id'}" groups="stock.group_production_lot"/>
<filter name="locationgroup" string='Location' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'location_id'}"/>
<filter string='Packaging' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'package_id'}"/>
<filter string='Packaging Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'packaging_type_id'}"/>
<filter name="partnergroup" string='Partner' domain="[]" context="{'group_by': 'partner_id'}"/>
<filter string='Packaging' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'package_id'}" groups="stock.group_tracking_lot"/>
<filter string='Packaging Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'packaging_type_id'}" groups="stock.group_tracking_lot"/>
<filter string='Company' icon="terp-go-home" domain="[]" context="{'group_by' : 'company_id'}" groups="base.group_multi_company"/>
</group>
</search>
@ -1799,14 +1801,14 @@
<form string="Quants">
<field name="product_id"/>
<field name="qty"/>
<field name="lot_id"/>
<field name="package_id"/>
<field name="lot_id" groups="stock.group_production_lot"/>
<field name="package_id" groups="stock.group_tracking_lot"/>
<field name="location_id"/>
<field name="in_date"/>
<field name="reservation_id"/>
<field name="propagated_from_id"/>
<field name="history_ids"/>
<field name="owner_id"/>
<field name="owner_id" groups="stock.group_tracking_owner"/>
</form>
</field>
</record>
@ -1821,9 +1823,9 @@
<field name="product_id"/>
<field name="qty"/>
<field name="location_id"/>
<field name="owner_id"/>
<field name="lot_id"/>
<field name="package_id"/>
<field name="owner_id" groups="stock.group_tracking_owner"/>
<field name="lot_id" groups="stock.group_production_lot"/>
<field name="package_id" groups="stock.group_tracking_lot"/>
<field name="packaging_type_id" invisible="1"/>
<field name="in_date"/>
<field name="reservation_id" invisible='1'/>
@ -2132,17 +2134,6 @@
<menuitem action="action_routes_form" id="menu_stock_routes"
parent="stock.menu_stock_configuration" sequence="11" />
<record id="procurement_form_view_inherit" model="ir.ui.view">
<field name="name">procurement.order.form.view.inherit</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="model">procurement.order</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='rule_id']" position="after">
<field name="route_ids" widget="many2many_tags" />
</xpath>
</field>
</record>
<record id="view_product_procurement_rule_form" model="ir.ui.view">
<field name="name">product.template.procurement.rule.inherit</field>

View File

@ -71,8 +71,9 @@
-
!python {model: stock.picking}: |
po_id = self.pool.get('purchase.order').search(cr, uid, [('partner_id', '=', ref('supplier_dropship'))])
picking_id = self.search(cr, uid, [('purchase_id', '=', po_id[0])])
self.do_partial(cr, uid, picking_id)
assert po_id and len(po_id) == 1, 'Problem with the Purchase Order detected'
picking_ids = [pick.id for pick in self.pool.get('purchase.order').browse(cr, uid, po_id[0]).picking_ids]
self.do_partial(cr, uid, picking_ids)
-
Check one quant was created in Customers location with 200 pieces and one move in the history_ids
-

View File

@ -32,7 +32,7 @@ Warning messages can be displayed for objects like sale order, purchase order,
picking and invoice. The message is triggered by the form's onchange event.
""",
'author': 'OpenERP SA',
'depends': ['base', 'sale', 'purchase'],
'depends': ['base', 'sale_stock', 'purchase'],
'data': ['warning_view.xml'],
'demo': [],
'installable': True,

View File

@ -170,8 +170,6 @@ class stock_picking(osv.osv):
return {'value': result.get('value',{}), 'warning':warning}
# FIXME:(class stock_picking_in and stock_picking_out) this is a temporary workaround because of a framework bug (ref: lp:996816).
# It should be removed as soon as the bug is fixed
class stock_picking(osv.osv):
_inherit = 'stock.picking'
@ -215,10 +213,10 @@ class product_product(osv.osv):
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
def product_id_change_with_wh(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False, packaging=False,
fiscal_position=False, flag=False, context=None):
fiscal_position=False, flag=False, warehouse_id=False, context=None):
warning = {}
if not product:
return {'value': {'th_weight' : 0, 'product_packaging': False,
@ -237,9 +235,9 @@ class sale_order_line(osv.osv):
warning['title'] = title
warning['message'] = message
result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty,
result = super(sale_order_line, self).product_id_change_with_wh( cr, uid, ids, pricelist, product, qty,
uom, qty_uos, uos, name, partner_id,
lang, update_tax, date_order, packaging, fiscal_position, flag, context=context)
lang, update_tax, date_order, packaging, fiscal_position, flag, warehouse_id=warehouse_id, context=context)
if result.get('warning',False):
warning['title'] = title and title +' & '+result['warning']['title'] or result['warning']['title']