Merge lp:~akretion-team/openobject-addons/trunk-add-tax-rounding-option into lp:openobject-addons

Proposed by Alexis de Lattre
Status: Merged
Merged at revision: 7018
Proposed branch: lp:~akretion-team/openobject-addons/trunk-add-tax-rounding-option
Merge into: lp:openobject-addons
Diff against target: 172 lines (+40/-11)
5 files modified
account/account.py (+25/-11)
account/company.py (+6/-0)
account/company_view.xml (+1/-0)
account/res_config.py (+7/-0)
account/res_config_view.xml (+1/-0)
To merge this branch: bzr merge lp:~akretion-team/openobject-addons/trunk-add-tax-rounding-option
Reviewer Review Type Date Requested Status
qdp (OpenERP) Pending
OpenERP Core Team Pending
Review via email: mp+113833@code.launchpad.net

Description of the change

This merge proposal replaces this first merge proposal :

https://code.launchpad.net/~akretion-team/openobject-addons/trunk-addons-tax-calculation-decimal-precision/+merge/103579

It implements the suggestion that Fabien wrote in the comments of the first merge proposal to have a simple option "round per line"/"round globally".

To post a comment you must log in.
Revision history for this message
Lorenzo Battistini (elbati) wrote :
Revision history for this message
Alexis de Lattre (alexis-via) wrote :

@Lorenzo

I am not (yet) familiar with YAML, so I can't review your proposal, sorry.

Revision history for this message
Lorenzo Battistini (elbati) wrote :

On 07/11/2012 10:55 PM, Alexis de Lattre wrote:
> @Lorenzo
>
> I am not (yet) familiar with YAML, so I can't review your proposal, sorry.

Hello Alexis, I just adapted my tests to your implementation and it
passed them.
So, well done :-)

I propose to merge them
<https://code.launchpad.net/%7Eelbati/openobject-addons/add-yaml-tests-for-tax-computation/+merge/114679>
into the account, sale and purchase modules.

Just one remark: as correctly pointed by Ferdinand
<https://lists.launchpad.net/openerp-expert-accounting/msg01728.html>,
there should be the possibility to set the 'Tax calculation rounding
method' at partner and document level. This is because a company could
receive some supplier invoices computed by 'Round per line' and some
others by 'Round globally'. So, user should be able to change the
behaviour according to the case.

Regards and thanks for your work.

--
Lorenzo Battistini
http://planet.domsense.com/en/author/elbati/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account/account.py'
2--- account/account.py 2012-06-26 20:09:09 +0000
3+++ account/account.py 2012-07-07 21:01:19 +0000
4@@ -2066,7 +2066,20 @@
5 'taxes': [] # List of taxes, see compute for the format
6 }
7 """
8+
9+ # By default, for each tax, tax amount will first be computed
10+ # and rounded at the 'Account' decimal precision for each
11+ # PO/SO/invoice line and then these rounded amounts will be
12+ # summed, leading to the total amount for that tax. But, if the
13+ # company has tax_calculation_rounding_method = round_globally,
14+ # we still follow the same method, but we use a much larger
15+ # precision when we round the tax amount for each line (we use
16+ # the 'Account' decimal precision + 5), and that way it's like
17+ # rounding after the sum of the tax amounts of each line
18 precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
19+ tax_compute_precision = precision
20+ if taxes and taxes[0].company_id.tax_calculation_rounding_method == 'round_globally':
21+ tax_compute_precision += 5
22 totalin = totalex = round(price_unit * quantity, precision)
23 tin = []
24 tex = []
25@@ -2075,7 +2088,7 @@
26 tex.append(tax)
27 else:
28 tin.append(tax)
29- tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner)
30+ tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner, precision=tax_compute_precision)
31 for r in tin:
32 totalex -= r.get('amount', 0.0)
33 totlex_qty = 0.0
34@@ -2083,7 +2096,7 @@
35 totlex_qty = totalex/quantity
36 except:
37 pass
38- tex = self._compute(cr, uid, tex, totlex_qty, quantity,product=product, partner=partner)
39+ tex = self._compute(cr, uid, tex, totlex_qty, quantity, product=product, partner=partner, precision=tax_compute_precision)
40 for r in tex:
41 totalin += r.get('amount', 0.0)
42 return {
43@@ -2096,7 +2109,7 @@
44 _logger.warning("Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included")
45 return self._compute(cr, uid, taxes, price_unit, quantity, product, partner)
46
47- def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
48+ def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
49 """
50 Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
51
52@@ -2105,14 +2118,15 @@
53 tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
54 one tax for each tax id in IDS and their children
55 """
56+ if not precision:
57+ precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
58 res = self._unit_compute(cr, uid, taxes, price_unit, product, partner, quantity)
59 total = 0.0
60- precision_pool = self.pool.get('decimal.precision')
61 for r in res:
62 if r.get('balance',False):
63- r['amount'] = round(r.get('balance', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account')) - total
64+ r['amount'] = round(r.get('balance', 0.0) * quantity, precision) - total
65 else:
66- r['amount'] = round(r.get('amount', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account'))
67+ r['amount'] = round(r.get('amount', 0.0) * quantity, precision)
68 total += r['amount']
69 return res
70
71@@ -2188,7 +2202,7 @@
72 r['todo'] = 0
73 return res
74
75- def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
76+ def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
77 """
78 Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
79 Price Unit is a VAT included price
80@@ -2198,15 +2212,15 @@
81 tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
82 one tax for each tax id in IDS and their children
83 """
84+ if not precision:
85+ precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
86 res = self._unit_compute_inv(cr, uid, taxes, price_unit, product, partner=None)
87 total = 0.0
88- obj_precision = self.pool.get('decimal.precision')
89 for r in res:
90- prec = obj_precision.precision_get(cr, uid, 'Account')
91 if r.get('balance',False):
92- r['amount'] = round(r['balance'] * quantity, prec) - total
93+ r['amount'] = round(r['balance'] * quantity, precision) - total
94 else:
95- r['amount'] = round(r['amount'] * quantity, prec)
96+ r['amount'] = round(r['amount'] * quantity, precision)
97 total += r['amount']
98 return res
99
100
101=== modified file 'account/company.py'
102--- account/company.py 2012-05-10 11:38:26 +0000
103+++ account/company.py 2012-07-07 21:01:19 +0000
104@@ -25,6 +25,11 @@
105 _inherit = "res.company"
106 _columns = {
107 'expects_chart_of_accounts': fields.boolean('Expects a Chart of Accounts'),
108+ 'tax_calculation_rounding_method': fields.selection([
109+ ('round_per_line', 'Round per line'),
110+ ('round_globally', 'Round globally'),
111+ ], 'Tax calculation rounding method',
112+ help="If you select 'Round per line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
113 'paypal_account': fields.char("Paypal Account", size=128, help="Paypal username (usually email) for receiving online payments."),
114 'overdue_msg': fields.text('Overdue Payments Message', translate=True),
115 'property_reserve_and_surplus_account': fields.property(
116@@ -39,6 +44,7 @@
117
118 _defaults = {
119 'expects_chart_of_accounts': True,
120+ 'tax_calculation_rounding_method': 'round_per_line',
121 'overdue_msg': '''Dear Sir, dear Madam,
122
123 Our records indicate that some payments on your account are still due. Please find details below.
124
125=== modified file 'account/company_view.xml'
126--- account/company_view.xml 2012-05-29 08:56:42 +0000
127+++ account/company_view.xml 2012-07-07 21:01:19 +0000
128@@ -24,6 +24,7 @@
129 <field name="arch" type="xml">
130 <field name="currency_id" position="after">
131 <field name="property_reserve_and_surplus_account" colspan="2"/>
132+ <field name="tax_calculation_rounding_method" />
133 <field name="paypal_account" placeholder="sales@openerp.com"/>
134 </field>
135 </field>
136
137=== modified file 'account/res_config.py'
138--- account/res_config.py 2012-06-28 11:34:23 +0000
139+++ account/res_config.py 2012-07-07 21:01:19 +0000
140@@ -49,6 +49,12 @@
141 'has_chart_of_accounts': fields.boolean('Company has a chart of accounts'),
142 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', domain="[('visible','=', True)]"),
143 'code_digits': fields.integer('# of Digits', help="No. of Digits to use for account code"),
144+ 'tax_calculation_rounding_method': fields.related('company_id',
145+ 'tax_calculation_rounding_method', type='selection', selection=[
146+ ('round_per_line', 'Round per line'),
147+ ('round_globally', 'Round globally'),
148+ ], string='Tax calculation rounding method',
149+ help="If you select 'Round per line' : for each tax, the tax amount will first be computed and rounded for each PO/SO/invoice line and then these rounded amounts will be summed, leading to the total amount for that tax. If you select 'Round globally': for each tax, the tax amount will be computed for each PO/SO/invoice line, then these amounts will be summed and eventually this total tax amount will be rounded. If you sell with tax included, you should choose 'Round per line' because you certainly want the sum of your tax-included line subtotals to be equal to the total amount with taxes."),
150 'sale_tax': fields.many2one("account.tax.template", "Default Sale Tax"),
151 'purchase_tax': fields.many2one("account.tax.template", "Default Purchase Tax"),
152 'sale_tax_rate': fields.float('Sales Tax (%)'),
153@@ -152,6 +158,7 @@
154 'has_chart_of_accounts': has_chart_of_accounts,
155 'has_fiscal_year': bool(fiscalyear_count),
156 'chart_template_id': False,
157+ 'tax_calculation_rounding_method': company.tax_calculation_rounding_method,
158 }
159 # update journals and sequences
160 for journal_type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):
161
162=== modified file 'account/res_config_view.xml'
163--- account/res_config_view.xml 2012-07-06 14:54:10 +0000
164+++ account/res_config_view.xml 2012-07-07 21:01:19 +0000
165@@ -76,6 +76,7 @@
166 <group>
167 <field name="default_purchase_tax" domain="[('type_tax_use','=','purchase'), ('company_id','=',company_id)]"
168 attrs="{'invisible': [('has_chart_of_accounts','=',False)]}"/>
169+ <field name="tax_calculation_rounding_method" />
170 <field name="module_account_asset"/>
171 <field name="module_account_budget"/>
172 </group>

Subscribers

People subscribed via source and target branches

to all changes: