[FIX] calender year in VAT listing wizard for Belgium statement
[odoo/odoo.git] / addons / l10n_be / wizard / partner_vat_listing.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution    
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (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 General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22 import wizard
23 import time
24 import datetime
25 import pooler
26 import base64
27 from tools.translate import _
28 import tools
29
30 form = """<?xml version="1.0"?>
31 <form string="Select Fiscal Year">
32     <label string="This wizard will create an XML file for Vat details and total invoiced amounts per partner."  colspan="4"/>
33     <newline/>
34     <field name="date_start" default_focus="1"/>
35     <newline/>
36     <field name="date_stop"/>
37     <newline/>
38     <field name="mand_id" help="Should be provided when subscription of INTERVAT service is done"/>
39     <newline/>
40     <field name="limit_amount" help="Limit under which the partners will not be included into the listing"/>
41     <newline/>
42     <field name="test_xml" help="Set the XML output as test file"/>
43 </form>"""
44
45 fields = {
46     'date_start': {'string':"Start date",'type':'date','required':True ,'default': lambda *a: time.strftime('%Y-01-01')},
47     'date_stop': {'string':"End date",'type':'date','required':True, 'default': lambda *a: time.strftime('%Y-12-01')},
48     'mand_id':{'string':'MandataireId','type':'char','size':'30','required': True,},
49     'limit_amount':{'string':'Limit Amount','type':'integer','required': True, },
50     'test_xml': {'string':'Test XML file', 'type':'boolean', },
51    }
52 msg_form = """<?xml version="1.0"?>
53 <form string="Notification">
54     <separator string="XML File has been Created."  colspan="4"/>
55     <field name="msg" colspan="4" nolabel="1"/>
56     <field name="file_save" />
57 </form>"""
58
59 msg_fields = {
60   'msg': {'string':'File created', 'type':'text', 'size':'100','readonly':True},
61   'file_save':{'string': 'Save File',
62         'type': 'binary',
63         'readonly': True,},
64 }
65
66 class wizard_vat(wizard.interface):
67
68     def _create_xml(self, cr, uid, data, context):
69         datas=[]
70         seq_controlref = pooler.get_pool(cr.dbname).get('ir.sequence').get(cr, uid,'controlref')
71         seq_declarantnum = pooler.get_pool(cr.dbname).get('ir.sequence').get(cr, uid,'declarantnum')
72         obj_cmpny = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid).company_id
73         company_vat = obj_cmpny.partner_id.vat
74         if not company_vat: 
75             raise wizard.except_wizard(_('Data Insufficient'),_('No VAT Number Associated with Main Company!'))
76
77         cref = company_vat + seq_controlref
78         dnum = cref + seq_declarantnum
79
80         p_id_list = pooler.get_pool(cr.dbname).get('res.partner').search(cr,uid,[('vat_subjected','!=',False)])
81
82         if not p_id_list:
83              raise wizard.except_wizard(_('Data Insufficient!'),_('No partner has a VAT Number asociated with him.'))
84         domains = [('date_start','>=',data['form']['date_start']),('date_stop','<=',data['form']['date_stop'])]
85         date_stop = data['form']['date_stop']
86         period_ids = pooler.get_pool(cr.dbname).get('account.period').search(cr, uid, domains)
87         if not period_ids:
88             raise osv.except_osv(_('Warning !'), _('Please select the proper Start date and End Date'))
89         period = "("+','.join(map(lambda x: str(x), period_ids)) +")"
90
91         street = zip_city = country = ''
92         addr = pooler.get_pool(cr.dbname).get('res.partner').address_get(cr, uid, [obj_cmpny.partner_id.id], ['invoice'])
93         if addr.get('invoice',False):
94             ads=pooler.get_pool(cr.dbname).get('res.partner.address').browse(cr,uid,[addr['invoice']])[0]     
95                 
96             zip_city = pooler.get_pool(cr.dbname).get('res.partner.address').get_city(cr,uid,ads.id)
97             if not zip_city:
98                 zip_city = ''
99             if ads.street:
100                 street = ads.street
101             if ads.street2:
102                 street += ads.street2
103             if ads.country_id:
104                 country = ads.country_id.code
105
106         sender_date = time.strftime('%Y-%m-%d')
107         comp_name = obj_cmpny.name
108         data_file = '<?xml version="1.0"?>\n<VatList xmlns="http://www.minfin.fgov.be/VatList" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.minfin.fgov.be/VatList VatList.xml" RecipientId="VAT-ADMIN" SenderId="'+ str(company_vat) + '"'
109         data_file +=' ControlRef="'+ cref + '" MandataireId="'+ data['form']['mand_id'] + '" SenderDate="'+ str(sender_date)+ '"'
110         if data['form']['test_xml']:
111             data_file += ' Test="0"'
112         data_file += ' VersionTech="1.2">'
113         data_file += '\n<AgentRepr DecNumber="1">\n\t<CompanyInfo>\n\t\t<VATNum>'+str(company_vat)+'</VATNum>\n\t\t<Name>'+ comp_name +'</Name>\n\t\t<Street>'+ street +'</Street>\n\t\t<CityAndZipCode>'+ zip_city +'</CityAndZipCode>'
114         data_file += '\n\t\t<Country>'+ country +'</Country>\n\t</CompanyInfo>\n</AgentRepr>'
115         data_comp = '\n<CompanyInfo>\n\t<VATNum>'+str(company_vat)+'</VATNum>\n\t<Name>'+ comp_name +'</Name>\n\t<Street>'+ street +'</Street>\n\t<CityAndZipCode>'+ zip_city +'</CityAndZipCode>\n\t<Country>'+ country +'</Country>\n</CompanyInfo>'
116         data_period = '\n<Period>'+ date_stop[:4] +'</Period>'
117         error_message = []
118
119         for p_id in p_id_list:
120             record = {} # this holds record per partner
121             obj_partner = pooler.get_pool(cr.dbname).get('res.partner').browse(cr,uid,p_id)
122             
123             #This listing is only for customers located in belgium, that's the 
124             #reason why we skip all the partners that haven't their 
125             #(or one of their) default address(es) located in Belgium.
126             go_ahead = False
127             for ads in obj_partner.address:
128                 if ads.type == 'default' and (ads.country_id and ads.country_id.code == 'BE'):
129                     go_ahead = True
130                     break
131             if not go_ahead:
132                 continue
133             query = 'select b.code,sum(credit)-sum(debit) from account_move_line l left join account_account a on (l.account_id=a.id) left join account_account_type b on (a.user_type=b.id) where b.code in ('"'produit'"','"'tax'"') and l.partner_id='+str(p_id)+' and l.period_id in '+period+' group by b.code'
134             cr.execute(query)
135             line_info = cr.fetchall()
136             if not line_info:
137                 continue
138
139             record['vat'] = obj_partner.vat
140
141             #it seems that this listing is only for belgian customers
142             record['country'] = 'BE'
143
144             #...deprecated...
145             #~addr = pooler.get_pool(cr.dbname).get('res.partner').address_get(cr, uid, [obj_partner.id], ['invoice'])
146             
147             #~ if addr.get('invoice',False):
148                 #~ads=pooler.get_pool(cr.dbname).get('res.partner.address').browse(cr,uid,[addr['invoice']])[0] 
149             
150                 #~ if ads.country_id:
151                     #~ record.append(ads.country_id.code)
152                 #~ else:
153                     #~ error_message.append('Data Insufficient! : '+ 'The Partner "'+obj_partner.name + '"'' has no country associated with its Invoice address!')
154                     
155             #~ if len(record)<2:
156                 #~ record.append('')
157                 #~ error_message.append('Data Insufficient! : '+ 'The Partner "'+obj_partner.name + '"'' has no Invoice address!')
158
159             record['amount'] = 0
160             record['turnover'] = 0
161
162             for item in line_info:
163                 if item[0]=='produit':
164                     record['turnover'] += item[1]
165                 else:
166                     record['amount'] += item[1]
167             datas.append(record)
168
169         seq=0
170         data_clientinfo=''
171         sum_tax=0.00
172         sum_turnover=0.00
173         if len(error_message):
174             data['form']['msg']='Exception : \n' +'-'*50+'\n'+ '\n'.join(error_message)
175             return data['form']
176         for line in datas:
177             if line['turnover'] < data['form']['limit_amount']:
178                 continue
179             seq +=1
180             sum_tax +=line['amount']
181             sum_turnover +=line['turnover']
182             data_clientinfo +='\n<ClientList SequenceNum="'+str(seq)+'">\n\t<CompanyInfo>\n\t\t<VATNum>'+line['vat'] +'</VATNum>\n\t\t<Country>'+tools.ustr(line['country']) +'</Country>\n\t</CompanyInfo>\n\t<Amount>'+str(int(line['amount'] * 100)) +'</Amount>\n\t<TurnOver>'+str(int(line['turnover'] * 100)) +'</TurnOver>\n</ClientList>'
183
184         data_decl ='\n<DeclarantList SequenceNum="1" DeclarantNum="'+ dnum + '" ClientNbr="'+ str(seq) +'" TurnOverSum="'+ str(int(sum_turnover * 100)) +'" TaxSum="'+ str(int(sum_tax * 100)) +'" />'
185         data_file += data_decl + data_comp + str(data_period) + data_clientinfo + '\n</VatList>'
186
187         data['form']['msg'] = 'Save the File with '".xml"' extension.'
188         data['form']['file_save'] = base64.encodestring(data_file.encode('utf8'))
189         return data['form']
190
191     states = {
192         'init': {
193             'actions': [],
194             'result': {'type':'form', 'arch':form, 'fields':fields, 'state':[('end','Cancel'),('go','Create XML')]},
195         },
196         'go': {
197             'actions': [_create_xml],
198             'result': {'type':'form', 'arch':msg_form, 'fields':msg_fields, 'state':[('end','Ok')]},
199         }
200
201     }
202
203 wizard_vat('list.vat.detail')
204 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: