diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py
index 6f2d2a07ca0228956279219811d0528db793d1fc..7bfd52df4201bbaaee114ea96a71db186447e344 100644
--- a/addons/delivery/stock.py
+++ b/addons/delivery/stock.py
@@ -56,13 +56,13 @@ class stock_picking(osv.osv):
         'volume': fields.float('Volume'),
         'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
                   store={
-                 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
-                 'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
+                 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 40),
+                 'stock.move': (_get_picking_line, ['picking_id', 'product_id','product_uom_qty','product_uom'], 40),
                  }),
         'weight_net': fields.function(_cal_weight, type='float', string='Net Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
                   store={
-                 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
-                 'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
+                 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 40),
+                 'stock.move': (_get_picking_line, ['picking_id', 'product_id','product_uom_qty','product_uom'], 40),
                  }),
         'carrier_tracking_ref': fields.char('Carrier Tracking Ref'),
         'number_of_packages': fields.integer('Number of Packages'),
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 5add8703614db9e63f67e80cfad0a6ae21f2865d..db62e265430ebffbb81347ece0799c0fb0610540 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -1074,12 +1074,13 @@ class mrp_production(osv.osv):
         type_obj = self.pool.get('stock.picking.type')
         # Need to search for a picking type
         move = stock_move.browse(cr, uid, move_id, context=context)
-        code = stock_move.get_code_from_locs(cr, uid, move, context=context)
+        src_loc = loc_obj.browse(cr, uid, source_location_id, context=context)
+        dest_loc = loc_obj.browse(cr, uid, dest_location_id, context=context)
+        code = stock_move.get_code_from_locs(cr, uid, move, src_loc, dest_loc, context=context)
         if code == 'outgoing':
-            check_loc_id = source_location_id
+            check_loc = src_loc
         else:
-            check_loc_id = dest_location_id
-        check_loc = loc_obj.browse(cr, uid, check_loc_id, context=context)
+            check_loc = dest_loc
         wh = loc_obj.get_warehouse(cr, uid, check_loc, context=context)
         domain = [('code', '=', code)]
         if wh: 
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index 482f31b22ebfcbbb7ee3ae36de9bffbc11776580..4dd3f47776df1e2dadf19e5591610cb9a68dd2e5 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -113,6 +113,9 @@
                                         <field digits="(14, 3)" name="weight_net"/>
                                     </group>
                                 </group>
+                                <group name="packaging" string="Packaging" attrs="{'invisible':[('type','=','service')]}" groups="product.group_stock_packaging" colspan="4">
+                                    <field name="packaging_ids" string="Configurations" context="{'tree_view_ref':'product.product_packaging_tree_view_product', 'form_view_ref': 'product.product_packaging_form_view_without_product'}"/>
+                                </group>
                             </page>
                             <page string="Sales" attrs="{'invisible':[('sale_ok','=',False)]}" name="sales">
                                 <group name="sale">
@@ -704,6 +707,7 @@
             <field name="arch" type="xml">
                 <tree string="Packaging">
                     <field name="sequence" widget="handle"/>
+                    <field name="product_tmpl_id"/>
                     <field name="ean"/>
                     <field name="qty"/>
                     <field name="ul"/>
@@ -712,6 +716,20 @@
             </field>
         </record>
 
+        <record id="product_packaging_tree_view_product" model="ir.ui.view">
+            <field name="name">product.packaging.tree.view.product</field>
+            <field name="model">product.packaging</field>
+            <field name="arch" type="xml">
+                <tree string="Packaging">
+                    <field name="qty"/>
+                    <field name="ul"/>
+                    <field name="ul_qty"/>
+                    <field name="rows"/>
+                    <field name="ul_container"/>
+                </tree>
+            </field>
+        </record>
+
         <record id="product_packaging_form_view" model="ir.ui.view">
             <field name="name">product.packaging.form.view</field>
             <field name="model">product.packaging</field>
@@ -737,6 +755,29 @@
             </field>
         </record>
 
+        <record id="product_packaging_form_view_without_product" model="ir.ui.view">
+            <field name="name">product.packaging.form.view.without.product</field>
+            <field name="model">product.packaging</field>
+            <field name="arch" type="xml">
+                <form string="Packaging">
+                    <group col="4">
+                        <field name="ean"/>
+                        <field name="sequence" invisible="1"/>
+                        <newline/>
+                        <field name="qty"/>
+                        <field name="ul"/>
+                        <separator colspan="4" string="Palletization"/>
+                        <field name="ul_qty"/>
+                        <field name="rows"/>
+                        <field name="ul_container"/>
+                        <field name="weight"/>
+                        <separator colspan="4" string="Other Info"/>
+                        <field colspan="4" name="name"/>
+                    </group>
+                </form>
+            </field>
+        </record>
+
         <record id="product_supplierinfo_form_view" model="ir.ui.view">
             <field name="name">product.supplierinfo.form.view</field>
             <field name="model">product.supplierinfo</field>
diff --git a/addons/sale_stock/sale_stock_view.xml b/addons/sale_stock/sale_stock_view.xml
index b754a8d0c7fc901f57f287074b9e1e74ceaa5a21..0d5223a03c88a46917ce380a1eed9fd11db1263b 100644
--- a/addons/sale_stock/sale_stock_view.xml
+++ b/addons/sale_stock/sale_stock_view.xml
@@ -64,7 +64,7 @@
                    </xpath>
                    <xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='tax_id']" position="before">
                        <field name="product_tmpl_id" invisible="1"/>
-                       <field name="product_packaging" context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}" on_change="product_packaging_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, parent.partner_id, product_packaging, True, context)" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging" /> 
+                       <field name="product_packaging" context="{'default_product_tmpl_id': product_tmpl_id, 'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}" on_change="product_packaging_change(parent.pricelist_id, product_id, product_uom_qty, product_uom, parent.partner_id, product_packaging, True, context)" domain="[('product_tmpl_id','=',product_tmpl_id)]" groups="product.group_stock_packaging" />
                    </xpath>
                    <xpath expr="//page[@string='Order Lines']/field[@name='order_line']/tree[@string='Sales Order Lines']/field[@name='sequence']" position="after">
                        <field name="delay" invisible="1"/>
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 9e3c8cf69ea0e372c58ce5e47b1d2e111ab6becf..973136c1ed7e877a5fab9320ac96a57626e3eae5 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -383,7 +383,7 @@ class stock_quant(osv.osv):
             self.pool.get('stock.move').write(cr, uid, [move.id], {'partially_available': True}, context=context)
 
     def quants_move(self, cr, uid, quants, move, location_to, location_from=False, lot_id=False, owner_id=False, src_package_id=False, dest_package_id=False, context=None):
-        """Moves all given stock.quant in the given destination location.
+        """Moves all given stock.quant in the given destination location.  Unreserve from current move.
         :param quants: list of tuple(browse record(stock.quant) or None, quantity to move)
         :param move: browse record (stock.move)
         :param location_to: browse record (stock.location) depicting where the quants have to be moved
@@ -418,7 +418,8 @@ class stock_quant(osv.osv):
     def move_quants_write(self, cr, uid, quants, move, location_dest_id, dest_package_id, context=None):
         vals = {'location_id': location_dest_id.id,
                 'history_ids': [(4, move.id)],
-                'package_id': dest_package_id}
+                'package_id': dest_package_id,
+                'reservation_id': False}
         self.write(cr, SUPERUSER_ID, [q.id for q in quants], vals, context=context)
 
     def quants_get_prefered_domain(self, cr, uid, location, product, qty, domain=None, prefered_domain_list=[], restrict_lot_id=False, restrict_partner_id=False, context=None):
@@ -2242,7 +2243,7 @@ class stock_move(osv.osv):
                 self.write(cr, uid, [move.id], vals, context=context)
 
     def action_done(self, cr, uid, ids, context=None):
-        """ Process completly the moves given as ids and if all moves are done, it will finish the picking.
+        """ Process completely the moves given as ids and if all moves are done, it will finish the picking.
         """
         context = context or {}
         picking_obj = self.pool.get("stock.picking")
@@ -2293,6 +2294,7 @@ class stock_move(osv.osv):
                     self.pool.get('stock.quant.package').write(cr, SUPERUSER_ID, [ops.package_id.id], {'parent_id': ops.result_package_id.id}, context=context)
                 move_qty[move.id] -= record.qty
         #Check for remaining qtys and unreserve/check move_dest_id in
+        move_dest_ids = set()
         for move in self.browse(cr, uid, ids, context=context):
             if move_qty[move.id] > 0:  # (=In case no pack operations in picking)
                 main_domain = [('qty', '>', 0)]
@@ -2304,27 +2306,24 @@ class stock_move(osv.osv):
                 qty = move_qty[move.id]
                 quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=main_domain, prefered_domain_list=prefered_domain_list, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context)
                 quant_obj.quants_move(cr, uid, quants, move, move.location_dest_id, lot_id=move.restrict_lot_id.id, owner_id=move.restrict_partner_id.id, context=context)
-            #unreserve the quants and make them available for other operations/moves
-            quant_obj.quants_unreserve(cr, uid, move, context=context)
 
-            #Check moves that were pushed
-            if move.move_dest_id.state in ('waiting', 'confirmed'):
-                # FIXME is opw 607970 still present with new WMS?
-                # (see commits 1ef2c181033bd200906fb1e5ce35e234bf566ac6
-                # and 41c5ceb8ebb95c1b4e98d8dd1f12b8e547a24b1d)
-                other_upstream_move_ids = self.search(cr, uid, [('id', '!=', move.id), ('state', 'not in', ['done', 'cancel']),
-                                            ('move_dest_id', '=', move.move_dest_id.id)], context=context)
-                #If no other moves for the move that got pushed:
-                if not other_upstream_move_ids and move.move_dest_id.state in ('waiting', 'confirmed'):
-                    self.action_assign(cr, uid, [move.move_dest_id.id], context=context)
+            # If the move has a destination, add it to the list to reserve
+            if move.move_dest_id and move.move_dest_id.state in ('waiting', 'confirmed'):
+                move_dest_ids.add(move.move_dest_id.id)
+
             if move.procurement_id:
                 procurement_ids.append(move.procurement_id.id)
 
+            #unreserve the quants and make them available for other operations/moves
+            quant_obj.quants_unreserve(cr, uid, move, context=context)
         # Check the packages have been placed in the correct locations
         self._check_package_from_moves(cr, uid, ids, context=context)
         #set the move as done
         self.write(cr, uid, ids, {'state': 'done', 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
         self.pool.get('procurement.order').check(cr, uid, procurement_ids, context=context)
+        #assign destination moves
+        if move_dest_ids:
+            self.action_assign(cr, uid, list(move_dest_ids), context=context)
         #check picking state to set the date_done is needed
         done_picking = []
         for picking in picking_obj.browse(cr, uid, list(pickings), context=context):
@@ -2443,14 +2442,15 @@ class stock_move(osv.osv):
         return self.action_confirm(cr, uid, [new_move], context=context)[0]
 
 
-    def get_code_from_locs(self, cr, uid, move, context=None):
+    def get_code_from_locs(self, cr, uid, move, location_id=False, location_dest_id=False, context=None):
         """
         Returns the code the picking type should have.  This can easily be used
         to check if a move is internal or not
+        move, location_id and location_dest_id are browse records
         """
         code = 'internal'
-        src_loc = move.location_id
-        dest_loc = move.location_dest_id
+        src_loc = location_id or move.location_id
+        dest_loc = location_dest_id or move.location_dest_id
         if src_loc.usage == 'internal' and dest_loc.usage != 'internal':
             code = 'outgoing'
         if src_loc.usage != 'internal' and dest_loc.usage == 'internal':
diff --git a/addons/stock/test/packing.yml b/addons/stock/test/packing.yml
index b889d93419d2eaeba91c0fbdcccebe6ed4d101e3..22be2e8222014c2b6a364d3d783fbf5c0224588d 100644
--- a/addons/stock/test/packing.yml
+++ b/addons/stock/test/packing.yml
@@ -138,13 +138,13 @@
   !python {model: stock.picking}: |
     backorder_ids = self.search(cr, uid, [('backorder_id', '=', ref('delivery_order1'))], context=context)
     assert backorder_ids, "Backorder should have been created"
+    self.action_assign(cr, uid, backorder_ids, context=context)
     self.do_prepare_partial(cr, uid, backorder_ids, context=context)
     picking = self.browse(cr, uid, backorder_ids[0])
     assert len(picking.pack_operation_ids) == 2, "Wrong number of pack operation"
     for pack_op in picking.pack_operation_ids:
         assert pack_op.product_qty == 1, "Wrong quantity in pack operation (%s found instead of 1)" % (pack_op.product_qty)
         assert pack_op.package_id.name in ('Pallet 2', 'Pallet 3'), "Wrong pallet info in pack operation (%s found)" % (pack_op.package_id.name)
-    self.action_assign(cr, uid, backorder_ids, context=context)
     self.do_transfer(cr, uid, backorder_ids, context=context)
 - 
   Check there are still 0 pieces in stock