← Back to team overview

openerp-community-reviewer team mailing list archive

[Merge] lp:~lmi/ocb-addons/7.0-bug-796570-amu into lp:ocb-addons

 

Laurent Mignon (Acsone) has proposed merging lp:~lmi/ocb-addons/7.0-bug-796570-amu into lp:ocb-addons.

Requested reviews:
  OpenERP Community Backports Team (ocb)

For more details, see:
https://code.launchpad.net/~lmi/ocb-addons/7.0-bug-796570-amu/+merge/203378

Automatically derived from https://code.launchpad.net/~acsone-openerp/openobject-addons/7.0-bug-796570-amu for https://code.launchpad.net/~openerp/openobject-addons/7.0. Below is a copy of the original description.

Fix the default tax bug lp:796570.

As requested by Fabien (https://bugs.launchpad.net/openobject-addons/+bug/796570/comments/5) the bug have been corrected on all the modules where the default tax is ignored (sale, purchase, delivery, mrp_repair, point_of_sale, purchase_requisition and stock).

Two functions have been added on the module 'product_product' (get_taxes_id_or_default and get_supplier_taxes_id_or_default). This functions are now used in the corrected modules and in account, hr_expense and hr_timesheet_invoice in order to have the same logic everywhere.

-- 
https://code.launchpad.net/~lmi/ocb-addons/7.0-bug-796570-amu/+merge/203378
Your team OpenERP Community Backports Team is requested to review the proposed merge of lp:~lmi/ocb-addons/7.0-bug-796570-amu into lp:ocb-addons.
=== modified file 'account/account_invoice.py'
--- account/account_invoice.py	2013-11-02 13:03:02 +0000
+++ account/account_invoice.py	2014-01-27 17:23:47 +0000
@@ -1515,10 +1515,9 @@
             result['account_id'] = a
 
         if type in ('out_invoice', 'out_refund'):
-            taxes = res.taxes_id and res.taxes_id or (a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False)
+            tax_id = self.pool.get('product.product').get_taxes_id_or_default(cr, uid, res.id, fpos, context=context)
         else:
-            taxes = res.supplier_taxes_id and res.supplier_taxes_id or (a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False)
-        tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes)
+            tax_id = self.pool.get('product.product').get_supplier_taxes_id_or_default(cr, uid, res.id, fpos, context=context)
 
         if type in ('in_invoice', 'in_refund'):
             result.update( {'price_unit': price_unit or res.standard_price,'invoice_line_tax_id': tax_id} )

=== modified file 'account/product.py'
--- account/product.py	2012-10-23 16:05:04 +0000
+++ account/product.py	2014-01-27 17:23:47 +0000
@@ -72,4 +72,54 @@
 
 product_template()
 
+
+class product_product(osv.osv):
+    _inherit = "product.product"
+
+    def get_taxes_id_or_default(self, cr, uid, id_, fpos, context=None):
+        """
+        Return the product taxes id if there is one on the product,
+        if there is none: return the product category default income tax
+        """
+
+        taxes = self.get_taxes_or_default(cr, uid, id_, fpos, context=context)
+        return self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes)
+
+    def get_taxes_or_default(self, cr, uid, id_, fpos, context=None):
+        """
+        Return the product taxes if there is one on the product,
+        if there is none: return the product category default income tax
+        """
+
+        product = self.pool.get('product.product').browse(cr, uid, id_, context=context)
+        taxes = product.taxes_id
+        if not taxes:
+            account = product.property_account_income or product.categ_id.property_account_income_categ
+            account = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, account)
+            taxes = account.tax_ids
+        return taxes
+
+    def get_supplier_taxes_id_or_default(self, cr, uid, id_, fpos, context=None):
+        """
+        Return the product supplier taxes id if there is one on the product,
+        if there is none: return the product category default expense tax
+        """
+
+        taxes = self.get_supplier_taxes_or_default(cr, uid, id_, fpos, context=context)
+        return self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes)
+
+    def get_supplier_taxes_or_default(self, cr, uid, id_, fpos, context=None):
+        """
+        Return the product supplier taxes if there is one on the product,
+        if there is none: return the product category default expense tax
+        """
+
+        product = self.pool.get('product.product').browse(cr, uid, id_, context=context)
+        taxes = product.supplier_taxes_id
+        if not taxes:
+            account = product.property_account_expense or product.categ_id.property_account_expense_categ
+            account = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, account)
+            taxes = account.tax_ids
+        return taxes
+
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'account/tests/__init__.py'
--- account/tests/__init__.py	2013-12-06 17:00:12 +0000
+++ account/tests/__init__.py	2014-01-27 17:23:47 +0000
@@ -1,7 +1,9 @@
 from . import test_tax
 from . import test_search
+from . import test_default_tax
 
 fast_suite = [
 	test_tax,
 	test_search,
+	test_default_tax,
 ]

=== added file 'account/tests/test_default_tax.py'
--- account/tests/test_default_tax.py	1970-01-01 00:00:00 +0000
+++ account/tests/test_default_tax.py	2014-01-27 17:23:47 +0000
@@ -0,0 +1,162 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Authors: Muschang Anthony
+#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
+#    All Rights Reserved
+#
+#    WARNING: This program as such is intended to be used by professional
+#    programmers who take the whole responsibility of assessing all potential
+#    consequences resulting from its eventual inadequacies and bugs.
+#    End users who are looking for a ready-to-use solution with commercial
+#    guarantees and support are strongly advised to contact a Free Software
+#    Service Company.
+#
+#    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 openerp.tests.common as common
+import logging
+
+_logger = logging.getLogger(__name__)
+
+DB = common.DB
+ADMIN_USER_ID = common.ADMIN_USER_ID
+
+
+class test_default_tax(common.TransactionCase):
+
+    def test_default_tax_invoice(self):
+        """
+            Test obtaining the sale taxes from account.accout default tax
+        """
+
+        account_model = self.registry('account.account')
+        product_category_model = self.registry('product.category')
+        product_model = self.registry('product.product')
+        invoice_model = self.registry('account.invoice')
+        invoice_line_model = self.registry('account.invoice.line')
+        partner_model = self.registry('res.partner')
+
+        id_product_category_a = self.ref("product.product_category_1")
+
+        #add a tax id to the product category
+        product_category = product_category_model.browse(self.cr, self.uid, id_product_category_a)
+        id_account = product_category.property_account_income_categ.id
+
+        account_model.write(self.cr, ADMIN_USER_ID, id_account, {
+            'tax_ids': [(0, 0, {'name': 'Tax A'})],
+        })
+
+        self.assertEquals(product_category.property_account_income_categ.tax_ids[0].name, "Tax A", "there must be a default tax on the product category")
+
+        id_product = product_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Product A',
+            'categ_id': id_product_category_a,
+        })
+
+        id_partner = partner_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Partner A',
+        })
+
+        id_invoice = invoice_model.create(self.cr, ADMIN_USER_ID, {
+            'partner_id': id_partner,
+            'account_id': id_account,
+        })
+
+        invoice_model.write(self.cr, ADMIN_USER_ID, id_invoice, {
+            'invoice_line': [(0, 0, {'name': 'Order line A',
+                                     'invoice_id': id_invoice,
+                                    })],
+        })
+
+        invoice = invoice_model.browse(self.cr, self.uid, id_invoice)
+        values_to_update = invoice_line_model.product_id_change(self.cr, self.uid, invoice.invoice_line[0].id, id_product, uom_id=False, partner_id=id_partner)['value']
+        self.assertEqual(product_category.property_account_income_categ.tax_ids[0].id, values_to_update['invoice_line_tax_id'][0])
+
+        """Set an invoice account in the product, the default tax should be ignored"""
+
+        product_model.write(self.cr, ADMIN_USER_ID, id_product, {
+            'taxes_id': [(0, 0, {'name': 'Tax B'})],
+        })
+
+        product = product_model.browse(self.cr, self.uid, id_product)
+        self.assertEquals(product_category.property_account_income_categ.tax_ids[0].name, "Tax A", "the default tax on the product category must not have change")
+        self.assertEquals(product.taxes_id[0].name, "Tax B", "the default tax on the product category must not have change")
+
+        values_to_update = invoice_line_model.product_id_change(self.cr, self.uid, invoice.invoice_line[0].id, id_product, uom_id=False, partner_id=id_partner)['value']
+        self.assertEqual(product.taxes_id[0].id, values_to_update['invoice_line_tax_id'][0])
+
+    def test_default_tax_expense(self):
+        """
+            Test obtaining the purchase taxes from account.accout default tax
+        """
+
+        account_model = self.registry('account.account')
+        product_category_model = self.registry('product.category')
+        product_model = self.registry('product.product')
+        invoice_model = self.registry('account.invoice')
+        invoice_line_model = self.registry('account.invoice.line')
+        partner_model = self.registry('res.partner')
+
+        id_product_category_a = self.ref("product.product_category_1")
+
+        #add a tax id to the product category
+        product_category = product_category_model.browse(self.cr, self.uid, id_product_category_a)
+        id_account = product_category.property_account_expense_categ.id
+
+        account_model.write(self.cr, ADMIN_USER_ID, id_account, {
+            'tax_ids': [(0, 0, {'name': 'Tax A'})],
+        })
+
+        self.assertEquals(product_category.property_account_expense_categ.tax_ids[0].name, "Tax A", "there must be a default tax on the product category")
+
+        id_product = product_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Product A',
+            'categ_id': id_product_category_a,
+        })
+
+        id_partner = partner_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Partner A',
+        })
+
+        id_invoice = invoice_model.create(self.cr, ADMIN_USER_ID, {
+            'partner_id': id_partner,
+            'account_id': id_account,
+        })
+
+        invoice_model.write(self.cr, ADMIN_USER_ID, id_invoice, {
+            'invoice_line': [(0, 0, {'name': 'Order line A',
+                                     'invoice_id': id_invoice,
+                                    })],
+        })
+
+        invoice = invoice_model.browse(self.cr, self.uid, id_invoice)
+        values_to_update = invoice_line_model.product_id_change(self.cr, self.uid, invoice.invoice_line[0].id, id_product, uom_id=False, partner_id=id_partner, type='in_invoice')['value']
+        self.assertEqual(product_category.property_account_expense_categ.tax_ids[0].id, values_to_update['invoice_line_tax_id'][0])
+
+        """Set an invoice account in the product, the default tax should be ignored"""
+
+        product_model.write(self.cr, ADMIN_USER_ID, id_product, {
+            'supplier_taxes_id': [(0, 0, {'name': 'Tax B'})],
+        })
+
+        product = product_model.browse(self.cr, self.uid, id_product)
+        self.assertEquals(product_category.property_account_expense_categ.tax_ids[0].name, "Tax A", "the default tax on the product category must not have change")
+        self.assertEquals(product.supplier_taxes_id[0].name, "Tax B", "the default tax on the product category must not have change")
+
+        values_to_update = invoice_line_model.product_id_change(self.cr, self.uid, invoice.invoice_line[0].id, id_product, uom_id=False, partner_id=id_partner, type='in_invoice')['value']
+        self.assertEqual(product.supplier_taxes_id[0].id, values_to_update['invoice_line_tax_id'][0])
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'delivery/sale.py'
--- delivery/sale.py	2012-10-23 16:05:04 +0000
+++ delivery/sale.py	2014-01-27 17:23:47 +0000
@@ -48,6 +48,7 @@
         grid_obj = self.pool.get('delivery.grid')
         carrier_obj = self.pool.get('delivery.carrier')
         acc_fp_obj = self.pool.get('account.fiscal.position')
+        product_obj = self.pool.get('product.product')
         for order in self.browse(cr, uid, ids, context=context):
             grid_id = carrier_obj.grid_get(cr, uid, [order.carrier_id.id], order.partner_shipping_id.id)
             if not grid_id:
@@ -58,9 +59,9 @@
 
             grid = grid_obj.browse(cr, uid, grid_id, context=context)
 
-            taxes = grid.carrier_id.product_id.taxes_id
             fpos = order.fiscal_position or False
-            taxes_ids = acc_fp_obj.map_tax(cr, uid, fpos, taxes)
+            taxes_ids = product_obj.get_taxes_id_or_default(cr, uid, grid.carrier_id.product_id.id, fpos, context=context)
+
             #create the sale order line
             line_obj.create(cr, uid, {
                 'order_id': order.id,

=== modified file 'delivery/stock.py'
--- delivery/stock.py	2013-11-19 18:18:55 +0000
+++ delivery/stock.py	2014-01-27 17:23:47 +0000
@@ -80,6 +80,7 @@
         """
         carrier_obj = self.pool.get('delivery.carrier')
         grid_obj = self.pool.get('delivery.grid')
+        product_obj = self.pool.get('product.product')
         if not picking.carrier_id or \
             any(inv_line.product_id.id == picking.carrier_id.product_id.id
                 for inv_line in invoice.invoice_line):
@@ -99,13 +100,13 @@
             account_id = picking.carrier_id.product_id.categ_id\
                     .property_account_income_categ.id
 
-        taxes = picking.carrier_id.product_id.taxes_id
         partner = picking.partner_id or False
+
         if partner:
-            account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, partner.property_account_position, account_id)
-            taxes_ids = self.pool.get('account.fiscal.position').map_tax(cr, uid, partner.property_account_position, taxes)
+            fpos = partner.property_account_position,
         else:
-            taxes_ids = [x.id for x in taxes]
+            fpos = False
+        taxes_ids = product_obj.get_taxes_id_or_default(cr, uid, picking.carrier_id.product_id.id, fpos, context=context)
 
         return {
             'name': picking.carrier_id.name,

=== modified file 'hr_expense/hr_expense.py'
--- hr_expense/hr_expense.py	2013-09-09 08:02:09 +0000
+++ hr_expense/hr_expense.py	2014-01-27 17:23:47 +0000
@@ -298,7 +298,7 @@
                 continue
             res.append(mres)
             tax_code_found= False
-            
+
             #Calculate tax according to default tax on product
             taxes = []
             #Taken from product_id_onchange in account.invoice
@@ -307,15 +307,7 @@
                 fpos_obj = self.pool.get('account.fiscal.position')
                 fpos = fposition_id and fpos_obj.browse(cr, uid, fposition_id, context=context) or False
                 product = line.product_id
-                taxes = product.supplier_taxes_id
-                #If taxes are not related to the product, maybe they are in the account
-                if not taxes:
-                    a = product.property_account_expense.id #Why is not there a check here?
-                    if not a:
-                        a = product.categ_id.property_account_expense_categ.id
-                    a = fpos_obj.map_account(cr, uid, fpos, a)
-                    taxes = a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False
-                tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes)
+                taxes = self.pool.get('product.product').get_supplier_taxes_or_default(cr, uid, product.id, fpos, context=context)
             if not taxes:
                 continue
             #Calculating tax on the line and creating move?

=== modified file 'hr_timesheet_invoice/hr_timesheet_invoice.py'
--- hr_timesheet_invoice/hr_timesheet_invoice.py	2014-01-13 16:56:47 +0000
+++ hr_timesheet_invoice/hr_timesheet_invoice.py	2014-01-27 17:23:47 +0000
@@ -263,15 +263,17 @@
                         if factor.customer_name:
                             factor_name += ' - ' + factor.customer_name
 
+                        fpos = account.partner_id.property_account_position
                         general_account = product.property_account_income or product.categ_id.property_account_income_categ
+                        general_account = fiscal_pos_obj.map_account(cr, uid, fpos, general_account)
+
                         if not general_account:
                             raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
-                        taxes = product.taxes_id or general_account.tax_ids
-                        tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
+
+                        taxes = product_obj.get_taxes_id_or_default(cr, uid, product_id, fpos, context=context)
                         curr_line.update({
-                            'invoice_line_tax_id': [(6,0,tax )],
                             'name': factor_name,
-                            'invoice_line_tax_id': [(6,0,tax)],
+                            'invoice_line_tax_id': [(6, 0, taxes)],
                             'account_id': general_account.id,
                         })
                     #

=== modified file 'mrp_repair/mrp_repair.py'
--- mrp_repair/mrp_repair.py	2013-12-18 16:52:56 +0000
+++ mrp_repair/mrp_repair.py	2014-01-27 17:23:47 +0000
@@ -582,7 +582,7 @@
             product_obj = self.pool.get('product.product').browse(cr, uid, product)
             if partner_id:
                 partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
-                result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, partner.property_account_position, product_obj.taxes_id)
+                result['tax_id'] = self.pool.get('product.product').get_taxes_id_or_default(cr, uid, product, partner.property_account_position)
 
             result['name'] = product_obj.partner_ref
             result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False

=== modified file 'point_of_sale/point_of_sale.py'
--- point_of_sale/point_of_sale.py	2013-12-10 18:17:33 +0000
+++ point_of_sale/point_of_sale.py	2014-01-27 17:23:47 +0000
@@ -888,7 +888,6 @@
                 inv_line['price_unit'] = line.price_unit
                 inv_line['discount'] = line.discount
                 inv_line['name'] = inv_name
-                inv_line['invoice_line_tax_id'] = [(6, 0, [x.id for x in line.product_id.taxes_id] )]
                 inv_line_ref.create(cr, uid, inv_line, context=context)
             inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
             wf_service.trg_validate(uid, 'pos.order', order.id, 'invoice', cr)

=== modified file 'purchase/purchase.py'
--- purchase/purchase.py	2014-01-20 17:07:29 +0000
+++ purchase/purchase.py	2014-01-27 17:23:47 +0000
@@ -1030,9 +1030,8 @@
         else:
             price = product.standard_price
 
-        taxes = account_tax.browse(cr, uid, map(lambda x: x.id, product.supplier_taxes_id))
         fpos = fiscal_position_id and account_fiscal_position.browse(cr, uid, fiscal_position_id, context=context) or False
-        taxes_ids = account_fiscal_position.map_tax(cr, uid, fpos, taxes)
+        taxes_ids = product_product.get_supplier_taxes_id_or_default(cr, uid, product.id, fpos, context=context)
         res['value'].update({'price_unit': price, 'taxes_id': taxes_ids})
 
         return res

=== added directory 'purchase/tests'
=== added file 'purchase/tests/__init__.py'
--- purchase/tests/__init__.py	1970-01-01 00:00:00 +0000
+++ purchase/tests/__init__.py	2014-01-27 17:23:47 +0000
@@ -0,0 +1,5 @@
+from . import test_default_tax
+
+fast_suite = [
+    test_default_tax,
+]

=== added file 'purchase/tests/test_default_tax.py'
--- purchase/tests/test_default_tax.py	1970-01-01 00:00:00 +0000
+++ purchase/tests/test_default_tax.py	2014-01-27 17:23:47 +0000
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Authors: Muschang Anthony
+#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
+#    All Rights Reserved
+#
+#    WARNING: This program as such is intended to be used by professional
+#    programmers who take the whole responsibility of assessing all potential
+#    consequences resulting from its eventual inadequacies and bugs.
+#    End users who are looking for a ready-to-use solution with commercial
+#    guarantees and support are strongly advised to contact a Free Software
+#    Service Company.
+#
+#    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 openerp.tests.common as common
+import logging
+import datetime
+
+_logger = logging.getLogger(__name__)
+
+DB = common.DB
+ADMIN_USER_ID = common.ADMIN_USER_ID
+
+
+class test_default_tax(common.TransactionCase):
+
+    def test_default_tax_expense(self):
+        """
+            Test obtaining the purchase taxes from account.accout default tax
+        """
+
+        account_model = self.registry('account.account')
+        product_category_model = self.registry('product.category')
+        product_model = self.registry('product.product')
+        purchase_model = self.registry('purchase.order')
+        order_line_model = self.registry('purchase.order.line')
+        partner_model = self.registry('res.partner')
+
+        id_product_category_a = self.ref("product.product_category_1")
+
+        #add a tax id to the product category
+        product_category = product_category_model.browse(self.cr, self.uid, id_product_category_a)
+        id_account = product_category.property_account_expense_categ.id
+
+        account_model.write(self.cr, ADMIN_USER_ID, id_account, {
+            'tax_ids': [(0, 0, {'name': 'Tax A'})],
+        })
+
+        self.assertEquals(product_category.property_account_expense_categ.tax_ids[0].name, "Tax A", "there must be a default tax on the product category")
+
+        id_product = product_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Product A',
+            'categ_id': id_product_category_a,
+        })
+
+        id_partner = partner_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Partner A',
+        })
+
+        id_pricelist = self.ref("product.list0")
+
+        id_purchase = purchase_model.create(self.cr, ADMIN_USER_ID, {
+            'partner_id': id_partner,
+            'location_id': self.ref("stock.stock_location_3"),
+            'pricelist_id': id_pricelist,
+        })
+
+        purchase_model.write(self.cr, ADMIN_USER_ID, id_purchase, {
+            'order_line': [(0, 0, {'name': 'Order line A',
+                                   'order_id': id_purchase,
+                                   'price_unit': 0.0,
+                                   'date_planned': datetime.date(2012, 12, 12)})],
+        })
+
+        purchase = purchase_model.browse(self.cr, self.uid, id_purchase)
+        values_to_update = order_line_model.product_id_change(self.cr, self.uid, purchase.order_line[0].id, id_pricelist, id_product, qty=1, uom_id=False, partner_id=id_partner)['value']
+        self.assertEqual(product_category.property_account_expense_categ.tax_ids[0].id, values_to_update['taxes_id'][0])
+
+        """Set an purchase account in the product, the default tax should be ignored"""
+
+        product_model.write(self.cr, ADMIN_USER_ID, id_product, {
+            'supplier_taxes_id': [(0, 0, {'name': 'Tax B'})],
+        })
+
+        product = product_model.browse(self.cr, self.uid, id_product)
+        self.assertEquals(product_category.property_account_expense_categ.tax_ids[0].name, "Tax A", "the default tax on the product category must not have change")
+        self.assertEquals(product.supplier_taxes_id[0].name, "Tax B", "the default tax on the product category must not have change")
+
+        values_to_update = order_line_model.product_id_change(self.cr, self.uid, purchase.order_line[0].id, id_pricelist, id_product, qty=1, uom_id=False, partner_id=id_partner)['value']
+        self.assertEqual(product.supplier_taxes_id[0].id, values_to_update['taxes_id'][0])
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'purchase_requisition/purchase_requisition.py'
--- purchase_requisition/purchase_requisition.py	2013-11-29 10:02:22 +0000
+++ purchase_requisition/purchase_requisition.py	2014-01-27 17:23:47 +0000
@@ -157,6 +157,8 @@
         purchase_order_line = self.pool.get('purchase.order.line')
         res_partner = self.pool.get('res.partner')
         fiscal_position = self.pool.get('account.fiscal.position')
+        product_obj = self.pool.get('product.product')
+
         supplier = res_partner.browse(cr, uid, partner_id, context=context)
         supplier_pricelist = supplier.property_product_pricelist_purchase or False
         res = {}
@@ -179,8 +181,9 @@
             for line in requisition.line_ids:
                 product = line.product_id
                 seller_price, qty, default_uom_po_id, date_planned = self._seller_details(cr, uid, line, supplier, context=context)
-                taxes_ids = product.supplier_taxes_id
-                taxes = fiscal_position.map_tax(cr, uid, supplier.property_account_position, taxes_ids)
+
+                taxes = product_obj.get_supplier_taxes_id_or_default(cr, uid, product.id, supplier.property_account_position, context=context)
+
                 purchase_order_line.create(cr, uid, {
                     'order_id': purchase_id,
                     'name': product.partner_ref,

=== modified file 'sale/sale.py'
--- sale/sale.py	2014-01-15 14:40:30 +0000
+++ sale/sale.py	2014-01-27 17:23:47 +0000
@@ -899,8 +899,7 @@
                 uos = False
         fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
         if update_tax: #The quantity only have changed
-            result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
-
+            result['tax_id'] = self.pool.get('product.product').get_taxes_id_or_default(cr, uid, product_obj.id, fpos, context=context)
         if not flag:
             result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner)[0][1]
             if product_obj.description_sale:

=== added directory 'sale/tests'
=== added file 'sale/tests/__init__.py'
--- sale/tests/__init__.py	1970-01-01 00:00:00 +0000
+++ sale/tests/__init__.py	2014-01-27 17:23:47 +0000
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Authors: Anthony Muschang
+#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
+#    All Rights Reserved
+#
+#    WARNING: This program as such is intended to be used by professional
+#    programmers who take the whole responsibility of assessing all potential
+#    consequences resulting from its eventual inadequacies and bugs.
+#    End users who are looking for a ready-to-use solution with commercial
+#    guarantees and support are strongly advised to contact a Free Software
+#    Service Company.
+#
+#    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_default_tax
+
+checks = [
+    test_default_tax,
+]
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'sale/tests/test_default_tax.py'
--- sale/tests/test_default_tax.py	1970-01-01 00:00:00 +0000
+++ sale/tests/test_default_tax.py	2014-01-27 17:23:47 +0000
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Authors: Muschang Anthony
+#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
+#    All Rights Reserved
+#
+#    WARNING: This program as such is intended to be used by professional
+#    programmers who take the whole responsibility of assessing all potential
+#    consequences resulting from its eventual inadequacies and bugs.
+#    End users who are looking for a ready-to-use solution with commercial
+#    guarantees and support are strongly advised to contact a Free Software
+#    Service Company.
+#
+#    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 openerp.tests.common as common
+import logging
+
+_logger = logging.getLogger(__name__)
+
+DB = common.DB
+ADMIN_USER_ID = common.ADMIN_USER_ID
+
+
+class test_default_tax(common.TransactionCase):
+
+    def setUp(self):
+        super(test_default_tax, self).setUp()
+
+    def test_default_tax(self):
+        """
+            Test obtaining the sale and purchase taxes from account.accout default tax
+        """
+
+        account_model = self.registry('account.account')
+        product_category_model = self.registry('product.category')
+        product_model = self.registry('product.product')
+        sales_order_model = self.registry('sale.order')
+        sales_order_line_model = self.registry('sale.order.line')
+        partner_model = self.registry('res.partner')
+
+        id_product_category_a = self.ref("product.product_category_1")
+
+        #add a tax id to the product category
+        product_category = product_category_model.browse(self.cr, self.uid, id_product_category_a)
+
+        account_model.write(self.cr, ADMIN_USER_ID, product_category.property_account_income_categ.id, {
+            'tax_ids': [(0, 0, {'name': 'Tax A'})],
+        })
+
+        self.assertEquals(product_category.property_account_income_categ.tax_ids[0].name, "Tax A", "there must be a default tax on the product category")
+
+        id_product = product_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Product A',
+            'categ_id': id_product_category_a,
+        })
+
+        id_partner = partner_model.create(self.cr, ADMIN_USER_ID, {
+            'name': 'Partner A',
+        })
+
+        id_pricelist = self.ref("product.list0")
+
+        id_sales_order = sales_order_model.create(self.cr, ADMIN_USER_ID, {
+            'partner_id': id_partner,
+            'pricelist_id': id_pricelist,
+            'partner_invoice_id': id_partner,
+            'partner_shipping_id': id_partner,
+        })
+
+        sales_order_model.write(self.cr, ADMIN_USER_ID, id_sales_order, {
+            'order_line': [(0, 0, {'name': 'Order line A',
+                                   'product_id': id_product,
+                                   'product_uom_qty': 8,
+                                   'order_id': id_sales_order,
+                                   })],
+        })
+
+        sale_order = sales_order_model.browse(self.cr, self.uid, id_sales_order)
+
+        sales_order_values_to_update = sales_order_line_model.product_id_change(self.cr, self.uid, sale_order.order_line[0], id_pricelist, id_product, partner_id=id_partner)['value']
+
+        self.assertEqual(product_category.property_account_income_categ.tax_ids[0].id, sales_order_values_to_update['tax_id'][0])
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== modified file 'stock/stock.py'
--- stock/stock.py	2014-01-22 13:38:22 +0000
+++ stock/stock.py	2014-01-27 17:23:47 +0000
@@ -968,20 +968,17 @@
         @param type: Type of invoice
         @return: Taxes Ids for the move line
         """
-        if type in ('in_invoice', 'in_refund'):
-            taxes = move_line.product_id.supplier_taxes_id
-        else:
-            taxes = move_line.product_id.taxes_id
 
         if move_line.picking_id and move_line.picking_id.partner_id and move_line.picking_id.partner_id.id:
-            return self.pool.get('account.fiscal.position').map_tax(
-                cr,
-                uid,
-                move_line.picking_id.partner_id.property_account_position,
-                taxes
-            )
-        else:
-            return map(lambda x: x.id, taxes)
+            fpos = move_line.picking_id.partner_id.property_account_position
+        else:
+            fpos = False
+
+        product_obj = self.pool.get('product.product')
+        if type in ('in_invoice', 'in_refund'):
+            return product_obj.get_supplier_taxes_id_or_default(cr, uid, move_line.product_id.id, fpos)
+        else:
+            return product_obj.get_taxes_id_or_default(cr, uid, move_line.product_id.id, fpos)
 
     def _get_account_analytic_invoice(self, cr, uid, picking, move_line):
         return False


Follow ups