1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
6
# Associazione OpenERP Italia (<http://www.openerp-italia.org>)
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU Affero General Public License as
10
# published by the Free Software Foundation, either version 3 of the
11
# License, or (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU Affero General Public License for more details.
18
# You should have received a copy of the GNU Affero General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
##############################################################################
23
from osv import fields, osv
24
import decimal_precision as dp
28
class account_tax(osv.osv):
30
_inherit = 'account.tax'
32
def compute_all(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
33
res = super(account_tax, self).compute_all(cr, uid, taxes, price_unit, quantity, address_id, product, partner)
35
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
36
tax_list = res['taxes']
37
totalex = res['total']
38
if len(tax_list) == 2:
40
if tax.get('balance',False): # Calcolo di imponibili per l'IVA parzialmente detraibile
41
deductible_base = totalex
42
ind_tax = tax_list[abs(tax_list.index(tax)-1)]
43
ind_tax_obj = self.browse(cr, uid, ind_tax['id'])
44
ded_tax_obj = self.browse(cr, uid, tax['id'])
45
base_ind = float(Decimal(str(totalex * ind_tax_obj.amount)).quantize(Decimal('1.'+precision*'0'), rounding=ROUND_HALF_UP))
46
base_ded = float(Decimal(str(totalex - base_ind)).quantize(Decimal('1.'+precision*'0'), rounding=ROUND_HALF_UP))
47
tax_total = float(Decimal(str(tax['balance'])).quantize(Decimal('1.'+precision*'0'), rounding=ROUND_HALF_UP))
48
ind_tax['price_unit'] = base_ind
49
tax['price_unit'] = base_ded
55
class account_invoice_tax(osv.osv):
57
_inherit = "account.invoice.tax"
62
{(False, 21, 132): {'account_id': 132,
69
'name': u'20I5b - IVA al 20% detraibile al 50% (I)',
72
'tax_code_id': False},
73
(20, False, 46): {'account_id': 46,
77
'base_code_id': False,
80
'name': u'20I5a - IVA al 20% detraibile al 50% (D)',
84
(26, 27, 46): {'account_id': 46,
86
'base': 123.57000000000001,
87
'base_amount': 123.57000000000001,
91
'name': u'20b - Iva al 20% (credito)',
97
def tax_difference(self, cr, uid, cur, tax_grouped):
100
cur_obj = self.pool.get('res.currency')
101
tax_obj = self.pool.get('account.tax')
102
tax_code_obj = self.pool.get('account.tax.code')
104
for inv_tax in tax_grouped.values():
105
if inv_tax['tax_code_id']:
106
main_tax = tax_obj.get_main_tax(tax_obj.get_account_tax_by_tax_code(
107
tax_code_obj.browse(cr, uid, inv_tax['tax_code_id'])))
108
elif inv_tax['base_code_id']:
109
main_tax = tax_obj.get_main_tax(tax_obj.get_account_tax_by_base_code(
110
tax_code_obj.browse(cr, uid, inv_tax['base_code_id'])))
112
raise osv.except_osv(_('Error'),
113
_('No tax codes for invoice tax %s') % inv_tax['name'])
114
if not grouped_base.get(main_tax.amount, False):
115
grouped_base[main_tax.amount] = 0
116
grouped_base[main_tax.amount] += inv_tax['base']
117
for tax_rate in grouped_base:
118
real_total += grouped_base[tax_rate] * tax_rate
119
real_total = cur_obj.round(cr, uid, cur, real_total)
120
for inv_tax in tax_grouped.values():
121
invoice_total += inv_tax['amount']
122
return real_total - invoice_total
124
def compute(self, cr, uid, invoice_id, context=None):
125
tax_grouped = super(account_invoice_tax, self).compute(cr, uid, invoice_id, context)
126
inv_obj = self.pool.get('account.invoice')
127
tax_obj = self.pool.get('account.tax')
128
tax_code_obj = self.pool.get('account.tax.code')
129
invoice = inv_obj.browse(cr, uid, invoice_id, context=context)
130
cur = invoice.currency_id
131
tax_difference = self.tax_difference(cr, uid, cur, tax_grouped)
132
cur_obj = self.pool.get('res.currency')
133
if cur_obj.is_zero(cr, uid, cur, tax_difference):
135
company_currency = invoice.company_id.currency_id.id
136
for inv_tax in tax_grouped.values():
138
if not inv_tax['base_code_id'] and inv_tax['tax_code_id']:
139
ded_tax = tax_obj.get_account_tax_by_tax_code(
140
tax_code_obj.browse(cr, uid, inv_tax['tax_code_id']))
141
tax = tax_obj.get_main_tax(ded_tax)
142
for inv_tax_2 in tax_grouped.values():
144
if inv_tax_2['base_code_id'] and not inv_tax_2['tax_code_id']:
145
main_tax = tax_obj.get_main_tax(tax_obj.get_account_tax_by_base_code(
146
tax_code_obj.browse(cr, uid, inv_tax_2['base_code_id'])))
147
# Se hanno la stessa tassa
148
# (Il get_account_tax_by* potrebbe in generale ritornare una qualunque
149
# delle N imposte associate al tax_code. Per la parte indetraibile, il
150
# tax code dovrà sempre avere una sola imposta)
151
if main_tax.id == tax.id:
152
# se risulta un'eccedenza, la tolgo dalla parte detraibile
153
if tax_difference < 0:
154
inv_tax['amount'] = inv_tax['amount'] + tax_difference
155
# se risulta una mancanza, la aggiungo alla parte indetraibile
156
elif tax_difference > 0:
157
inv_tax_2['amount'] = inv_tax_2['amount'] + tax_difference
158
# calcolo l'importo del tax.code relativo all'imposta (la parte indetraibile non lo muove)
159
if invoice.type in ('out_invoice','in_invoice'):
160
inv_tax['tax_amount'] = cur_obj.compute(cr, uid, invoice.currency_id.id, company_currency,
161
inv_tax['amount'] * main_tax['tax_sign'],
162
context={'date': invoice.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
164
inv_tax['tax_amount'] = cur_obj.compute(cr, uid, invoice.currency_id.id, company_currency,
165
inv_tax['amount'] * main_tax['ref_tax_sign'],
166
context={'date': invoice.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
168
inv_tax['amount'] = cur_obj.round(cr, uid, cur, inv_tax['amount'])
169
inv_tax['tax_amount'] = cur_obj.round(cr, uid, cur, inv_tax['tax_amount'])
170
inv_tax_2['amount'] = cur_obj.round(cr, uid, cur, inv_tax_2['amount'])
173
account_invoice_tax()