openobject-italia-core-devs team mailing list archive
-
openobject-italia-core-devs team
-
Mailing list archive
-
Message #00730
lp:~openobject-italia-core-devs/openobject-italia/refactoring_account_invoice_tax_by_column into lp:openobject-italia
Lorenzo Battistini - Agile BG - Domsense has proposed merging lp:~openobject-italia-core-devs/openobject-italia/refactoring_account_invoice_tax_by_column into lp:openobject-italia.
Requested reviews:
OpenERP Italia core devs (openobject-italia-core-devs)
For more details, see:
https://code.launchpad.net/~openobject-italia-core-devs/openobject-italia/refactoring_account_invoice_tax_by_column/+merge/81258
--
https://code.launchpad.net/~openobject-italia-core-devs/openobject-italia/refactoring_account_invoice_tax_by_column/+merge/81258
Your team OpenERP Italia core devs is requested to review the proposed merge of lp:~openobject-italia-core-devs/openobject-italia/refactoring_account_invoice_tax_by_column into lp:openobject-italia.
=== modified file 'account_invoice_tax_by_column/__init__.py'
--- account_invoice_tax_by_column/__init__.py 2011-08-23 16:36:37 +0000
+++ account_invoice_tax_by_column/__init__.py 2011-11-04 11:28:23 +0000
@@ -21,4 +21,3 @@
##############################################################################
import invoice
-import account
=== modified file 'account_invoice_tax_by_column/__openerp__.py'
--- account_invoice_tax_by_column/__openerp__.py 2011-10-11 15:45:36 +0000
+++ account_invoice_tax_by_column/__openerp__.py 2011-11-04 11:28:23 +0000
@@ -47,12 +47,14 @@
'author': 'OpenERP Italian Community',
'website': 'http://www.openerp-italia.org',
'license': 'AGPL-3',
- "depends" : ['account', 'account_voucher'],
+ "depends" : ['account', 'account_voucher', 'c2c_account_tax_rounding'],
"init_xml" : [],
- "update_xml" : ['company_view.xml',],
+ "update_xml" : [],
"demo_xml" : [],
+ 'test': [
+ 'test/account_tax.xml',
+ 'test/tax_computation.yml',
+ ],
"active": False,
"installable": True
}
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
=== removed file 'account_invoice_tax_by_column/account.py'
--- account_invoice_tax_by_column/account.py 2011-10-24 12:19:02 +0000
+++ account_invoice_tax_by_column/account.py 1970-01-01 00:00:00 +0000
@@ -1,64 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2011
-# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
-#
-# 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 osv import fields, osv
-from tools.translate import _
-
-class res_company(osv.osv):
-
- _inherit = 'res.company'
-
- _columns = {
- 'vertical_comp' : fields.boolean('Tax Vertical Calculation'),
- }
-
- _defaults = {
- 'vertical_comp': True
- }
-
-res_company()
-
-class account_tax(osv.osv):
-
- _inherit = 'account.tax'
-
- def get_main_tax(self, tax):
- if not tax.parent_id:
- return tax
- else:
- return self.get_main_tax(tax.parent_id)
-
- def get_account_tax(self, cr, uid, inv_tax_name):
- splitted_name = inv_tax_name.split(' - ')
- if len(splitted_name) > 1:
- tax_name = splitted_name[1]
- else:
- tax_name = splitted_name[0]
- # cerco la tassa per nome, dopo averlo ottenuto dalla tassa in fattura
- tax_ids = self.search(cr, uid, [('name', '=', tax_name)])
- if not tax_ids:
- raise osv.except_osv(_('Error'), _('The tax %s does not exist') % tax_name)
- if len(tax_ids) > 1:
- raise osv.except_osv(_('Error'), _('Too many taxes with name %s') % tax_name)
- return self.browse(cr, uid, tax_ids[0])
-
-account_tax()
=== removed file 'account_invoice_tax_by_column/company_view.xml'
--- account_invoice_tax_by_column/company_view.xml 2011-10-11 15:45:36 +0000
+++ account_invoice_tax_by_column/company_view.xml 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
- <data>
- <record id="view_company_form" model="ir.ui.view">
- <field name="inherit_id" ref="base.view_company_form"/>
- <field name="name">view.company.form</field>
- <field name="model">res.company</field>
- <field name="type">form</field>
- <field name="arch" type="xml">
- <field name="currency_id" position="after">
- <field name="vertical_comp"/>
- </field>
- </field>
- </record>
- </data>
-</openerp>
=== modified file 'account_invoice_tax_by_column/invoice.py'
--- account_invoice_tax_by_column/invoice.py 2011-10-21 13:53:32 +0000
+++ account_invoice_tax_by_column/invoice.py 2011-11-04 11:28:23 +0000
@@ -26,90 +26,53 @@
class account_invoice_tax(osv.osv):
_inherit = "account.invoice.tax"
- def compute_taxes_by_rate(self, cr, uid, lines=[], precision=2, address_id=None, partner=None):
-
- # lines has the form
- # [{'price_unit': 100, 'discount': 0, 'quantity': 1, 'taxes': [account.tax], 'product': product.product}]
- # returns a dictionary like {0.2: 20}
-
- tax_obj = self.pool.get('account.tax')
- tax_by_rate = {}
- # collect the base amount grouped by tax rate
- for line in lines:
- for tax in line['taxes']:
- # TODO manage multi currency
- if not tax_by_rate.get(tax['id'], False):
- tax_by_rate[tax['id']] = {'base_amount': 0.0, 'product': None}
- tax_by_rate[tax['id']]['base_amount'] += (line['price_unit'] * (1-(line['discount'] or 0.0)/100.0)) \
- * line['quantity']
- if line.get('product', False):
- tax_by_rate[tax['id']]['product'] = line['product']
- # compute the tax amount grouped by tax
- for tax_id in tax_by_rate:
- tax = tax_obj.browse(cr, uid, tax_id)
- total = tax_obj.compute_all(cr, uid, [tax], tax_by_rate[tax_id]['base_amount'], 1,
- address_id=address_id, product=tax_by_rate[tax_id]['product'], partner=partner)
- tax_by_rate[tax_id] = total['total_included'] - total['total']
-
- return tax_by_rate
-
def compute(self, cr, uid, invoice_id, context=None):
tax_grouped = super(account_invoice_tax, self).compute(cr, uid, invoice_id, context)
- user_obj = self.pool.get('res.users')
- precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
- if user_obj.browse(cr, uid, uid).company_id.vertical_comp:
- tax_obj = self.pool.get('account.tax')
- inv_obj = self.pool.get('account.invoice')
-
- inv = inv_obj.browse(cr, uid, invoice_id, context=context)
-
- for inv_tax in tax_grouped.values():
- inv_tax['tax_rate'] = tax_obj.get_main_tax(tax_obj.get_account_tax(cr, uid, inv_tax['name'])).amount
- inv_tax['tax_id'] = tax_obj.get_main_tax(tax_obj.get_account_tax(cr, uid, inv_tax['name'])).id
-
- lines = []
- for line in inv.invoice_line:
- line_dic = {'price_unit': line.price_unit, 'discount': line.discount, 'quantity': line.quantity,
- 'taxes': [], 'product': line.product_id}
- for tax in line.invoice_line_tax_id:
- line_dic['taxes'].append(tax)
- lines.append(line_dic)
-
- tax_by_rate = self.compute_taxes_by_rate(cr, uid, lines=lines, precision=precision,
- address_id=inv.address_invoice_id.id, partner=inv.partner_id)
-
- # compute the tax amount of tax_grouped (old wrong amount), grouped by tax rate
- wrong_tax_by_rate = {}
- for inv_tax in tax_grouped.values():
- if not wrong_tax_by_rate.get(inv_tax['tax_id'], False):
- wrong_tax_by_rate[inv_tax['tax_id']] = 0
- wrong_tax_by_rate[inv_tax['tax_id']] += inv_tax['tax_amount']
-
- # compute the difference between correct and wrong amount
- difference_by_rate = {}
- for tax_id in tax_by_rate:
- difference_by_rate[tax_id] = tax_by_rate[tax_id] - wrong_tax_by_rate[tax_id]
-
- for tax_id in difference_by_rate:
- tax = tax_obj.browse(cr, uid, tax_id)
- value_set = False
- # first try to add difference to non deductible tax
- for inv_tax in tax_grouped.values():
- if inv_tax['tax_rate'] == tax.amount:
- if inv_tax['base_code_id'] == False:
- inv_tax['tax_amount'] = inv_tax['tax_amount'] + difference_by_rate[tax_id]
- inv_tax['amount'] = inv_tax['amount'] + difference_by_rate[tax_id]
- value_set = True
- break
- # else add it to the normal tax
- if not value_set:
- for inv_tax in tax_grouped.values():
- if inv_tax['tax_rate'] == tax.amount:
- inv_tax['tax_amount'] = inv_tax['tax_amount'] + difference_by_rate[tax_id]
- inv_tax['amount'] = inv_tax['amount'] + difference_by_rate[tax_id]
- value_set = True
- break
-
+ total_base = 0
+ total_tax = {}
+ total_amount_of_taxes_horizontal = 0
+ number_deductible_account = 0
+ cur_obj = self.pool.get('res.currency')
+ inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id, context=context)
+ cur = inv.currency_id
+ for line in inv.invoice_line:
+ # workout of total amount of taxes
+ for tax in line.invoice_line_tax_id:
+ key = tax['amount']
+ if not key in total_tax:
+ # Total_tax
+ total_tax[key] = [0]
+ total_tax[key][0] += (line.price_unit* (1-(line.discount or 0.0)/100.0)) * tax['amount']
+
+ index = 0
+ for t in tax_grouped.values():
+ if inv.type in ('in_invoice') and t['base_code_id'] == False:
+ number_deductible_account += 1
+ total_amount_of_taxes_horizontal += t['tax_amount']
+
+ total_amount_of_taxes_vertical = 0
+ # round the total amount of taxes
+ for t in total_tax.values():
+ t[0] = cur_obj.round(cr, uid, cur, t[0])
+ total_amount_of_taxes_vertical += t[0]
+ total_amount_of_taxes_vertical = cur_obj.round(cr, uid, cur, total_amount_of_taxes_vertical)
+ total_amount_of_taxes_horizontal = cur_obj.round(cr, uid, cur, total_amount_of_taxes_horizontal)
+ if number_deductible_account != 0:
+ quotient = (total_amount_of_taxes_vertical - total_amount_of_taxes_horizontal) / number_deductible_account
+ quotient = cur_obj.round(cr, uid, cur, quotient)
+ remainder = (total_amount_of_taxes_vertical - total_amount_of_taxes_horizontal) - number_deductible_account * quotient
+ remainder = cur_obj.round(cr, uid, cur, remainder)
+ # change at least a deductible tax amount to to make coincide total amount of taxes
+ counter = 0
+ if inv.type in ('in_invoice') and total_amount_of_taxes_vertical != total_amount_of_taxes_horizontal:
+ for t in tax_grouped.values():
+ if t['base_code_id'] == False:
+ counter += 1
+ t['tax_amount'] = t['tax_amount'] + quotient
+ t['amount'] = t['amount'] + quotient
+ if counter == number_deductible_account:
+ t['tax_amount'] = t['tax_amount'] + remainder
+ t['amount'] = t['amount'] + remainder
return tax_grouped
account_invoice_tax()
=== added directory 'account_invoice_tax_by_column/test'
=== added file 'account_invoice_tax_by_column/test/account_tax.xml'
--- account_invoice_tax_by_column/test/account_tax.xml 1970-01-01 00:00:00 +0000
+++ account_invoice_tax_by_column/test/account_tax.xml 2011-11-04 11:28:23 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data noupdate="1">
+
+ <record id="account_tax_10" model="account.tax">
+ <field name="name">10 %</field>
+ <field name="amount">0.1</field>
+ <field name="line_precision">1</field>
+ </record>
+
+ <record id="account_tax_21" model="account.tax">
+ <field name="name">21 %</field>
+ <field name="amount">0.21</field>
+ <field name="line_precision">1</field>
+ </record>
+
+ </data>
+</openerp>
=== added file 'account_invoice_tax_by_column/test/tax_computation.yml'
--- account_invoice_tax_by_column/test/tax_computation.yml 1970-01-01 00:00:00 +0000
+++ account_invoice_tax_by_column/test/tax_computation.yml 2011-11-04 11:28:23 +0000
@@ -0,0 +1,135 @@
+-
+ In order to test tax computation I create a new customer invoice
+-
+ !record {model: account.invoice, id: account_invoice_customer0}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_zen
+ address_invoice_id: base.res_partner_address_zen
+ company_id: base.main_company
+ currency_id: base.EUR
+ date_invoice: !eval time.strftime('%Y-%m-%d')
+ invoice_line:
+ - account_id: account.a_sale
+ name: '23.83'
+ price_unit: 23.83
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_21
+ - account_id: account.a_sale
+ name: '7.44'
+ price_unit: 7.44
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_21
+ journal_id: account.sales_journal
+ partner_id: base.res_partner_3
+
+-
+ Compute the total tax.
+-
+ !python {model: account.invoice}: |
+ self.button_compute(cr, uid, [ref("account_invoice_customer0")])
+-
+ Then I verify the amount.
+-
+ !assert {model: account.invoice, id: account_invoice_customer0}:
+ - amount_tax == 6.57
+
+-
+ In order to test tax computation I create a new customer invoice
+-
+ !record {model: account.invoice, id: account_invoice_customer1}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_zen
+ address_invoice_id: base.res_partner_address_zen
+ company_id: base.main_company
+ currency_id: base.EUR
+ date_invoice: !eval time.strftime('%Y-%m-%d')
+ invoice_line:
+ - account_id: account.a_sale
+ name: '24.92'
+ price_unit: 24.92
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_21
+ - account_id: account.a_sale
+ name: '7.44'
+ price_unit: 7.44
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_21
+ journal_id: account.sales_journal
+ partner_id: base.res_partner_3
+
+-
+ Compute the total tax.
+-
+ !python {model: account.invoice}: |
+ self.button_compute(cr, uid, [ref("account_invoice_customer1")])
+-
+ Then I verify the amount.
+-
+ !assert {model: account.invoice, id: account_invoice_customer1}:
+ - amount_tax == 6.8
+
+
+-
+ In order to test tax computation I create a new customer invoice
+-
+ !record {model: account.invoice, id: account_invoice_customer2}:
+ account_id: account.a_recv
+ address_contact_id: base.res_partner_address_zen
+ address_invoice_id: base.res_partner_address_zen
+ company_id: base.main_company
+ currency_id: base.EUR
+ date_invoice: !eval time.strftime('%Y-%m-%d')
+ invoice_line:
+ - account_id: account.a_sale
+ name: '1.99'
+ price_unit: 1.99
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ - account_id: account.a_sale
+ name: '0.38'
+ price_unit: 0.38
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ - account_id: account.a_sale
+ name: '5.68'
+ price_unit: 5.68
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ - account_id: account.a_sale
+ name: '0.45'
+ price_unit: 0.45
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ - account_id: account.a_sale
+ name: '1.05'
+ price_unit: 1.05
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ - account_id: account.a_sale
+ name: '2.87'
+ price_unit: 2.87
+ quantity: 1.0
+ invoice_line_tax_id:
+ - account_tax_10
+ journal_id: account.sales_journal
+ partner_id: base.res_partner_3
+
+-
+ Compute the total tax.
+-
+ !python {model: account.invoice}: |
+ self.button_compute(cr, uid, [ref("account_invoice_customer2")])
+-
+ Then I verify the amount.
+-
+ !assert {model: account.invoice, id: account_invoice_customer2}:
+ - amount_tax == 1.24
=== modified file 'l10n_it_vat_registries/account.py'
--- l10n_it_vat_registries/account.py 2011-08-19 13:08:24 +0000
+++ l10n_it_vat_registries/account.py 2011-11-04 11:28:23 +0000
@@ -43,4 +43,24 @@
('name_uniq', 'UNIQUE(name)', 'The tax name must be unique!'),
]
+ def get_main_tax(self, tax):
+ if not tax.parent_id:
+ return tax
+ else:
+ return self.get_main_tax(tax.parent_id)
+
+ def get_account_tax(self, cr, uid, inv_tax_name):
+ splitted_name = inv_tax_name.split(' - ')
+ if len(splitted_name) > 1:
+ tax_name = splitted_name[1]
+ else:
+ tax_name = splitted_name[0]
+ # cerco la tassa per nome, dopo averlo ottenuto dalla tassa in fattura
+ tax_ids = self.search(cr, uid, [('name', '=', tax_name)])
+ if not tax_ids:
+ raise osv.except_osv(_('Error'), _('The tax %s does not exist') % tax_name)
+ if len(tax_ids) > 1:
+ raise osv.except_osv(_('Error'), _('Too many taxes with name %s') % tax_name)
+ return self.browse(cr, uid, tax_ids[0])
+
account_invoice_tax()
Follow ups