[MERGE] merged with main branch
bzr revid: qdp-launchpad@openerp.com-20131023122842-d4yxulpthx4qa9q5
This commit is contained in:
commit
f2b9d8f05f
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
-
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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']
|
||||
|
|
Loading…
Reference in New Issue