~archetipo/openobject-italia/caritas_pcomod

« back to all changes in this revision

Viewing changes to l10n_it_partially_deductible_vat/account.py

  • Committer: Lorenzo Battistini
  • Date: 2012-07-17 06:49:52 UTC
  • Revision ID: lorenzo.battistini@agilebg.com-20120717064952-uamv3rgntbohqg41
[REM] account_invoice_tax_by_column l10n_it_partially_deductible_vat

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- encoding: utf-8 -*-
2
 
##############################################################################
3
 
#
4
 
#    OpenERP, Open Source Management Solution
5
 
#    Copyright (C) 2011
6
 
#    Associazione OpenERP Italia (<http://www.openerp-italia.org>)
7
 
#
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.
12
 
#
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.
17
 
#
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/>.
20
 
#
21
 
##############################################################################
22
 
 
23
 
from osv import fields, osv
24
 
import decimal_precision as dp
25
 
from decimal import *
26
 
import time
27
 
 
28
 
class account_tax(osv.osv):
29
 
 
30
 
    _inherit = 'account.tax'
31
 
 
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)
34
 
        
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:
39
 
            for tax in tax_list:
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
50
 
 
51
 
        return res
52
 
 
53
 
account_tax()
54
 
 
55
 
class account_invoice_tax(osv.osv):
56
 
 
57
 
    _inherit = "account.invoice.tax"
58
 
    
59
 
    '''
60
 
    tax_grouped:
61
 
    
62
 
    {(False, 21, 132): {'account_id': 132,
63
 
                    'amount': 12.36,
64
 
                    'base': 61.79,
65
 
                    'base_amount': 61.79,
66
 
                    'base_code_id': 21,
67
 
                    'invoice_id': 1L,
68
 
                    'manual': False,
69
 
                    'name': u'20I5b - IVA al 20% detraibile al 50% (I)',
70
 
                    'sequence': 1,
71
 
                    'tax_amount': 12.36,
72
 
                    'tax_code_id': False},
73
 
    (20, False, 46): {'account_id': 46,
74
 
                   'amount': 12.35,
75
 
                   'base': 61.78,
76
 
                   'base_amount': 61.78,
77
 
                   'base_code_id': False,
78
 
                   'invoice_id': 1L,
79
 
                   'manual': False,
80
 
                   'name': u'20I5a - IVA al 20% detraibile al 50% (D)',
81
 
                   'sequence': 2,
82
 
                   'tax_amount': 12.35,
83
 
                   'tax_code_id': 20},
84
 
    (26, 27, 46): {'account_id': 46,
85
 
                'amount': 24.71,
86
 
                'base': 123.57000000000001,
87
 
                'base_amount': 123.57000000000001,
88
 
                'base_code_id': 27,
89
 
                'invoice_id': 1L,
90
 
                'manual': False,
91
 
                'name': u'20b - Iva al 20% (credito)',
92
 
                'sequence': 1,
93
 
                'tax_amount': 24.71,
94
 
                'tax_code_id': 26}}
95
 
    '''
96
 
    
97
 
    def tax_difference(self, cr, uid, cur, tax_grouped):
98
 
        real_total = 0
99
 
        invoice_total = 0
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')
103
 
        grouped_base = {}
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'])))
111
 
            else:
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
123
 
 
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):
134
 
            return tax_grouped
135
 
        company_currency = invoice.company_id.currency_id.id
136
 
        for inv_tax in tax_grouped.values():
137
 
            # parte detraibile
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():
143
 
                    # parte indetraibile
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)
163
 
                            else:
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)
167
 
 
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'])
171
 
        return tax_grouped
172
 
    
173
 
account_invoice_tax()