[FIX] l10n_be: merge changed for intervat 8 compatiblity
authorNoviat <>
Tue, 17 Apr 2012 13:53:40 +0000 (15:53 +0200)
committerXavier ALT <xal@openerp.com>
Tue, 17 Apr 2012 13:53:40 +0000 (15:53 +0200)
bzr revid: xal@openerp.com-20120417135340-u4zrilkkfv8mlpb5

addons/l10n_be/wizard/l10n_be_account_vat_declaration.py
addons/l10n_be/wizard/l10n_be_account_vat_declaration_view.xml
addons/l10n_be/wizard/l10n_be_vat_intra.py

index bc635e0..1595ffb 100644 (file)
@@ -3,6 +3,13 @@
 #
 #    OpenERP, Open Source Management Solution
 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#    
+#    Adapted by Noviat to 
+#     - enforce correct vat number
+#     - support negative balance
+#     - assign amount of tax code 71-72 correclty to grid 71 or 72
+#     - support Noviat tax code scheme
+#     - support multiple accounting periods per VAT declaration
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
@@ -35,18 +42,30 @@ class l10n_be_vat_declaration(osv.osv_memory):
 
     _columns = {
         'name': fields.char('File Name', size=32),
-        'period_id': fields.many2one('account.period','Period', required=True),
-        'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', domain=[('parent_id', '=', False)]),
+        'period_id': fields.many2one('account.period','Period'), # kept for backward compatibility! you should use new 'period_ids' field
+        '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 VAT declaration'),
+        'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', domain=[('parent_id', '=', False)], required=True),
         'msg': fields.text('File created', size=64, readonly=True),
         'file_save': fields.binary('Save File'),
         'ask_resitution': fields.boolean('Ask Restitution',help='It indicates whether a resitution is to made or not?'),
         'ask_payment': fields.boolean('Ask Payment',help='It indicates whether a payment is to made or not?'),
-        'client_nihil': fields.boolean('Last Declaration of Enterprise',help='Tick this case only if it concerns only the last statement on the civil or cessation of activity'),
+        'client_nihil': fields.boolean('Last Declaration, no clients in client listing', help='Tick this case only if it concerns only the last statement on the civil or cessation of activity: ' \
+            'no clients to be included in the client listing.'),
+        'comments': fields.text('Comments'),
     }
+
+    def _get_tax_code(self, cr, uid, context=None):
+        obj_tax_code = self.pool.get('account.tax.code')
+        obj_user = self.pool.get('res.users')
+        company_id = obj_user.browse(cr, uid, uid, context=context).company_id.id
+        tax_code_ids = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', False)], context=context)
+        return tax_code_ids and tax_code_ids[0] or False
+
     _defaults = {
         'msg': 'Save the File with '".xml"' extension.',
         'file_save': _get_xml_data,
         'name': 'vat_declaration.xml',
+        'tax_code_id': _get_tax_code,
     }
 
     def create_xml(self, cr, uid, ids, context=None):
@@ -58,8 +77,12 @@ class l10n_be_vat_declaration(osv.osv_memory):
         if context is None:
             context = {}
 
-        list_of_tags = ['00','01','02','03','44','45','46','47','48','49','54','55','56','57','59','61','62','63','64','71','81','82','83','84','85','86','87','88','91']
+        list_of_tags = ['00','01','02','03','44','45','46','47','48','49','54','55','56','57','59','61','62','63','64','71','72','81','82','83','84','85','86','87','88','91']
         data_tax = self.browse(cr, uid, ids[0])
+
+        if not data_tax.period_id and not data_tax.period_ids:
+            raise osv.except_osv(_('Data Insufficient!'),_('Please select at least one Period.'))
+
         if data_tax.tax_code_id:
             obj_company = data_tax.tax_code_id.company_id
         else:
@@ -67,48 +90,135 @@ class l10n_be_vat_declaration(osv.osv_memory):
         vat_no = obj_company.partner_id.vat
         if not vat_no:
             raise osv.except_osv(_('Data Insufficient'), _('No VAT Number Associated with Main Company!'))
+        vat_no = vat_no.replace(' ','').upper()
+        vat = vat_no[2:]
 
-        tax_code_ids = obj_tax_code.search(cr, uid, [], context=context)
+        tax_code_ids = obj_tax_code.search(cr, uid, [('parent_id','child_of',data_tax.tax_code_id.id), ('company_id','=',obj_company.id)], context=context)
         ctx = context.copy()
         data  = self.read(cr, uid, ids)[0]
-        ctx['period_id'] = data['period_id'] #added context here
-        tax_info = obj_tax_code.read(cr, uid, tax_code_ids, ['code','sum_period'], context=ctx)
-
-        address = post_code = city = country_code = ''
+        tax_info = {}
+        if data['period_id']:
+            # using the old wizard view - convert it to period_ids
+            data_period = data['period_id']
+            if isinstance(data_period, (list,tuple)):
+                data_period = data_period[0]
+            data['period_ids'] = [ data_period ]
+        for period_id in data['period_ids']:
+            ctx['period_id'] = period_id #added context here
+            tax_period_info = obj_tax_code.read(cr, uid, tax_code_ids, ['code','sum_period'], context=ctx)
+            for c in tax_period_info:
+                tax_info.update({c['code']: tax_info.get(c['code'], 0.0) + c['sum_period']})
+
+        name = email = phone = address = post_code = city = country_code = ''
         city, post_code, address, country_code = self.pool.get('res.company')._get_default_ad(obj_company.partner_id.address)
-
-        account_period = obj_acc_period.browse(cr, uid, data['period_id'], context=context)
-
-        send_ref = str(obj_company.partner_id.id) + str(account_period.date_start[5:7]) + str(account_period.date_stop[:4])
-        data_of_file = '<?xml version="1.0"?>\n<VATSENDING xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="MultiDeclarationTVA-NoSignature-16.xml">'
-        data_of_file +='\n\t<DECLARER>\n\t\t<VATNUMBER>'+str(vat_no)+'</VATNUMBER>\n\t\t<NAME>'+ obj_company.name +'</NAME>\n\t\t<ADDRESS>'+address+'</ADDRESS>'
-        data_of_file +='\n\t\t<POSTCODE>'+post_code+'</POSTCODE>\n\t\t<CITY>'+city+'</CITY>\n\t\t<COUNTRY>'+country_code+'</COUNTRY>\n\t\t<SENDINGREFERENCE>'+send_ref+'</SENDINGREFERENCE>\n\t</DECLARER>'
-        data_of_file +='\n\t<VATRECORD>\n\t\t<RECNUM>1</RECNUM>\n\t\t<VATNUMBER>'+((vat_no and str(vat_no[2:])) or '')+'</VATNUMBER>\n\t\t<DPERIODE>\n\t\t\t'
-
-        starting_month = account_period.date_start[5:7]
-        ending_month = account_period.date_stop[5:7]
+        for addr in obj_company.partner_id.address:
+            if addr.type == 'default':
+                name = addr.name or ""
+                email = addr.email or ""
+                phone = addr.email or ""
+                break
+
+        account_periods = obj_acc_period.browse(cr, uid, data['period_ids'], context=context)
+        issued_by = vat_no[:2] 
+        comments = data['comments'] or ''
+        
+        period_end_dates = sorted([x.date_stop for x in account_periods])
+        period_start_dates = sorted([x.date_start for x in account_periods])        
+        send_ref = str(obj_company.partner_id.id) + period_end_dates[0][5:7] + period_end_dates[-1][:4]
+        
+        starting_month = period_start_dates[0][5:7]
+        ending_month = period_end_dates[-1][5:7]
+        quarter = str(((int(starting_month) - 1) / 3) + 1)
+    
+        if not country_code:
+            raise osv.except_osv(_('Data Insufficient!'),_('No country associated with the company.'))
+        if not email:
+            raise osv.except_osv(_('Data Insufficient!'),_('No email address associated with the company.'))
+        if not phone:
+            raise osv.except_osv(_('Data Insufficient!'),_('No phone associated with the company.'))
+        file_data = {
+                        'issued_by': issued_by,
+                        'vat_no': vat_no,
+                        'only_vat': vat_no[2:],
+                        'cmpny_name': obj_company.name,
+                        'address': address,
+                        'post_code': post_code,
+                        'city': city,
+                        'country_code': country_code,
+                        'email': email,
+                        'phone': phone.replace('.','').replace('/','').replace('(','').replace(')','').replace(' ',''),
+                        'send_ref': send_ref,
+                        'quarter': quarter,
+                        'month': starting_month,
+                        'year': period_end_dates[-1][:4],
+                        'client_nihil': (data['client_nihil'] and 'YES' or 'NO'),
+                        'ask_restitution': (data['ask_resitution'] and 'YES' or 'NO'),
+                        'ask_payment': (data['ask_payment'] and 'YES' or 'NO'),
+                        'comments': comments,
+                     }
+        
+        data_of_file = """<?xml version="1.0"?>
+<ns2:VATConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/VATConsignment" VATDeclarationsNbr="1">
+    <ns2:Representative>
+        <RepresentativeID identificationType="NVAT" issuedBy="%(issued_by)s">%(only_vat)s</RepresentativeID>
+        <Name>%(cmpny_name)s</Name>
+        <Street>%(address)s</Street>
+        <PostCode>%(post_code)s</PostCode>
+        <City>%(city)s</City>
+        <CountryCode>%(country_code)s</CountryCode>
+        <EmailAddress>%(email)s</EmailAddress>
+        <Phone>%(phone)s</Phone>
+    </ns2:Representative>
+    <ns2:VATDeclaration SequenceNumber="1" DeclarantReference="%(send_ref)s">
+        <ns2:Declarant>
+            <VATNumber xmlns="http://www.minfin.fgov.be/InputCommon">%(only_vat)s</VATNumber>
+            <Name>%(cmpny_name)s</Name>
+            <Street>%(address)s</Street>
+            <PostCode>%(post_code)s</PostCode>
+            <City>%(city)s</City>
+            <CountryCode>%(country_code)s</CountryCode>
+            <EmailAddress>%(email)s</EmailAddress>
+            <Phone>%(phone)s</Phone>
+        </ns2:Declarant>
+        <ns2:Period>
+    """ % (file_data)
+         
         if starting_month != ending_month:
             #starting month and ending month of selected period are not the same
             #it means that the accounting isn't based on periods of 1 month but on quarters
-            quarter = str(((int(starting_month) - 1) / 3) + 1)
-            data_of_file += '<QUARTER>'+quarter+'</QUARTER>\n\t\t\t'
+            data_of_file += '\t\t<ns2:Quarter>%(quarter)s</ns2:Quarter>\n\t\t' % (file_data)
         else:
-            data_of_file += '<MONTH>'+starting_month+'</MONTH>\n\t\t\t'
-        data_of_file += '<YEAR>' + str(account_period.date_stop[:4]) + '</YEAR>\n\t\t</DPERIODE>\n\t\t<ASK RESTITUTION="'+ (data['ask_resitution'] and 'YES' or 'NO') +'" PAYMENT="'+ (data['ask_payment'] and 'YES' or 'NO') +'"/>'
-        data_of_file += '\n\t\t<ClientListingNihil>'+ (data['client_nihil'] and 'YES' or 'NO') +'</ClientListingNihil>'
-        data_of_file +='\n\t\t<DATA>\n\t\t\t<DATA_ELEM>'
-
+            data_of_file += '\t\t<ns2:Month>%(month)s</ns2:Month>\n\t\t' % (file_data)
+        data_of_file += '\t<ns2:Year>%(year)s</ns2:Year>' % (file_data)
+        data_of_file += '\n\t\t</ns2:Period>\n'
+        
+        data_of_file += '\t\t<ns2:Data>\t'
+        
+        if tax_info.get('VI') >= 0:
+            tax_info['71'] = tax_info['VI']
+        else:
+            tax_info['72'] = tax_info.get('VI',0)
+        cases_list = []
         for item in tax_info:
-            if item['code'] == '91' and ending_month != 12:
+            if tax_info['91'] and ending_month != 12:
                 #the tax code 91 can only be send for the declaration of December
                 continue
-            if item['code']:
-                if item['code'] == '71-72':
-                    item['code']='71'
-                if item['code'] in list_of_tags:
-                    data_of_file +='\n\t\t\t\t<D'+str(int(item['code'])) +'>' + str(abs(int(round(item['sum_period']*100)))) +  '</D'+str(int(item['code'])) +'>'
-
-        data_of_file += '\n\t\t\t</DATA_ELEM>\n\t\t</DATA>\n\t</VATRECORD>\n</VATSENDING>'
+            if tax_info[item] and item in list_of_tags: 
+                cases_list.append(item)
+        cases_list.sort()
+        for item in cases_list:
+            grid_amount_data = {
+                    'code': str(int(item)),
+                    'amount': '%.2f' %abs(tax_info[item]),
+                    }
+            data_of_file += '\n\t\t\t<ns2:Amount GridNumber="%(code)s">%(amount)s</ns2:Amount''>' % (grid_amount_data)
+            
+        data_of_file += '\n\t\t</ns2:Data>'
+        data_of_file += '\n\t\t<ns2:ClientListingNihil>%(client_nihil)s</ns2:ClientListingNihil>' % (file_data)
+        data_of_file += '\n\t\t<ns2:Ask Restitution="%(ask_restitution)s" Payment="%(ask_payment)s"/>' % (file_data)
+        if file_data['comments']:
+            data_of_file += '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>' % (file_data)
+        data_of_file += '\n\t</ns2:VATDeclaration> \n</ns2:VATConsignment>'
         model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_vat_save')], context=context)
         resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
         context['file_save'] = data_of_file
index fe81a4f..1a635c6 100644 (file)
                                        <group>
                                           <group colspan="4">
                                                        <separator string="Declare Periodical VAT" colspan="4"/><newline/>
-                                               <field name="period_id" widget="selection"/>
                                                        <field name="tax_code_id" string="Company" widget="selection" groups="base.group_multi_company"/>
+                            <field name="period_ids" nolabel="1" colspan="4" height="200" width="550">
+                                <tree colors="blue:state in ('draft');gray:state in ('done') " string="Period">
+                                  <field name="name"/>
+                                  <field name="code"/>
+                                  <field name="date_start"/>
+                                  <field name="date_stop"/>
+                                  <field name="special"/>
+                                  <field name="state"/>
+                                </tree>
+                            </field>
                                                        <newline/>
                                                </group>
                                                <group>
                                                        <field name="client_nihil" string="Is Last Declaration" colspan="1" /><label/>
                                </group>
                                <newline/>
+                    <group colspan="4" groups="base.group_extended">
+                        <separator string="Comments" colspan="4"/>
+                        <field colspan="4" name="comments" nolabel="1"/>
+                    </group>
                                        <group>
                                        <separator colspan="4"/>
                                        <newline/>
index da1a21d..f7fe067 100644 (file)
@@ -4,6 +4,10 @@
 #    OpenERP, Open Source Management Solution
 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
+#    Adapted by Noviat to 
+#     - make the 'mand_id' field optional
+#     - support Noviat tax code scheme
+#
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
 #    published by the Free Software Foundation, either version 3 of the
@@ -23,6 +27,7 @@ import base64
 
 from osv import osv, fields
 from tools.translate import _
+from report import report_sxw
 
 class partner_vat_intra(osv.osv_memory):
     """
@@ -51,101 +56,202 @@ class partner_vat_intra(osv.osv_memory):
     '''
     ),
         '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'),
-        'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', domain=[('parent_id', '=', False)]),
+        'tax_code_id': fields.many2one('account.tax.code', 'Company', domain=[('parent_id', '=', False)], help="Keep empty to use the user's company", required=True),
         'test_xml': fields.boolean('Test XML file', help="Sets the XML output as test file"),
-        'mand_id' : fields.char('MandataireId', size=14, required=True,  help="This identifies the representative of the sending company. This is a string of 14 characters"),
+        'mand_id' : fields.char('Reference', size=14, help="Reference given by the Representative of the sending company."),
         'msg': fields.text('File created', size=14, readonly=True),
         'no_vat': fields.text('Partner With No VAT', size=14, readonly=True, help="The Partner whose VAT number is not defined they doesn't include in XML File."),
         'file_save' : fields.binary('Save File', readonly=True),
         'country_ids': fields.many2many('res.country', 'vat_country_rel', 'vat_id', 'country_id', 'European Countries'),
+        'comments': fields.text('Comments'),
         }
 
+    def _get_tax_code(self, cr, uid, context=None):
+        obj_tax_code = self.pool.get('account.tax.code')
+        obj_user = self.pool.get('res.users')
+        company_id = obj_user.browse(cr, uid, uid, context=context).company_id.id
+        tax_code_ids = obj_tax_code.search(cr, uid, [('company_id', '=', company_id), ('parent_id', '=', False)], context=context)
+        return tax_code_ids and tax_code_ids[0] or False
+
     _defaults = {
         'country_ids': _get_europe_country,
         'file_save': _get_xml_data,
-        'name': 'vat_Intra.xml',
+        'name': 'vat_intra.xml',
+        'tax_code_id': _get_tax_code,
     }
 
-    def create_xml(self, cursor, user, ids, context=None):
+    def _get_datas(self, cr, uid, ids, context=None):
+        """Collects require data for vat intra xml
+        :param ids: id of wizard.
+        :return: dict of all data to be used to generate xml for Partner VAT Intra.
+        :rtype: dict
+        """
+        if context is None:
+            context = {}
+
         obj_user = self.pool.get('res.users')
         obj_sequence = self.pool.get('ir.sequence')
         obj_partner = self.pool.get('res.partner')
         obj_partner_add = self.pool.get('res.partner.address')
-        mod_obj = self.pool.get('ir.model.data')
-        street = zip_city = country = p_list = data_clientinfo = ''
+
+        xmldict = {}
         seq = amount_sum = 0
 
-        if context is None:
-            context = {}
-        data_tax = self.browse(cursor, user, ids[0], context=context)
-        if data_tax.tax_code_id:
-            data_cmpny = data_tax.tax_code_id.company_id
+        wiz_data = self.browse(cr, uid, ids[0], context=context)
+        comments = wiz_data.comments
+
+        if wiz_data.tax_code_id:
+            data_company = wiz_data.tax_code_id.company_id
         else:
-            data_cmpny = obj_user.browse(cursor, user, user).company_id
-        data  = self.read(cursor, user, ids)[0]
-        company_vat = data_cmpny.partner_id.vat
+            data_company = obj_user.browse(cr, uid, uid, context=context).company_id
+        
+        # Get Company vat
+        company_vat = data_company.partner_id.vat
         if not company_vat:
             raise osv.except_osv(_('Data Insufficient'),_('No VAT Number Associated with Main Company!'))
+        company_vat = company_vat.replace(' ','').upper()
+        SenderId = company_vat[2:]
+        issued_by = company_vat[:2]
 
-        seq_controlref = obj_sequence.get(cursor, user, 'controlref')
-        seq_declarantnum = obj_sequence.get(cursor, user, 'declarantnum')
-        cref = company_vat[2:] + seq_controlref[-4:]
-        dnum = cref + seq_declarantnum[-5:]
-        if len(data['period_code']) != 6:
+        if len(wiz_data.period_code) != 6:
             raise osv.except_osv(_('Wrong Period Code'), _('The period code you entered is not valid.'))
 
-        addr = obj_partner.address_get(cursor, user, [data_cmpny.partner_id.id], ['invoice'])
-        if addr.get('invoice',False):
-            ads = obj_partner_add.browse(cursor, user, [addr['invoice']])[0]
-            zip_city = (ads.city or '') + ' ' + (ads.zip or '')
-            if zip_city== ' ':
-                zip_city = ''
-            if ads.street:
-                street = ads.street
-            if ads.street2:
-                street += ' '
-                street += ads.street2
-            if ads.country_id:
-                country = ads.country_id.code
-
-        comp_name = data_cmpny.name
-        sender_date = time.strftime('%Y-%m-%d')
-        data_file = '<?xml version="1.0"?>\n<VatIntra xmlns="http://www.minfin.fgov.be/VatIntra" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" RecipientId="VAT-ADMIN" SenderId="' + str(company_vat) + '"'
-        data_file += ' ControlRef="' + cref + '" MandataireId="' + data['mand_id'] + '" SenderDate="'+ str(sender_date)+ '"'
-        data_file += ' VersionTech="1.3">'
-        data_file += '\n\t<AgentRepr DecNumber="1">\n\t\t<CompanyInfo>\n\t\t\t<VATNum>' + str(company_vat)+'</VATNum>\n\t\t\t<Name>'+ comp_name +'</Name>\n\t\t\t<Street>'+ street +'</Street>\n\t\t\t<CityAndZipCode>'+ zip_city +'</CityAndZipCode>'
-        data_file += '\n\t\t\t<Country>' + country +'</Country>\n\t\t</CompanyInfo>\n\t</AgentRepr>'
-        data_comp = '\n\t\t<CompanyInfo>\n\t\t\t<VATNum>'+str(company_vat[2:])+'</VATNum>\n\t\t\t<Name>'+ comp_name +'</Name>\n\t\t\t<Street>'+ street +'</Street>\n\t\t\t<CityAndZipCode>'+ zip_city +'</CityAndZipCode>\n\t\t\t<Country>'+ country +'</Country>\n\t\t</CompanyInfo>'
-        data_period = '\n\t\t<Period>'+ data['period_code'] +'</Period>' #trimester
-        p_id_list = obj_partner.search(cursor, user, [('vat','!=',False)])
+        if not wiz_data.period_ids:
+            raise osv.except_osv(_('Data Insufficient!'),_('Please select at least one Period.'))
+
+        p_id_list = obj_partner.search(cr, uid, [('vat','!=',False)], context=context)
         if not p_id_list:
             raise osv.except_osv(_('Data Insufficient!'),_('No partner has a VAT Number asociated with him.'))
 
-        if not data['period_ids']:
-            raise osv.except_osv(_('Data Insufficient!'),_('Please select at least one Period.'))
-        cursor.execute('''SELECT p.name As partner_name, l.partner_id AS partner_id, p.vat AS vat, t.code AS intra_code, SUM(l.tax_amount) AS amount
+        seq_declarantnum = obj_sequence.get(cr, uid, 'declarantnum')
+        dnum = company_vat[2:] + seq_declarantnum[-4:]
+
+        name = email = phone = address = post_code = city = country_code = ''
+        city, post_code, address, country_code = self.pool.get('res.company')._get_default_ad(data_company.partner_id.address)
+        for addr in data_company.partner_id.address:
+            if addr.type == 'default':
+                name = addr.name or ""
+                email = addr.email or ""
+                phone = addr.phone or ""
+
+        if not country_code:
+            raise osv.except_osv(_('Data Insufficient!'),_('No country associated with the company.'))
+        if not email:
+            raise osv.except_osv(_('Data Insufficient!'),_('No email address associated with the company.'))
+        if not phone:
+            raise osv.except_osv(_('Data Insufficient!'),_('No phone associated with the company.'))
+        xmldict.update({
+                        'company_name': data_company.name,
+                        'company_vat': company_vat, 
+                        'vatnum':  company_vat[2:],
+                        'mand_id': wiz_data.mand_id, 
+                        'sender_date': str(time.strftime('%Y-%m-%d')),
+                        'address': address,
+                        'city': city,
+                        'post_code': post_code,
+                        'country_code': country_code,
+                        'email': email,
+                        'phone': phone.replace('/','').replace('.','').replace('(','').replace(')','').replace(' ',''),
+                        'period': wiz_data.period_code,
+                        'clientlist': [], 
+                        'comments': comments,
+                        'issued_by': issued_by,
+                        })
+        
+        codes = ('44', '46L', '46T', '48s44', '48s46L', '48s46T')
+        cr.execute('''SELECT p.name As partner_name, l.partner_id AS partner_id, p.vat AS vat, 
+                      (CASE WHEN t.code = '48s44' THEN '44'
+                            WHEN t.code = '48s46L' THEN '46L'
+                            WHEN t.code = '48s46T' THEN '46T'
+                       ELSE t.code END) AS intra_code,
+                      SUM(CASE WHEN t.code in ('48s44','48s46L','48s46T') THEN -l.tax_amount ELSE l.tax_amount END) AS amount
                       FROM account_move_line l
                       LEFT JOIN account_tax_code t ON (l.tax_code_id = t.id)
                       LEFT JOIN res_partner p ON (l.partner_id = p.id)
-                      WHERE t.code IN ('44a','44b','88')
+                      WHERE t.code IN %s
                        AND l.period_id IN %s
-                      GROUP BY p.name, l.partner_id, p.vat, t.code''', (tuple(data['period_ids']), ))
-        for row in cursor.dictfetchall():
+                       AND t.company_id = %s
+                      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))
+
+        p_count = 0
+
+        for row in cr.dictfetchall():
             if not row['vat']:
-                p_list += str(row['partner_name']) + ', '
-                continue
+                row['vat'] = ''
+                p_count += 1
+
             seq += 1
-            amt = row['amount'] or 0
-            amt = int(round(amt * 100))
+            amt = row['amount'] or 0.0
             amount_sum += amt
-            intra_code = row['intra_code'] == '88' and 'L' or (row['intra_code'] == '44b' and 'T' or (row['intra_code'] == '44a' and 'S' or ''))
-            data_clientinfo +='\n\t\t<ClientList SequenceNum="'+str(seq)+'">\n\t\t\t<CompanyInfo>\n\t\t\t\t<VATNum>'+row['vat'][2:] +'</VATNum>\n\t\t\t\t<Country>'+row['vat'][:2] +'</Country>\n\t\t\t</CompanyInfo>\n\t\t\t<Amount>'+str(amt) +'</Amount>\n\t\t\t<Code>'+str(intra_code) +'</Code>\n\t\t</ClientList>'
-        amount_sum = int(amount_sum)
-        data_decl = '\n\t<DeclarantList SequenceNum="1" DeclarantNum="'+ dnum + '" ClientNbr="'+ str(seq) +'" AmountSum="'+ str(amount_sum) +'" >'
-        data_file += data_decl + data_comp + str(data_period) + data_clientinfo + '\n\t</DeclarantList>\n</VatIntra>'
+
+            intra_code = row['intra_code'] == '44' and 'S' or (row['intra_code'] == '46L' and 'L' or (row['intra_code'] == '46T' and 'T' or ''))
+
+            xmldict['clientlist'].append({
+                                        'partner_name': row['partner_name'],
+                                        'seq': seq, 
+                                        'vatnum': row['vat'][2:].replace(' ','').upper(), 
+                                        'vat': row['vat'],
+                                        'country_code': row['vat'][:2],
+                                        'amount': '%.2f' %amt,
+                                        'intra_code': row['intra_code'],
+                                        'code': intra_code})
+
+        xmldict.update({'dnum': dnum, 'clientnbr': str(seq), 'amountsum': '%.2f' %amount_sum, 'partner_wo_vat': p_count})
+        return xmldict
+
+    def create_xml(self, cursor, user, ids, context=None):
+        """Creates xml that is to be exported and sent to estate for partner vat intra.
+        :return: Value for next action.
+        :rtype: dict
+        """
+        mod_obj = self.pool.get('ir.model.data')
+        xml_data = self._get_datas(cursor, user, ids, context=context)
+        month_quarter = xml_data['period'][:2]
+        year = xml_data['period'][2:]
+        data_file = ''
+
+        # Can't we do this by etree?
+        data_head = """<?xml version="1.0" encoding="ISO-8859-1"?>
+<ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1">
+    <ns2:Representative>
+        <RepresentativeID identificationType="NVAT" issuedBy="%(issued_by)s">%(vatnum)s</RepresentativeID>
+        <Name>%(company_name)s</Name>
+        <Street>%(address)s</Street>
+        <PostCode>%(post_code)s</PostCode>
+        <City>%(city)s</City>
+        <CountryCode>%(country_code)s</CountryCode>
+        <EmailAddress>%(email)s</EmailAddress>
+        <Phone>%(phone)s</Phone>
+    </ns2:Representative>""" % (xml_data)
+        if xml_data['mand_id']:
+            data_head += '\n\t\t<ns2:RepresentativeReference>%(mand_id)s</ns2:RepresentativeReference>' % (xml_data)
+        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>%(address)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_code)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)
+        if month_quarter.startswith('3'):
+            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>'
+        elif month_quarter.startswith('0') and month_quarter.endswith('0'):
+            data_comp_period+= '\n\t\t<ns2:Period>\n\t\t\t<ns2:Year>'+year+'</ns2:Year>\n\t\t</ns2:Period>'
+        else:
+            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>'
+
+        data_clientinfo = ''
+        for client in xml_data['clientlist']:
+            if not client['vatnum']:
+                raise osv.except_osv(_('Data Insufficient!'),_('No vat number defined for %s') % client['partner_name'])
+            data_clientinfo +='\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country_code)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount)s</ns2:Amount>\n\t\t</ns2:IntraClient>' % (client)
+
+        data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum)s">' % (xml_data)
+
+        data_file += data_head + data_decl + data_comp_period + data_clientinfo
+        if xml_data['comments']:
+            data_file += '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>' % (xml_data)
+        data_file += '\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' % (xml_data)
+
+        
+        context['file_save'] = data_file
+
         model_data_ids = mod_obj.search(cursor, user,[('model','=','ir.ui.view'),('name','=','view_vat_intra_save')], context=context)
         resource_id = mod_obj.read(cursor, user, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
-        context['file_save'] = data_file
+
         return {
             'name': _('Save'),
             'context': context,