~bcim/account-invoicing/saas1-belgium

« back to all changes in this revision

Viewing changes to l10n_be_coa_multilang/wizard/l10n_be_vat_intra.py

  • Committer: openerp
  • Date: 2013-02-24 21:17:21 UTC
  • Revision ID: openerp@oerp70-20130224211721-276jiqx175k33onp
update l10n_be_coa_multilang

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6
6
#
7
7
#    Adapted by Noviat to
8
 
#     - make the 'mand_id' field optional
9
8
#     - support Noviat tax code scheme
 
9
#     - align with periodical VAT declaration
10
10
#
11
11
#    This program is free software: you can redistribute it and/or modify
12
12
#    it under the terms of the GNU Affero General Public License as
28
28
from osv import osv, fields
29
29
from tools.translate import _
30
30
from report import report_sxw
 
31
import logging
 
32
_logger = logging.getLogger(__name__)
31
33
 
32
34
class partner_vat_intra(osv.osv_memory):
33
 
    """
34
 
    Partner Vat Intra
35
 
    """
36
 
    _name = "partner.vat.intra"
 
35
    """ VAT Intracom declaration
 
36
    """
 
37
    _name = 'partner.vat.intra'
37
38
    _description = 'Partner VAT Intra'
38
39
 
39
 
    def _get_xml_data(self, cr, uid, context=None):
40
 
        if context.get('file_save', False):
41
 
            return base64.encodestring(context['file_save'].encode('utf8'))
42
 
        return ''
43
 
 
44
 
    def _get_europe_country(self, cursor, user, context=None):
45
 
        return self.pool.get('res.country').search(cursor, user, [('code', 'in', ['AT', 'BG', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB'])])
 
40
    def _get_period(self, cr, uid, context=None):       
 
41
        domain = [('special', '=', False), ('date_stop', '<', time.strftime('%Y-%m-%d'))]
 
42
        result = self.pool.get('account.period').search(cr, uid, domain)
 
43
        return result and result[-1:] or False
 
44
 
 
45
    def _get_europe_country(self, cr, uid, context=None):
 
46
        return self.pool.get('res.country').search(cr, uid, [('code', 'in', ['AT', 'BG', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB'])])
 
47
 
 
48
    def _get_tax_code(self, cr, uid, context=None):
 
49
        obj_tax_code = self.pool.get('account.tax.code')
 
50
        obj_user = self.pool.get('res.users')
 
51
        company_id = obj_user.browse(cr, uid, uid, context=context).company_id.id
 
52
        tax_code_ids = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', False)], context=context)
 
53
        return tax_code_ids and tax_code_ids[0] or False
46
54
 
47
55
    _columns = {
48
56
        'name': fields.char('File Name', size=32),
49
 
        'period_code': fields.char('Period Code',size = 6,required = True, help = '''This is where you have to set the period code for the intracom declaration using the format: ppyyyy
 
57
        'file_save' : fields.binary('Save File', readonly=True),
 
58
        'period_ids': fields.many2many('account.period', 'vat_intra_period_rel', 'acc_id', 'period_id', 'Period (s)', required=True,
 
59
            help='Select here the period(s) you want to include in your Intracom declaration'),
 
60
        'period_code': fields.char('Period Code',size = 6,
 
61
               help = """This field allows you to override the period code for the Intracom declaration.
 
62
      Format: PPYYYY
50
63
      PP can stand for a month: from '01' to '12'.
51
64
      PP can stand for a trimester: '31','32','33','34'
52
65
          The first figure means that it is a trimester,
53
66
          The second figure identify the trimester.
54
67
      PP can stand for a complete fiscal year: '00'.
55
68
      YYYY stands for the year (4 positions).
56
 
    '''
57
 
    ),
58
 
        'period_ids': fields.many2many('account.period', 'account_period_rel', 'acc_id', 'period_id', 'Period (s)', help = 'Select here the period(s) you want to include in your intracom declaration'),
 
69
    """
 
70
        ),
 
71
 
59
72
        'tax_code_id': fields.many2one('account.tax.code', 'Company', domain=[('parent_id', '=', False)], help="Keep empty to use the user's company", required=True),
60
 
        'test_xml': fields.boolean('Test XML file', help="Sets the XML output as test file"),
61
 
        'mand_id' : fields.char('Reference', size=14, help="Reference given by the Representative of the sending company."),
62
 
        'msg': fields.text('File created', size=14, readonly=True),
63
 
        'no_vat': fields.text('Partner With No VAT', size=14, readonly=True, help="The Partner whose VAT number is not defined  and they are not included in XML File."),
64
 
        'file_save' : fields.binary('Save File', readonly=True),
65
73
        'country_ids': fields.many2many('res.country', 'vat_country_rel', 'vat_id', 'country_id', 'European Countries'),
66
74
        'comments': fields.text('Comments'),
67
75
        }
68
76
 
69
 
    def _get_tax_code(self, cr, uid, context=None):
70
 
        obj_tax_code = self.pool.get('account.tax.code')
71
 
        obj_user = self.pool.get('res.users')
72
 
        company_id = obj_user.browse(cr, uid, uid, context=context).company_id.id
73
 
        tax_code_ids = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', False)], context=context)
74
 
        return tax_code_ids and tax_code_ids[0] or False
75
 
 
76
77
    _defaults = {
 
78
        'period_ids': _get_period,
77
79
        'country_ids': _get_europe_country,
78
 
        'file_save': _get_xml_data,
79
 
        'name': 'vat_intra.xml',
80
80
        'tax_code_id': _get_tax_code,
81
81
    }
82
82
 
83
83
    def _get_datas(self, cr, uid, ids, context=None):
84
 
        """Collects require data for vat intra xml
 
84
        """Collects required data for vat intra xml
85
85
        :param ids: id of wizard.
86
86
        :return: dict of all data to be used to generate xml for Partner VAT Intra.
87
87
        :rtype: dict
112
112
        company_vat = company_vat.replace(' ','').upper()
113
113
        issued_by = company_vat[:2]
114
114
 
115
 
        if len(wiz_data.period_code) != 6:
 
115
        if wiz_data.period_code and len(wiz_data.period_code) != 6:
116
116
            raise osv.except_osv(_('Error!'), _('Period code is not valid.'))
117
117
 
118
118
        if not wiz_data.period_ids:
147
147
            raise osv.except_osv(_('Insufficient Data!'),_('No email address associated with the company.'))
148
148
        if not phone:
149
149
            raise osv.except_osv(_('Insufficient Data!'),_('No phone associated with the company.'))
 
150
 
 
151
        account_periods = wiz_data.period_ids
 
152
 
 
153
        period_end_dates = sorted([x.date_stop for x in account_periods])
 
154
        period_start_dates = sorted([x.date_start for x in account_periods])                    
 
155
        
 
156
        starting_month = period_start_dates[0][5:7]
 
157
        ending_month = period_end_dates[-1][5:7]
 
158
        year = period_end_dates[-1][:4]
 
159
        quarter = str(((int(starting_month) - 1) / 3) + 1)
 
160
 
150
161
        xmldict.update({
151
 
                        'company_name': data_company.name,
152
 
                        'company_vat': company_vat,
153
 
                        'vatnum':  company_vat[2:],
154
 
                        'mand_id': wiz_data.mand_id,
155
 
                        'sender_date': str(time.strftime('%Y-%m-%d')),
156
 
                        'street': street,
157
 
                        'city': city,
158
 
                        'post_code': post_code,
159
 
                        'country': country,
160
 
                        'email': email,
161
 
                        'phone': phone.replace('/','').replace('.','').replace('(','').replace(')','').replace(' ',''),
162
 
                        'period': wiz_data.period_code,
163
 
                        'clientlist': [],
164
 
                        'comments': comments,
165
 
                        'issued_by': issued_by,
166
 
                        })
 
162
            'company_name': data_company.name,
 
163
            'company_vat': company_vat,
 
164
            'vatnum':  company_vat[2:],
 
165
            #'mand_id': wiz_data.mand_id, # dropped since also not supported in periodical VAT declaration
 
166
            'sender_date': str(time.strftime('%Y-%m-%d')),
 
167
            'street': street,
 
168
            'city': city,
 
169
            'post_code': post_code,
 
170
            'country': country,
 
171
            'email': email,
 
172
            'phone': phone.replace('/','').replace('.','').replace('(','').replace(')','').replace(' ',''),
 
173
            'period_code': wiz_data.period_code,             
 
174
            'quarter': quarter,
 
175
            'starting_month': starting_month,
 
176
            'ending_month': ending_month,
 
177
            'year': year,
 
178
            'clientlist': [],
 
179
            'comments': comments,
 
180
            'issued_by': issued_by,
 
181
            })
167
182
 
168
183
        codes = ('44', '46L', '46T', '48s44', '48s46L', '48s46T')
169
 
        cr.execute('''SELECT p.name As partner_name, l.partner_id AS partner_id, p.vat AS vat,
 
184
        cr.execute('''SELECT p.name AS partner_name, l.partner_id AS partner_id, p.vat AS vat,
170
185
                      (CASE WHEN t.code = '48s44' THEN '44'
171
186
                            WHEN t.code = '48s46L' THEN '46L'
172
187
                            WHEN t.code = '48s46T' THEN '46T'
173
188
                       ELSE t.code END) AS intra_code,
174
 
                      SUM(CASE WHEN t.code in ('48s44','48s46L','48s46T') THEN -l.tax_amount ELSE l.tax_amount END) AS amount
 
189
                      SUM(CASE WHEN t.code IN ('48s44','48s46L','48s46T') THEN -l.tax_amount ELSE l.tax_amount END) AS amount
175
190
                      FROM account_move_line l
176
191
                      LEFT JOIN account_tax_code t ON (l.tax_code_id = t.id)
177
192
                      LEFT JOIN res_partner p ON (l.partner_id = p.id)
178
193
                      WHERE t.code IN %s
179
194
                       AND l.period_id IN %s
180
195
                       AND t.company_id = %s
181
 
                      GROUP BY p.name, l.partner_id, p.vat, intra_code''', (codes, tuple([p.id for p in wiz_data.period_ids]), data_company.id))
 
196
                      GROUP BY p.name, l.partner_id, p.vat, intra_code''', 
 
197
            (codes, tuple([p.id for p in wiz_data.period_ids]), data_company.id))
 
198
        
 
199
        rows = cr.dictfetchall()       
 
200
        if not rows:
 
201
            raise osv.except_osv(_('No Data Available'), _('No intracom transactions found for the selected period(s) !'))           
182
202
 
183
203
        p_count = 0
184
 
 
185
 
        for row in cr.dictfetchall():
 
204
        for row in rows:
186
205
            if not row['vat']:
187
206
                row['vat'] = ''
188
207
                p_count += 1
194
213
            intra_code = row['intra_code'] == '44' and 'S' or (row['intra_code'] == '46L' and 'L' or (row['intra_code'] == '46T' and 'T' or ''))
195
214
 
196
215
            xmldict['clientlist'].append({
197
 
                                        'partner_name': row['partner_name'],
198
 
                                        'seq': seq,
199
 
                                        'vatnum': row['vat'][2:].replace(' ','').upper(),
200
 
                                        'vat': row['vat'],
201
 
                                        'country': row['vat'][:2].upper(),
202
 
                                        'amount': amt,
203
 
                                        'intra_code': row['intra_code'],
204
 
                                        'code': intra_code})
 
216
                'partner_name': row['partner_name'],
 
217
                'seq': seq,
 
218
                'vatnum': row['vat'][2:].replace(' ','').upper(),
 
219
                'vat': row['vat'],
 
220
                'country': row['vat'][:2].upper(),
 
221
                'amount': amt,
 
222
                'amount': '%.2f' %amt, # used in xml
 
223
                'amt': amt,            # used in pdf      
 
224
                'intra_code': row['intra_code'],
 
225
                'code': intra_code})
205
226
 
206
 
        xmldict.update({'dnum': dnum, 'clientnbr': str(seq), 'amountsum': amount_sum, 'partner_wo_vat': p_count})
 
227
        xmldict.update({
 
228
            'dnum': dnum, 
 
229
            'clientnbr': str(seq), 
 
230
            'amountsum': '%.2f' %amount_sum, # used in xml
 
231
            'amtsum': amount_sum, # used in pdf  
 
232
            'partner_wo_vat': p_count})
207
233
        return xmldict
208
234
 
209
 
    def create_xml(self, cursor, user, ids, context=None):
 
235
    def create_xml(self, cr, uid, ids, context=None):
210
236
        """Creates xml that is to be exported and sent to estate for partner vat intra.
211
237
        :return: Value for next action.
212
238
        :rtype: dict
213
239
        """
214
240
        mod_obj = self.pool.get('ir.model.data')
215
 
        xml_data = self._get_datas(cursor, user, ids, context=context)
216
 
        month_quarter = xml_data['period'][:2]
217
 
        year = xml_data['period'][2:]
 
241
        xml_data = self._get_datas(cr, uid, ids, context=context)
218
242
        data_file = ''
219
243
 
220
244
        # Can't we do this by etree?
230
254
        <EmailAddress>%(email)s</EmailAddress>
231
255
        <Phone>%(phone)s</Phone>
232
256
    </ns2:Representative>""" % (xml_data)
233
 
        if xml_data['mand_id']:
234
 
            data_head += '\n\t\t<ns2:RepresentativeReference>%(mand_id)s</ns2:RepresentativeReference>' % (xml_data)
 
257
        #if xml_data['mand_id']:
 
258
        #    data_head += '\n\t\t<ns2:RepresentativeReference>%(mand_id)s</ns2:RepresentativeReference>' % (xml_data)
235
259
        data_comp_period = '\n\t\t<ns2:Declarant>\n\t\t\t<VATNumber>%(vatnum)s</VATNumber>\n\t\t\t<Name>%(company_name)s</Name>\n\t\t\t<Street>%(street)s</Street>\n\t\t\t<PostCode>%(post_code)s</PostCode>\n\t\t\t<City>%(city)s</City>\n\t\t\t<CountryCode>%(country)s</CountryCode>\n\t\t\t<EmailAddress>%(email)s</EmailAddress>\n\t\t\t<Phone>%(phone)s</Phone>\n\t\t</ns2:Declarant>' % (xml_data)
236
 
        if month_quarter.startswith('3'):
237
 
            data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>'+month_quarter[1]+'</ns2:Quarter> \n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
238
 
        elif month_quarter.startswith('0') and month_quarter.endswith('0'):
239
 
            data_comp_period+= '\n\t\t<ns2:Period>\n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
 
260
 
 
261
        if xml_data['period_code']:
 
262
            month_quarter = xml_data['period_code'][:2]
 
263
            year = xml_data['period_code'][2:]
 
264
            if month_quarter.startswith('3'):
 
265
                data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>'+month_quarter[1]+'</ns2:Quarter> \n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
 
266
            elif month_quarter.startswith('0') and month_quarter.endswith('0'):
 
267
                data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
 
268
            else:
 
269
                data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>'+month_quarter+'</ns2:Month> \n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
240
270
        else:
241
 
            data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>'+month_quarter+'</ns2:Month> \n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
 
271
            year = xml_data['year']
 
272
            if xml_data['starting_month'] != xml_data['ending_month']:
 
273
                month_quarter = '3' + xml_data['quarter']
 
274
                #starting month and ending month of selected period are not the same
 
275
                #it means that the accounting is not based on periods of 1 month but on quarters
 
276
                data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>%(quarter)s</ns2:Quarter> \n\t\t\t<ns2:Year>%(year)s</ns2:Year>\n\t\t</ns2:Period>' % (xml_data)
 
277
            else:
 
278
                month_quarter = xml_data['ending_month']
 
279
                data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>'+xml_data['ending_month']+'</ns2:Month> \n\t\t\t<ns2:Year>%(year)s</ns2:Year>\n\t\t</ns2:Period>' % (xml_data)
242
280
 
243
281
        data_clientinfo = ''
244
282
        for client in xml_data['clientlist']:
248
286
 
249
287
        data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum)s">' % (xml_data)
250
288
 
251
 
        data_file += data_head + data_decl + data_comp_period + data_clientinfo + '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' % (xml_data)
252
 
        context['file_save'] = data_file
253
 
 
254
 
        model_data_ids = mod_obj.search(cursor, user,[('model','=','ir.ui.view'),('name','=','view_vat_intra_save')], context=context)
255
 
        resource_id = mod_obj.read(cursor, user, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
 
289
        data_file += data_head + data_decl + data_comp_period + data_clientinfo
 
290
        if xml_data['comments']:
 
291
            data_file += '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>' % (xml_data)
 
292
        data_file += '\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' 
 
293
 
 
294
        self.write(cr, uid, ids, {
 
295
            'file_save': base64.encodestring(data_file.encode('utf8')), 
 
296
            'name': 'vat_intra_%s_%s.xml' %(year, month_quarter[0] == '3' and ('Q' + month_quarter[1]) or month_quarter),
 
297
            }, context=context)
 
298
 
 
299
        model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_vat_intra_save')], context=context)
 
300
        resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
256
301
 
257
302
        return {
258
303
            'name': _('Save'),
259
304
            'context': context,
260
305
            'view_type': 'form',
261
306
            'view_mode': 'form',
 
307
            'res_id': ids[0],
262
308
            'res_model': 'partner.vat.intra',
263
309
            'views': [(resource_id,'form')],
264
310
            'view_id': 'view_vat_intra_save',
275
321
        }
276
322
        return {
277
323
            'type': 'ir.actions.report.xml',
278
 
            'report_name': 'partner.vat.intra.print',
 
324
            'report_name': 'partner.vat.intra.print_nov',
279
325
            'datas': datas,
280
326
        }
281
327