# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2010 Tiny SPRL (). # # Corrections & modifications by Noviat nv/sa, (http://www.noviat.be): # - VAT listing based upon year in stead of fiscal year # - sql query adapted to select only 'tax-out' move lines # - extra button to print readable PDF report # # 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 # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # ############################################################################## import time import base64 from openerp.tools.translate import _ from openerp.osv import fields, osv from openerp.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), 'turnover': fields.float('Base Amount'), 'vat_amount': fields.float('VAT Amount'), } class partner_vat(osv.osv_memory): """ Vat Listing """ _name = "partner.vat" 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') 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' 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(_('Insufficient Data!'), _('No data for the selected year.')) partners = [] partner_ids = obj_partner.search(cr, uid, [('vat_subjected', '!=', False), ('vat','ilike','BE%')], context=context) if not partner_ids: raise osv.except_osv(_('Error'),_('No belgium contact with a VAT number in your database.')) 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 ('00','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) if not partners: raise osv.except_osv(_('Insufficient Data!'), _('No data found for the selected year.')) context.update({'partner_ids': partners, 'year': data['year'], 'limit_amount': data['limit_amount']}) 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'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'partner.vat.list', 'views': [(resource_id,'form')], 'context': context, 'type': 'ir.actions.act_window', 'target': 'new', } _columns = { 'year': fields.char('Year', size=4, required=True), 'limit_amount': fields.integer('Limit Amount', required=True), } _defaults={ 'year': lambda *a: str(int(time.strftime('%Y'))-1), 'limit_amount': 250, } class partner_vat_list(osv.osv_memory): """ Partner Vat Listing """ _name = "partner.vat.list" _columns = { '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), 'file_save' : fields.binary('Save File', readonly=True), 'comments': fields.text('Comments'), } def _get_partners(self, cr, uid, context=None): return context.get('partner_ids', []) _defaults={ 'partner_ids': _get_partners, } 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_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(_('Insufficient Data!'),_('No VAT number associated with the company.')) company_vat = company_vat.replace(' ','').upper() SenderId = company_vat[2:] issued_by = company_vat[:2] seq_declarantnum = obj_sequence.get(cr, uid, 'declarantnum') dnum = company_vat[2:] + seq_declarantnum[-4:] street = city = country = '' addr = obj_partner.address_get(cr, uid, [obj_cmpny.partner_id.id], ['invoice']) if addr.get('invoice',False): ads = obj_partner.browse(cr, uid, [addr['invoice']], context=context)[0] phone = ads.phone and ads.phone.replace(' ','') or '' email = ads.email or '' name = ads.name or '' city = ads.city or '' zip = obj_partner.browse(cr, uid, ads.id, context=context).zip or '' if not city: city = '' if ads.street: street = ads.street if ads.street2: street += ' ' + ads.street2 if ads.country_id: country = ads.country_id.code data = self.read(cr, uid, ids)[0] comp_name = obj_cmpny.name if not email: raise osv.except_osv(_('Insufficient Data!'),_('No email address associated with the company.')) if not phone: raise osv.except_osv(_('Insufficient Data!'),_('No phone associated with the company.')) annual_listing_data = { 'issued_by': issued_by, 'company_vat': company_vat, 'comp_name': comp_name, 'street': street, 'zip': zip, 'city': city, 'country': country, 'email': email, 'phone': phone, 'SenderId': SenderId, 'period': context['year'], 'comments': data['comments'] or '' } data_file = """ %(SenderId)s %(comp_name)s %(street)s %(zip)s %(city)s""" if annual_listing_data['country']: data_file +="\n\t\t%(country)s" data_file += """ %(email)s %(phone)s """ data_file = data_file % annual_listing_data data_comp = """ %(SenderId)s %(comp_name)s %(street)s %(zip)s %(city)s %(country)s %(email)s %(phone)s %(period)s """ % annual_listing_data # Turnover and Farmer tags are not included client_datas = self._get_datas(cr, uid, ids, context=context) if not client_datas: raise osv.except_osv(_('Data Insufficient!'),_('No data available for the client.')) data_client_info = '' for amount_data in client_datas: data_client_info += """ %(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_begin data_end = """ %(comments)s """ % annual_listing_data data_file += data_begin + data_comp + data_client_info + data_end file_save = base64.encodestring(data_file.encode('utf8')) 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'] 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, cr, uid, ids, context=None): if context is None: context = {} 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) if not datas['client_datas']: raise osv.except_osv(_('Error!'), _('No record to print.')) return self.pool['report'].get_action( cr, uid, [], 'l10n_be.report_l10nvatpartnerlisting', data=datas, context=context ) 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) class wrapped_vat_listing_print(osv.AbstractModel): _name = 'report.l10n_be.report_l10nvatpartnerlisting' _inherit = 'report.abstract_report' _template = 'l10n_be.report_l10nvatpartnerlisting' _wrapped_report_class = partner_vat_listing_print # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: