diff --git a/addons/account/wizard/account_chart.py b/addons/account/wizard/account_chart.py
index 38df2f7484dd2971ecbf321357cd33bfd14a2d79..1fbfc6debd66abe85931dba471afa82a27957391 100644
--- a/addons/account/wizard/account_chart.py
+++ b/addons/account/wizard/account_chart.py
@@ -51,7 +51,7 @@ class account_chart(osv.osv_memory):
                                FROM account_period p
                                LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id)
                                WHERE f.id = %s
-                               ORDER BY p.date_start ASC
+                               ORDER BY p.date_start ASC, p.special DESC
                                LIMIT 1) AS period_start
                 UNION ALL
                 SELECT * FROM (SELECT p.id
diff --git a/addons/mrp/procurement.py b/addons/mrp/procurement.py
index 8b93e2a9bb6ea7128a48d1f2a1e359306c47d907..8c18023325f0b73970bad969e44072f3a6d3c2b4 100644
--- a/addons/mrp/procurement.py
+++ b/addons/mrp/procurement.py
@@ -24,6 +24,8 @@ from dateutil.relativedelta import relativedelta
 from openerp.osv import fields
 from openerp.osv import osv
 from openerp.tools.translate import _
+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
+
 
 class procurement_order(osv.osv):
     _inherit = 'procurement.order'
@@ -77,35 +79,43 @@ class procurement_order(osv.osv):
         res = procurement_obj.make_mo(cr, uid, ids, context=context)
         res = res.values()
         return len(res) and res[0] or 0
-    
+
+    def _get_date_planned(self, cr, uid, procurement, context=None):
+        format_date_planned = datetime.strptime(procurement.date_planned,
+                                                DEFAULT_SERVER_DATETIME_FORMAT)
+        date_planned = format_date_planned - relativedelta(days=procurement.product_id.produce_delay or 0.0)
+        date_planned = date_planned - relativedelta(days=procurement.company_id.manufacturing_lead)
+        return date_planned
+
+    def _prepare_mo_vals(self, cr, uid, procurement, context=None):
+        res_id = procurement.move_id.id
+        newdate = self._get_date_planned(cr, uid, procurement, context=context)
+        return {
+            'origin': procurement.origin,
+            'product_id': procurement.product_id.id,
+            'product_qty': procurement.product_qty,
+            'product_uom': procurement.product_uom.id,
+            'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
+            'product_uos': procurement.product_uos and procurement.product_uos.id or False,
+            'location_src_id': procurement.location_id.id,
+            'location_dest_id': procurement.location_id.id,
+            'bom_id': procurement.bom_id and procurement.bom_id.id or False,
+            'date_planned': newdate.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
+            'move_prod_id': res_id,
+            'company_id': procurement.company_id.id,
+        }
+
     def make_mo(self, cr, uid, ids, context=None):
         """ Make Manufacturing(production) order from procurement
         @return: New created Production Orders procurement wise 
         """
         res = {}
-        company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
         production_obj = self.pool.get('mrp.production')
         move_obj = self.pool.get('stock.move')
         procurement_obj = self.pool.get('procurement.order')
         for procurement in procurement_obj.browse(cr, uid, ids, context=context):
-            res_id = procurement.move_id.id
-            newdate = datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.product_id.produce_delay or 0.0)
-            newdate = newdate - relativedelta(days=company.manufacturing_lead)
-            produce_id = production_obj.create(cr, uid, {
-                'origin': procurement.origin,
-                'product_id': procurement.product_id.id,
-                'product_qty': procurement.product_qty,
-                'product_uom': procurement.product_uom.id,
-                'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
-                'product_uos': procurement.product_uos and procurement.product_uos.id or False,
-                'location_src_id': procurement.location_id.id,
-                'location_dest_id': procurement.location_id.id,
-                'bom_id': procurement.bom_id and procurement.bom_id.id or False,
-                'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
-                'move_prod_id': res_id,
-                'company_id': procurement.company_id.id,
-            })
-            
+            vals = self._prepare_mo_vals(cr, uid, procurement, context=context)
+            produce_id = production_obj.create(cr, uid, vals, context=context)
             res[procurement.id] = produce_id
             self.write(cr, uid, [procurement.id], {'state': 'running', 'production_id': produce_id})   
             bom_result = production_obj.action_compute(cr, uid,
diff --git a/addons/product/product.py b/addons/product/product.py
index 3937d8ed0925ac5796c7e18aea02d0c1c2719713..dec91506883b47dff22bf9863c7beab0d67d7cfd 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -637,11 +637,8 @@ class product_product(osv.osv):
         return result
 
     def _get_name_template_ids(self, cr, uid, ids, context=None):
-        result = set()
         template_ids = self.pool.get('product.product').search(cr, uid, [('product_tmpl_id', 'in', ids)])
-        for el in template_ids:
-            result.add(el)
-        return list(result)
+        return list(set(template_ids))
 
     _columns = {
         'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
diff --git a/addons/purchase/tests/__init__.py b/addons/purchase/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..295471b9aa3797f602ea47e7e35732cb26bf8c37
--- /dev/null
+++ b/addons/purchase/tests/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Business Applications
+#    Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import test_average_price
+
+checks = [
+    test_average_price,
+]
diff --git a/addons/purchase/tests/test_average_price.py b/addons/purchase/tests/test_average_price.py
new file mode 100644
index 0000000000000000000000000000000000000000..4cc4849a33e4007bb2ae612eba15aa53b4ece9d7
--- /dev/null
+++ b/addons/purchase/tests/test_average_price.py
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Business Applications
+#    Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+#from openerp.test.common import TransactionCase
+from datetime import date
+from openerp.tests import common
+from openerp import netsvc
+
+
+class TestAveragePrice(common.TransactionCase):
+    def setUp(self):
+        super(TestAveragePrice, self).setUp()
+        cr, uid, context = self.cr, self.uid, {}
+        self.ir_model_data = self.registry('ir.model.data')
+        self.product_product = self.registry('product.product')
+        self.purchase_order = self.registry('purchase.order')
+        self.purchase_order_line = self.registry('purchase.order.line')
+        self.pricelist = self.registry('product.pricelist')
+        self.stock_location = self.registry('stock.location')
+        self.stock_picking = self.registry('stock.picking')
+        self.stock_move = self.registry('stock.move')
+        self.stock_partial_move = self.registry('stock.partial.move')
+        self.stock_partial_move_line = self.registry('stock.partial.move.line')
+        self.partial_picking = self.registry('stock.partial.picking')
+        self.partial_picking_line = self.registry('stock.partial.picking.line')
+        change_product_qty = self.registry('stock.change.product.qty')
+
+        _, partner_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'res_partner_1')
+        _, pricelist_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'product', 'list0')
+        _, self.location_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock')
+        _, self.supplier_location_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_suppliers')
+        _, input_account_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'account', 'xfa')
+        _, output_account_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'account', 'xfa')
+        wf_service = netsvc.LocalService("workflow")
+
+        self.standard_price = 10
+        self.order_price_unit = 20
+        self.available_qty = 1
+        self.order_qty = 1
+        self.picking_qty = 1
+
+        self.product_id = self.product_product.create(cr, uid, {
+            'name': 'Average product',
+            'cost_method': 'average',
+            'valuation': 'real_time',
+            'property_stock_account_input': input_account_id,
+            'property_stock_account_output': output_account_id,
+        }, context=context)
+
+        self.product_product.do_change_standard_price(
+            cr, uid, [self.product_id], {
+                'new_price': self.standard_price,
+                'stock_input_account': input_account_id,
+                'stock_output_account': output_account_id})
+
+        change_product_qty_id = change_product_qty.create(
+            cr, uid, {
+                'location_id': self.location_id,
+                'new_quantity': self.available_qty,
+                'product_id': self.product_id})
+        change_product_qty.change_product_qty(
+            cr, uid, [change_product_qty_id], {
+                'active_model': 'product.product',
+                'active_id': self.product_id,
+                'active_ids': [self.product_id]})
+
+        self.po_01_id = self.purchase_order.create(cr, uid, {
+            'partner_id': partner_id,
+            'location_id': self.location_id,
+            'pricelist_id': pricelist_id,
+        }, context=context)
+
+        self.order_line_10 = self.purchase_order_line.create(cr, uid, {
+            'order_id': self.po_01_id,
+            'product_id': self.product_id,
+            'name': 'description',
+            'date_planned': date.today(),
+            'product_qty': self.order_qty,
+            'price_unit': self.order_price_unit
+        }, context=context)
+
+        wf_service.trg_validate(uid, 'purchase.order', self.po_01_id, 'purchase_confirm', cr)
+
+
+    def test_10_stock_move_action_done(self):
+        cr, uid, context = self.cr, self.uid, {}
+        picking_id = self.purchase_order.read(cr, uid, [self.po_01_id], ['picking_ids'])[0]['picking_ids']
+        move_lines_ids = self.stock_picking.read(cr, uid, picking_id, ['move_lines'])[0]['move_lines']
+        for move in self.stock_move.browse(cr, uid, move_lines_ids, context=context):
+            move.action_done()
+
+        new_price = self.product_product.read(cr, uid, self.product_id, ['standard_price'], context=context)['standard_price']
+        self.assertAlmostEqual(
+            new_price,
+            (self.available_qty * self.standard_price + self.order_qty * self.order_price_unit)
+            /(self.available_qty + self.order_qty))
+
+    def test_20_partial_stock_move(self):
+        cr, uid, context = self.cr, self.uid, {}
+        picking_ids = self.purchase_order.read(cr, uid, [self.po_01_id], ['picking_ids'])[0]['picking_ids']
+        product = self.product_product.browse(cr, uid, self.product_id, context=context)
+
+        partial_move_id = self.stock_partial_move.create(cr, uid, {
+            'date': date.today(),
+            'picking_id': picking_ids[0]
+        }, context=context)
+
+        move_lines_ids = self.stock_picking.read(cr, uid, picking_ids, ['move_lines'])[0]['move_lines']
+        for move in self.stock_move.browse(cr, uid, move_lines_ids, context=context):
+            self.stock_partial_move_line.create(cr, uid, {
+                'product_id': self.product_id,
+                'quantity': self.picking_qty,
+                'product_uom': product.uom_id.id,
+                'location_dest_id': self.location_id,
+                'location_id': self.supplier_location_id,
+                'move_id': move.id,
+                'cost': self.order_price_unit,
+                'wizard_id': partial_move_id,
+            }, context=context)
+
+        self.stock_partial_move.do_partial(cr, uid, [partial_move_id], context=context)
+
+        new_price = self.product_product.read(cr, uid, self.product_id, ['standard_price'], context=context)['standard_price']
+        self.assertAlmostEqual(
+            new_price,
+            (self.available_qty * self.standard_price + self.order_qty * self.order_price_unit)
+            /(self.available_qty + self.order_qty))
+
+    def test_30_partial_stock_picking(self):
+        cr, uid, context = self.cr, self.uid, {}
+        picking_ids = self.purchase_order.read(cr, uid, [self.po_01_id], ['picking_ids'])[0]['picking_ids']
+        product = self.product_product.browse(cr, uid, self.product_id, context=context)
+
+        partial_picking_id = self.partial_picking.create(cr, uid, {
+            'date': date.today(),
+            'picking_id': picking_ids[0],
+        }, context=context)
+
+        move_lines_ids = self.stock_picking.read(cr, uid, picking_ids, ['move_lines'])[0]['move_lines']
+        for move in self.stock_move.browse(cr, uid, move_lines_ids, context=context):
+            self.partial_picking_line.create(cr, uid, {
+                'product_id': self.product_id,
+                'quantity': self.picking_qty,
+                'product_uom': product.uom_id.id,
+                'location_dest_id': self.location_id,
+                'location_id': self.supplier_location_id,
+                'move_id': move.id,
+                'cost': self.order_price_unit,
+                'wizard_id': partial_picking_id,
+            }, context=context)
+
+        self.partial_picking.do_partial(cr, uid, [partial_picking_id], context=context)
+
+        new_price = self.product_product.read(cr, uid, self.product_id, ['standard_price'], context=context)['standard_price']
+        self.assertAlmostEqual(
+            new_price,
+            (self.available_qty * self.standard_price + self.order_qty * self.order_price_unit)
+            /(self.available_qty + self.order_qty))
+
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 99ee036f2e76fbfce7e626dbee0cc7cecc38dbae..379d252854bdf6dec0a99c28894b8348caa8a42c 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -1227,8 +1227,6 @@ class stock_picking(osv.osv):
             context = dict(context)
         res = {}
         move_obj = self.pool.get('stock.move')
-        product_obj = self.pool.get('product.product')
-        currency_obj = self.pool.get('res.currency')
         uom_obj = self.pool.get('product.uom')
         sequence_obj = self.pool.get('ir.sequence')
         for pick in self.browse(cr, uid, ids, context=context):
@@ -1256,40 +1254,12 @@ class stock_picking(osv.osv):
                 else:
                     too_many.append(move)
 
-                # Average price computation
                 if (pick.type == 'in') and (move.product_id.cost_method == 'average'):
-                    product = product_obj.browse(cr, uid, move.product_id.id)
-                    move_currency_id = move.company_id.currency_id.id
-                    context['currency_id'] = move_currency_id
-                    qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
-
-                    if product.id not in product_avail:
-                        # keep track of stock on hand including processed lines not yet marked as done
-                        product_avail[product.id] = product.qty_available
-
-                    if qty > 0:
-                        new_price = currency_obj.compute(cr, uid, product_currency,
-                                move_currency_id, product_price, round=False)
-                        new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
-                                product.uom_id.id)
-                        if product_avail[product.id] <= 0:
-                            product_avail[product.id] = 0
-                            new_std_price = new_price
-                        else:
-                            # Get the standard price
-                            amount_unit = product.price_get('standard_price', context=context)[product.id]
-                            new_std_price = ((amount_unit * product_avail[product.id])\
-                                + (new_price * qty))/(product_avail[product.id] + qty)
-                        # Write the field according to price type field
-                        product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price})
-
-                        # Record the values that were chosen in the wizard, so they can be
-                        # used for inventory valuation if real-time valuation is enabled.
-                        move_obj.write(cr, uid, [move.id],
-                                {'price_unit': product_price,
-                                 'price_currency_id': product_currency})
-
-                        product_avail[product.id] += qty
+                    # Record the values that were chosen in the wizard, so they can be
+                    # used for average price computation and inventory valuation
+                    move_obj.write(cr, uid, [move.id],
+                            {'price_unit': product_price,
+                             'price_currency_id': product_currency})
 
             # every line of the picking is empty, do not generate anything
             empty_picking = not any(q for q in move_product_qty.values() if q > 0)
@@ -2328,6 +2298,44 @@ class stock_move(osv.osv):
 
         return reference_amount, reference_currency_id
 
+    def _update_average_price(self, cr, uid, move, context=None):
+        product_obj = self.pool.get('product.product')
+        currency_obj = self.pool.get('res.currency')
+        uom_obj = self.pool.get('product.uom')
+        product_avail = {}
+
+        if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
+            product = product_obj.browse(cr, uid, move.product_id.id)
+            move_currency_id = move.company_id.currency_id.id
+            context['currency_id'] = move_currency_id
+
+            product_qty = move.product_qty
+            product_uom = move.product_uom.id
+            product_price = move.price_unit
+            product_currency = move.price_currency_id.id
+
+            if product.id not in product_avail:
+                # keep track of stock on hand including processed lines not yet marked as done
+                product_avail[product.id] = product.qty_available
+
+            qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
+            if qty > 0:
+                new_price = currency_obj.compute(cr, uid, product_currency,
+                        move_currency_id, product_price, round=False)
+                new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
+                        product.uom_id.id)
+                if product_avail[product.id] <= 0:
+                    product_avail[product.id] = 0
+                    new_std_price = new_price
+                else:
+                    # Get the standard price
+                    amount_unit = product.price_get('standard_price', context=context)[product.id]
+                    new_std_price = ((amount_unit * product_avail[product.id])\
+                        + (new_price * qty))/(product_avail[product.id] + qty)
+
+                product_obj.write(cr, uid, [product.id],{'standard_price': new_std_price})
+
+                product_avail[product.id] += qty
 
     def _create_product_valuation_moves(self, cr, uid, move, context=None):
         """
@@ -2414,6 +2422,7 @@ class stock_move(osv.osv):
                         if move.move_dest_id.auto_validate:
                             self.action_done(cr, uid, [move.move_dest_id.id], context=context)
 
+            self._update_average_price(cr, uid, move, context=context)
             self._create_product_valuation_moves(cr, uid, move, context=context)
             if move.state not in ('confirmed','done','assigned'):
                 todo.append(move.id)
@@ -2676,9 +2685,6 @@ class stock_move(osv.osv):
         """
         res = {}
         picking_obj = self.pool.get('stock.picking')
-        product_obj = self.pool.get('product.product')
-        currency_obj = self.pool.get('res.currency')
-        uom_obj = self.pool.get('product.uom')
 
         if context is None:
             context = {}
@@ -2704,33 +2710,13 @@ class stock_move(osv.osv):
             else:
                 too_many.append(move)
 
-            # Average price computation
             if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
-                product = product_obj.browse(cr, uid, move.product_id.id)
-                move_currency_id = move.company_id.currency_id.id
-                context['currency_id'] = move_currency_id
-                qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
-                if qty > 0:
-                    new_price = currency_obj.compute(cr, uid, product_currency,
-                            move_currency_id, product_price, round=False)
-                    new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
-                            product.uom_id.id)
-                    if product.qty_available <= 0:
-                        new_std_price = new_price
-                    else:
-                        # Get the standard price
-                        amount_unit = product.price_get('standard_price', context=context)[product.id]
-                        new_std_price = ((amount_unit * product.qty_available)\
-                            + (new_price * qty))/(product.qty_available + qty)
-
-                    product_obj.write(cr, uid, [product.id],{'standard_price': new_std_price})
-
-                    # Record the values that were chosen in the wizard, so they can be
-                    # used for inventory valuation if real-time valuation is enabled.
-                    self.write(cr, uid, [move.id],
-                                {'price_unit': product_price,
-                                 'price_currency_id': product_currency,
-                                })
+                # Record the values that were chosen in the wizard, so they can be
+                # used for average price computation and inventory valuation
+                self.write(cr, uid, [move.id],
+                            {'price_unit': product_price,
+                             'price_currency_id': product_currency,
+                            })
 
         for move in too_few:
             product_qty = move_product_qty[move.id]
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 4694b405d1457daf66a5c69d96399c7c9ebdaf82..fc9a56e4bdac9ddf6d034874ce66b1fbb3e24552 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -1608,7 +1608,9 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
                 .filter(function (column) { return column.tag === 'field';})
                 .pluck('name').value(),
             function (groups) {
-                self.view.$pager.hide();
+                // page count is irrelevant on grouped page, replace by limit
+                self.view.$pager.find('.oe_pager_group').hide();
+                self.view.$pager.find('.oe_list_pager_state').text(self.view._limit ? self.view._limit : '∞');
                 $el[0].appendChild(
                     self.render_groups(groups));
                 if (post_render) { post_render(); }