openerp-community-reviewer team mailing list archive
-
openerp-community-reviewer team
-
Mailing list archive
-
Message #03219
[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