From 351d056c448e310f6ba34751645a958b0b15b286 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 15 Feb 2012 14:18:16 +0100 Subject: [PATCH] [FIX+IMP] l10n_be: partner vat listing xml statement upgraded to intervat 8.0. Added the possibility to print the list exported. Those 2 points are courtesy of Noviat. Improved the query to get data for this xml export: we now base our computation on the tax_amount and tax_code_id, which is way more correct. bzr revid: qdp-launchpad@openerp.com-20120215131816-17ayv0pom1iddxf8 --- .../wizard/l10n_be_partner_vat_listing.py | 373 +++++++++--------- .../wizard/l10n_be_partner_vat_listing.rml | 179 +++++++++ .../wizard/l10n_be_partner_vat_listing.xml | 170 +++++--- 3 files changed, 463 insertions(+), 259 deletions(-) create mode 100644 addons/l10n_be/wizard/l10n_be_partner_vat_listing.rml diff --git a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py index 75162b37b82..37bfd034fae 100644 --- a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py +++ b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.py @@ -28,96 +28,73 @@ import time import base64 from tools.translate import _ from osv import fields, osv +from report import report_sxw class vat_listing_clients(osv.osv_memory): _name = 'vat.listing.clients' _columns = { 'name': fields.char('Client Name', size=32), 'vat': fields.char('VAT', size=64), - 'country': fields.char('Country', size=16), - 'amount': fields.float('Amount'), - 'turnover': fields.float('Turnover'), + 'turnover': fields.float('Base Amount'), + 'vat_amount': fields.float('VAT Amount'), } - def name_get(self, cr, uid, ids, context=None): - res = self.read(cr, uid, ids, ['name', 'vat'], context=context, load='_classic_write') - return [(r['id'], '%s - %s' % (r['name'] or '', r['vat'] or '')) for r in res] - - def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): - args.append(['id', 'in', context['partner_ids']]) - client_ids = self.search(cr, uid, [('vat', '=', name)] + args, limit=limit, context=context) - if not client_ids: - client_ids = self.search(cr, uid, [('name', 'ilike', name)] + args, limit=limit, context=context) - return self.name_get(cr, uid, client_ids, context=context) - vat_listing_clients() -class partner_vat_13(osv.osv_memory): +class partner_vat(osv.osv_memory): """ Vat Listing """ - _name = "partner.vat_13" + _name = "partner.vat" - def get_partner(self, cursor, user, ids, context=None): + def get_partner(self, cr, uid, ids, context=None): obj_period = self.pool.get('account.period') obj_partner = self.pool.get('res.partner') obj_vat_lclient = self.pool.get('vat.listing.clients') obj_model_data = self.pool.get('ir.model.data') - data = self.read(cursor, user, ids)[0] - #period = obj_period.search(cursor, user, [('fiscalyear_id', '=', data['fyear'])], context=context) + obj_module = self.pool.get('ir.module.module') + data = self.read(cr, uid, ids)[0] year = data['year'] date_start = year + '-01-01' date_stop = year + '-12-31' - period = obj_period.search(cursor, user, [('date_start' ,'>=', date_start), ('date_stop','<=',date_stop)]) - if not period: + if context.get('company_id', False): + company_id = context['company_id'] + else: + company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id + period_ids = obj_period.search(cr, uid, [('date_start' ,'>=', date_start), ('date_stop','<=',date_stop), ('company_id','=',company_id)]) + if not period_ids: raise osv.except_osv(_('Data Insufficient!'), _('No data for the selected Year.')) - #logger.notifyChannel('addons.'+self._name, netsvc.LOG_WARNING, 'period = %s' %period ) - - p_id_list = obj_partner.search(cursor, user, [('vat_subjected', '!=', False)], context=context) - if not p_id_list: - raise osv.except_osv(_('Data Insufficient!'), _('No partner has a VAT Number asociated with him.')) + partners = [] - records = [] - for obj_partner in obj_partner.browse(cursor, user, p_id_list, context=context): - record = {} # this holds record per partner - - #This listing is only for customers located in belgium, that's the - #reason why we skip all the partners that haven't their - #(or one of their) default address(es) located in Belgium. - go_ahead = False - for ads in obj_partner.address: - if ads.type == 'default' and (ads.country_id and ads.country_id.code == 'BE') and (obj_partner.vat or '').startswith('BE'): - go_ahead = True - break - if not go_ahead: - continue - cursor.execute('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 %s and l.partner_id=%s and l.period_id IN %s group by b.code',(('income','produit','tax_out'),obj_partner.id,tuple(period),)) - line_info = cursor.fetchall() - if not line_info: - continue - - record['vat'] = obj_partner.vat.replace(' ','').upper() - - #it seems that this listing is only for belgian customers - record['country'] = 'BE' - - record['amount'] = 0 - record['turnover'] = 0 - record['name'] = obj_partner.name - for item in line_info: - if item[0] in ('income','produit'): - record['turnover'] += item[1] - else: - record['amount'] += item[1] - id_client = obj_vat_lclient.create(cursor, user, record, context=context) - partners.append(id_client) - records.append(record) + partner_ids = obj_partner.search(cr, uid, [('vat_subjected', '!=', False), ('vat','ilike','BE%')], context=context) + cr.execute("""SELECT sub1.partner_id, sub1.name, sub1.vat, sub1.turnover, sub2.vat_amount + FROM (SELECT l.partner_id, p.name, p.vat, SUM(CASE WHEN c.code ='49' THEN -l.tax_amount ELSE l.tax_amount END) as turnover + FROM account_move_line l + LEFT JOIN res_partner p ON l.partner_id = p.id + LEFT JOIN account_tax_code c ON l.tax_code_id = c.id + WHERE c.code IN ('01','02','03','45','49') + AND l.partner_id IN %s + AND l.period_id IN %s + GROUP BY l.partner_id, p.name, p.vat) AS sub1 + LEFT JOIN (SELECT l2.partner_id, SUM(CASE WHEN c2.code ='64' THEN -l2.tax_amount ELSE l2.tax_amount END) as vat_amount + FROM account_move_line l2 + LEFT JOIN account_tax_code c2 ON l2.tax_code_id = c2.id + WHERE c2.code IN ('54','64') + AND l2.partner_id IN %s + AND l2.period_id IN %s + GROUP BY l2.partner_id) AS sub2 ON sub1.partner_id = sub2.partner_id + """,(tuple(partner_ids),tuple(period_ids),tuple(partner_ids),tuple(period_ids))) + for record in cr.dictfetchall(): + record['vat'] = record['vat'].replace(' ','').upper() + if record['turnover'] >= data['limit_amount']: + id_client = obj_vat_lclient.create(cr, uid, record, context=context) + partners.append(id_client) context.update({'partner_ids': partners, 'year': data['year'], 'limit_amount': data['limit_amount']}) - model_data_ids = obj_model_data.search(cursor, user, [('model','=','ir.ui.view'), ('name','=','view_vat_listing_13')]) - resource_id = obj_model_data.read(cursor, user, model_data_ids, fields=['res_id'])[0]['res_id'] + model_data_ids = obj_model_data.search(cr, uid, [('model','=','ir.ui.view'), ('name','=','view_vat_listing')]) + resource_id = obj_model_data.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id'] return { - 'name': 'Vat Listing', + 'name': _('Vat Listing'), 'view_type': 'form', 'view_mode': 'form', - 'res_model': 'partner.vat.list_13', + 'res_model': 'partner.vat.list', 'views': [(resource_id,'form')], 'context': context, 'type': 'ir.actions.act_window', @@ -134,82 +111,107 @@ class partner_vat_13(osv.osv_memory): 'limit_amount': 250, } -partner_vat_13() +partner_vat() -class partner_vat_list_13(osv.osv_memory): +class partner_vat_list(osv.osv_memory): """ Partner Vat Listing """ - _name = "partner.vat.list_13" + _name = "partner.vat.list" _columns = { - # TODO the referenced model has been deleted at revno 4672.1.2. 'partner_ids': fields.many2many('vat.listing.clients', 'vat_partner_rel', 'vat_id', 'partner_id', 'Clients', help='You can remove clients/partners which you do not want to show in xml file'), 'name': fields.char('File Name', size=32), - 'msg': fields.text('File created', size=64, readonly=True), 'file_save' : fields.binary('Save File', readonly=True), - 'identification_type': fields.selection([('tin','TIN'), ('nvat','NVAT'), ('other','Other')], 'Identification Type', required=True), - 'other': fields.char('Other Qlf', size=16, help="Description of a Identification Type"), 'comments': fields.text('Comments'), } - def _get_partners(self, cursor, user, context=None): + def _get_partners(self, cr, uid, context=None): return context.get('partner_ids', []) _defaults={ - # TODO the referenced model has been deleted at revno 4672.1.2. 'partner_ids': _get_partners, - 'identification_type' : 'tin', } - def create_xml(self, cursor, user, ids, context=None): + def _get_datas(self, cr, uid, ids, context=None): + obj_vat_lclient = self.pool.get('vat.listing.clients') datas = [] + data = self.read(cr, uid, ids)[0] + for partner in data['partner_ids']: + if isinstance(partner, list) and partner: + datas.append(partner[2]) + else: + client_data = obj_vat_lclient.read(cr, uid, partner, context=context) + datas.append(client_data) + client_datas = [] + seq = 0 + sum_tax = 0.00 + sum_turnover = 0.00 + amount_data = {} + for line in datas: + if not line: + continue + seq += 1 + sum_tax += line['vat_amount'] + sum_turnover += line['turnover'] + vat = line['vat'].replace(' ','').upper() + amount_data ={ + 'seq': str(seq), + 'vat': vat, + 'only_vat': vat[2:], + 'turnover': '%.2f' %line['turnover'], + 'vat_amount': '%.2f' %line['vat_amount'], + 'sum_tax': '%.2f' %sum_tax, + 'sum_turnover': '%.2f' %sum_turnover, + 'partner_name': line['name'], + } + client_datas += [amount_data] + return client_datas + + def create_xml(self, cr, uid, ids, context=None): + obj_sequence = self.pool.get('ir.sequence') obj_users = self.pool.get('res.users') obj_partner = self.pool.get('res.partner') - obj_fyear = self.pool.get('account.fiscalyear') obj_addr = self.pool.get('res.partner.address') - obj_vat_lclient = self.pool.get('vat.listing.clients') - - seq_controlref = obj_sequence.get(cursor, user, 'controlref') - seq_declarantnum = obj_sequence.get(cursor, user, 'declarantnum') - obj_cmpny = obj_users.browse(cursor, user, user, context=context).company_id + obj_model_data = self.pool.get('ir.model.data') + seq_declarantnum = obj_sequence.get(cr, uid, 'declarantnum') + obj_cmpny = obj_users.browse(cr, uid, uid, context=context).company_id company_vat = obj_cmpny.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] - cref = SenderId + seq_controlref - dnum = cref + seq_declarantnum - #obj_year= obj_fyear.browse(cursor, user, context['fyear'], context=context) + seq_declarantnum = obj_sequence.get(cr, uid, 'declarantnum') + dnum = company_vat[2:] + seq_declarantnum[-4:] street = city = country = '' - addr = obj_partner.address_get(cursor, user, [obj_cmpny.partner_id.id], ['invoice']) + addr = obj_partner.address_get(cr, uid, [obj_cmpny.partner_id.id], ['invoice']) if addr.get('invoice',False): - ads = obj_addr.browse(cursor, user, [addr['invoice']], context=context)[0] - phone = ads.phone or '' + ads = obj_addr.browse(cr, uid, [addr['invoice']], context=context)[0] + phone = ads.phone.replace(' ','') or '' email = ads.email or '' name = ads.name or '' - - city = obj_addr.get_city(cursor, user, ads.id) - zip = obj_addr.browse(cursor, user, ads.id, context=context).zip or '' + city = obj_addr.get_city(cr, uid, ads.id) + zip = obj_addr.browse(cr, uid, ads.id, context=context).zip or '' if not city: city = '' if ads.street: - street = ads.street + ' ' + street = ads.street if ads.street2: - street += ads.street2 + street += ' ' + ads.street2 if ads.country_id: country = ads.country_id.code - data = self.read(cursor, user, ids)[0] - other = data['other'] or '' + data = self.read(cr, uid, ids)[0] sender_date = time.strftime('%Y-%m-%d') comp_name = obj_cmpny.name + 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.')) annual_listing_data = { - 'identificationType': data['identification_type'].upper(), 'issued_by': issued_by, - 'other': other, 'company_vat': company_vat, 'comp_name': comp_name, 'street': street, @@ -223,25 +225,25 @@ class partner_vat_list_13(osv.osv_memory): 'comments': data['comments'] or '' } - data_file = """ - - - %(company_vat)s + data_file = """ + + + %(SenderId)s %(comp_name)s %(street)s %(zip)s - %(city)s - %(country)s + %(city)s""" + if annual_listing_data['country']: + data_file +="\n\t\t%(country)s" + data_file += """ %(email)s %(phone)s - - -""" % annual_listing_data + """ + data_file = data_file % annual_listing_data data_comp = """ - - - %(SenderId)s + + %(SenderId)s %(comp_name)s %(street)s %(zip)s @@ -249,105 +251,88 @@ class partner_vat_list_13(osv.osv_memory): %(country)s %(email)s %(phone)s - - %(period)s + + %(period)s """ % annual_listing_data - error_message = [] - - for partner in data['partner_ids']: - if isinstance(partner, list) and partner: - datas.append(partner[2]) - else: - client_data = obj_vat_lclient.read(cursor, user, partner, context=context) - datas.append(client_data) - seq = 0 + # Turnover and Farmer tags are not included + client_datas = self._get_datas(cr, uid, ids, context=context) data_client_info = '' - sum_tax = 0.00 - sum_turnover = 0.00 - if len(error_message): - return 'Exception : \n' +'-'*50+'\n'+ '\n'.join(error_message) - amount_data = { - 'seq': str(seq), - 'dnum': dnum, - 'sum_tax': str(0), - 'sum_turnover': str(0), - } - for line in datas: - vat_issued = line['vat'][:2] - if vat_issued == 'BE': - vat_issued = '' - else: - vat_issued = vat_issued - if not line: - continue - if line['turnover'] < context['limit_amount']: - continue - seq += 1 - sum_tax += line['amount'] - sum_turnover += line['turnover'] - - amount_data.update({ - 'seq': str(seq), - 'vat_issued': vat_issued, - 'only_vat': line['vat'].replace(' ','').upper()[2:], - 'turnover': str(int(round(line['turnover'] * 100))), - 'vat_amount': str(int(round(line['amount'] * 100))), - 'sum_tax': str(int(round(sum_tax * 100))), - 'sum_turnover': str(int(round(sum_turnover * 100))), - }) - # Turnover and Farmer tags are not included + for amount_data in client_datas: data_client_info += """ - - %(only_vat)s - %(turnover)s - %(vat_amount)s - """ % amount_data + + %(only_vat)s + %(turnover)s + %(vat_amount)s + """ % amount_data + amount_data_begin = client_datas[-1] + amount_data_begin.update({'dnum':dnum}) data_begin = """ - -""" % amount_data +""" % amount_data_begin data_end = """ - - %(comments)s - - + + %(comments)s + + """ % annual_listing_data data_file += data_begin + data_comp + data_client_info + data_end - msg = 'Save the File with '".xml"' extension.' file_save = base64.encodestring(data_file.encode('utf8')) - self.write(cursor, user, ids, {'file_save':file_save, 'msg':msg, 'name':'vat_list.xml'}, context=context) - return True + self.write(cr, uid, ids, {'file_save':file_save, 'name':'vat_list.xml'}, context=context) + model_data_ids = obj_model_data.search(cr, uid, [('model','=','ir.ui.view'), ('name','=','view_vat_listing_result')]) + resource_id = obj_model_data.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id'] -# Not fully implemented + return { + 'name': _('XML File has been Created'), + 'res_id': ids[0], + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'partner.vat.list', + 'views': [(resource_id,'form')], + 'context': context, + 'type': 'ir.actions.act_window', + 'target': 'new', + } -# def print_vatlist(self, cursor, user, ids, context=None): -# if context is None: -# context = {} -# obj_vat_lclient = self.pool.get('vat.listing.clients') -# client_datas = [] -# data = self.read(cursor, user, ids)[0] -# for partner in data['partner_ids']: -# if isinstance(partner, list) and partner: -# client_datas.append(partner[2]) -# else: -# client_data = obj_vat_lclient.read(cursor, user, partner, context=context) -# client_datas.append(client_data) -# -# datas = {'ids': []} -# datas['model'] = 'res.company' -# datas['year'] = context['year'] -# datas['limit_amount'] = context['limit_amount'] -# datas['client_datas'] = client_datas -# return { -# 'type': 'ir.actions.report.xml', -# 'report_name': 'partner.vat.listing.print', -# 'datas': datas, -# } + def print_vatlist(self, cr, uid, ids, context=None): + if context is None: + context = {} + obj_vat_lclient = self.pool.get('vat.listing.clients') + datas = {'ids': []} + datas['model'] = 'res.company' + datas['year'] = context['year'] + datas['limit_amount'] = context['limit_amount'] + datas['client_datas'] = self._get_datas(cr, uid, ids, context=context) + return { + 'type': 'ir.actions.report.xml', + 'report_name': 'partner.vat.listing.print', + 'datas': datas, + } -partner_vat_list_13() +partner_vat_list() + +class partner_vat_listing_print(report_sxw.rml_parse): + + def __init__(self, cr, uid, name, context): + super(partner_vat_listing_print, self).__init__(cr, uid, name, context=context) + self.localcontext.update( { + 'time': time, + }) + + def set_context(self, objects, data, ids, report_type=None): + client_datas = data['client_datas'] + self.localcontext.update( { + 'year': data['year'], + 'sum_turnover': client_datas[-1]['sum_turnover'], + 'sum_tax': client_datas[-1]['sum_tax'], + 'client_list': client_datas, + }) + super(partner_vat_listing_print, self).set_context(objects, data, ids) + +report_sxw.report_sxw('report.partner.vat.listing.print', 'res.partner', 'addons/l10n_be/wizard/l10n_be_partner_vat_listing.rml', parser=partner_vat_listing_print,header=False) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.rml b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.rml new file mode 100644 index 00000000000..81b0635fa37 --- /dev/null +++ b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.rml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ company.name ]] + + + [[ year ]] + + + Annual Listing of VAT-Subjected Customers + + + + + + + + + + Nr + + + Partner + + + VAT Number + + + Base Amount + + + VAT Amount + + + + + + + + + + + + + + + + [[ sum_turnover ]] + + + + + [[ sum_tax ]] + + + + + + + +
+ [[ repeatIn(client_list, 'l') ]] + + + + [[ l['seq'] ]] + + + [[ l['partner_name'] ]] + + + [[ l['vat'] ]] + + + [[ l['turnover'] ]] + + + [[ l['vat_amount'] ]] + + + + + + +
+ + + + + + +
+
+ diff --git a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.xml b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.xml index 205de040a7f..cb22ea66fe3 100644 --- a/addons/l10n_be/wizard/l10n_be_partner_vat_listing.xml +++ b/addons/l10n_be/wizard/l10n_be_partner_vat_listing.xml @@ -1,71 +1,111 @@ - - - Partner VAT Listing - partner.vat_13 - form - -
-