Merge lp:~therp-nl/openobject-addons/7.0-lp827649-voucher_tax_inclusive into lp:openobject-addons

Proposed by Stefan Rijnhart (Opener)
Status: Needs review
Proposed branch: lp:~therp-nl/openobject-addons/7.0-lp827649-voucher_tax_inclusive
Merge into: lp:openobject-addons
Diff against target: 186 lines (+55/-58)
1 file modified
account_voucher/account_voucher.py (+55/-58)
To merge this branch: bzr merge lp:~therp-nl/openobject-addons/7.0-lp827649-voucher_tax_inclusive
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+136534@code.launchpad.net

Description of the change

This branch adds support for using inclusive taxes on sales and purchase vouchers.

Tax is only computed using the account.tax model. As the workflow did not force this, the call to compute_tax() was added to action_move_line_create(). Compute_tax() was then modified to do nothing in the case of payment or receipt vouchers.

Using an inclusive tax can lead to small rounding differences that were not caught by the manual summing of voucher line amounts, and thus to unbalanced moves. This summing was therefore replaced with a call to account_move._compute_balance() on the voucher's move so that the writeoff amount is always correct (by definition).

To post a comment you must log in.

Unmerged revisions

8143. By Stefan Rijnhart (Opener)

[FIX] Indentation
[FIX] Remove domain on inclusive taxes from the voucher's tax

8142. By Stefan Rijnhart (Opener)

[FIX] lp:827649, account_voucher: generate correct move lines using inclusive tax

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_voucher/account_voucher.py'
2--- account_voucher/account_voucher.py 2012-12-06 15:38:56 +0000
3+++ account_voucher/account_voucher.py 2012-12-12 15:16:22 +0000
4@@ -311,7 +311,7 @@
5 ('pay_now','Pay Directly'),
6 ('pay_later','Pay Later or Group Funds'),
7 ],'Payment', select=True, readonly=True, states={'draft':[('readonly',False)]}),
8- 'tax_id': fields.many2one('account.tax', 'Tax', readonly=True, states={'draft':[('readonly',False)]}, domain=[('price_include','=', False)], help="Only for tax excluded from price"),
9+ 'tax_id': fields.many2one('account.tax', 'Tax', readonly=True, states={'draft':[('readonly',False)]}),
10 'pre_line':fields.boolean('Previous Payments ?', required=False),
11 'date_due': fields.date('Due Date', readonly=True, select=True, states={'draft':[('readonly',False)]}),
12 'payment_option':fields.selection([
13@@ -356,50 +356,50 @@
14 return voucher
15
16 def compute_tax(self, cr, uid, ids, context=None):
17+ """
18+ Map vouchers' taxes through the partners' fiscal positions. Apply
19+ the resulting taxes to the individual voucher lines. Store the calculated
20+ untaxed amount on each line. Calculate and store the voucher's total amount,
21+ which is including tax, as well as the total tax amount of the voucher.
22+ Do nothing in the case of payment or receipt vouchers, as in their
23+ case the total amount is not calculated, but keeps its given value.
24+
25+ :returns: nothing
26+ """
27 tax_pool = self.pool.get('account.tax')
28 partner_pool = self.pool.get('res.partner')
29 position_pool = self.pool.get('account.fiscal.position')
30 voucher_line_pool = self.pool.get('account.voucher.line')
31 voucher_pool = self.pool.get('account.voucher')
32- if context is None: context = {}
33
34 for voucher in voucher_pool.browse(cr, uid, ids, context=context):
35+ if voucher.type in ['payment', 'receipt']:
36+ continue
37+ total_tax = 0.0
38 voucher_amount = 0.0
39+ tax = False
40+ if voucher.tax_id:
41+ tax = [tax_pool.browse(cr, uid, voucher.tax_id.id, context=context)]
42+ partner = partner_pool.browse(cr, uid, voucher.partner_id.id, context=context) or False
43+ taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
44+ tax = tax_pool.browse(cr, uid, taxes, context=context)
45 for line in voucher.line_ids:
46- voucher_amount += line.untax_amount or line.amount
47- line.amount = line.untax_amount or line.amount
48- voucher_line_pool.write(cr, uid, [line.id], {'amount':line.amount, 'untax_amount':line.untax_amount})
49-
50- if not voucher.tax_id:
51- self.write(cr, uid, [voucher.id], {'amount':voucher_amount, 'tax_amount':0.0})
52- continue
53-
54- tax = [tax_pool.browse(cr, uid, voucher.tax_id.id, context=context)]
55- partner = partner_pool.browse(cr, uid, voucher.partner_id.id, context=context) or False
56- taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
57- tax = tax_pool.browse(cr, uid, taxes, context=context)
58-
59- total = voucher_amount
60- total_tax = 0.0
61-
62- if not tax[0].price_include:
63- for line in voucher.line_ids:
64- for tax_line in tax_pool.compute_all(cr, uid, tax, line.amount, 1).get('taxes', []):
65- total_tax += tax_line.get('amount', 0.0)
66- total += total_tax
67- else:
68- for line in voucher.line_ids:
69- line_total = 0.0
70- line_tax = 0.0
71-
72- for tax_line in tax_pool.compute_all(cr, uid, tax, line.untax_amount or line.amount, 1).get('taxes', []):
73- line_tax += tax_line.get('amount', 0.0)
74- line_total += tax_line.get('price_unit')
75- total_tax += line_tax
76- untax_amount = line.untax_amount or line.amount
77- voucher_line_pool.write(cr, uid, [line.id], {'amount':line_total, 'untax_amount':untax_amount})
78-
79- self.write(cr, uid, [voucher.id], {'amount':total, 'tax_amount':total_tax})
80+ untax_amount = 0.0
81+ if tax and line.amount:
82+ tax_computed = tax_pool.compute_all(cr, uid, tax, line.amount, 1)
83+ untax_amount = tax_computed.get('total', 0.0)
84+ voucher_amount += line.amount
85+ voucher_line_pool.write(cr, uid, [line.id], {'untax_amount': untax_amount or line.amount})
86+ if tax:
87+ tax_computed = tax_pool.compute_all(cr, uid, tax, voucher_amount, 1)
88+ for tax_line in tax_computed.get('taxes', []):
89+ total_tax += tax_line.get('amount', 0.0)
90+ voucher_amount = tax_computed.get('total_included', 0.0) or voucher_amount
91+
92+ self.write(cr, uid, [voucher.id], {
93+ 'amount': voucher_amount,
94+ 'tax_amount': total_tax,
95+ })
96 return True
97
98 def onchange_price(self, cr, uid, ids, line_ids, tax_id, partner_id=False, context=None):
99@@ -420,23 +420,23 @@
100 for line in line_ids:
101 line_amount = 0.0
102 line_amount = line.get('amount',0.0)
103-
104- if tax_id:
105- tax = [tax_pool.browse(cr, uid, tax_id, context=context)]
106- if partner_id:
107- partner = partner_pool.browse(cr, uid, partner_id, context=context) or False
108- taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
109- tax = tax_pool.browse(cr, uid, taxes, context=context)
110-
111- if not tax[0].price_include:
112- for tax_line in tax_pool.compute_all(cr, uid, tax, line_amount, 1).get('taxes', []):
113- total_tax += tax_line.get('amount')
114-
115 voucher_total += line_amount
116- total = voucher_total + total_tax
117+
118+ total = voucher_total
119+ if tax_id:
120+ tax = [tax_pool.browse(cr, uid, tax_id, context=context)]
121+ if partner_id:
122+ partner = partner_pool.browse(cr, uid, partner_id, context=context) or False
123+ taxes = position_pool.map_tax(cr, uid, partner and partner.property_account_position or False, tax)
124+ tax = tax_pool.browse(cr, uid, taxes, context=context)
125+
126+ tax_computed = tax_pool.compute_all(cr, uid, tax, voucher_total, 1)
127+ for tax_line in tax_computed.get('taxes', []):
128+ total_tax += tax_line.get('amount', 0.0)
129+ total = tax_computed.get('total_included', 0.0)
130
131 res.update({
132- 'amount': total or voucher_total,
133+ 'amount': total,
134 'tax_amount': total_tax
135 })
136 return {
137@@ -1074,7 +1074,6 @@
138 move_line_obj = self.pool.get('account.move.line')
139 currency_obj = self.pool.get('res.currency')
140 tax_obj = self.pool.get('account.tax')
141- tot_line = line_total
142 rec_lst_ids = []
143
144 voucher_brw = self.pool.get('account.voucher').browse(cr, uid, voucher_id, context)
145@@ -1117,10 +1116,8 @@
146 line.type = 'dr'
147
148 if (line.type=='dr'):
149- tot_line += amount
150 move_line['debit'] = amount
151 else:
152- tot_line -= amount
153 move_line['credit'] = amount
154
155 if voucher_brw.tax_id and voucher_brw.type in ('sale', 'purchase'):
156@@ -1189,6 +1186,7 @@
157 if line.move_line_id.id:
158 rec_lst_ids.append(rec_ids)
159
160+ tot_line = self.pool.get('account.move')._compute_balance(cr, uid, move_id, context=context)
161 return (tot_line, rec_lst_ids)
162
163 def writeoff_move_line_get(self, cr, uid, voucher_id, line_total, move_id, name, company_currency, current_currency, context=None):
164@@ -1266,6 +1264,7 @@
165 context = {}
166 move_pool = self.pool.get('account.move')
167 move_line_pool = self.pool.get('account.move.line')
168+ self.compute_tax(cr, uid, ids, context=context)
169 for voucher in self.browse(cr, uid, ids, context=context):
170 if voucher.move_id:
171 continue
172@@ -1283,12 +1282,10 @@
173 # Create the first line of the voucher
174 move_line_id = move_line_pool.create(cr, uid, self.first_move_line_get(cr,uid,voucher.id, move_id, company_currency, current_currency, context), context)
175 move_line_brw = move_line_pool.browse(cr, uid, move_line_id, context=context)
176- line_total = move_line_brw.debit - move_line_brw.credit
177 rec_list_ids = []
178- if voucher.type == 'sale':
179- line_total = line_total - self._convert_amount(cr, uid, voucher.tax_amount, voucher.id, context=ctx)
180- elif voucher.type == 'purchase':
181- line_total = line_total + self._convert_amount(cr, uid, voucher.tax_amount, voucher.id, context=ctx)
182+ balance = move_line_brw.debit - move_line_brw.credit
183+ sign = balance / abs(balance)
184+ line_total = sign * self._convert_amount(cr, uid, voucher.amount, voucher.id, context=ctx)
185 # Create one move line per voucher line where amount is not 0.0
186 line_total, rec_list_ids = self.voucher_move_line_create(cr, uid, voucher.id, line_total, move_id, company_currency, current_currency, context)
187

Subscribers

People subscribed via source and target branches

to all changes: