1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2013 Guadaltech. All Rights Reserved
6
# Author: Alberto Martín Cortada
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.
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.
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/.
21
##############################################################################
26
from datetime import datetime
27
from dateutil.relativedelta import relativedelta
30
from osv import osv, fields
31
from tools.translate import _
32
from account.report.account_tax_report import tax_report
35
class l10n_es_aeat_mod303_report(osv.osv):
37
_inherit = "l10n.es.aeat.report"
38
_name = "l10n.es.aeat.mod303.report"
39
_description = "AEAT 303 Report"
42
def button_calculate(self, cr, uid, ids, context=None):
46
self.action_confirm(cr, uid, ids, context)
50
def button_recalculate(self, cr, uid, ids, context=None):
54
self.action_confirm(cr, uid, ids, context)
58
def button_export(self, cr, uid, ids, context=None):
62
export_obj = self.pool.get("l10n.es.aeat.mod303.export_to_boe")
63
export_obj._export_boe_file(cr, uid, ids, self.browse(cr, uid, ids and ids[0]),'303')
70
'period': fields.selection([
71
('1T','First quarter'),('2T','Second quarter'),('3T','Third quarter'),
72
('4T','Fourth quarter'),('01','January'),('02','February'),('03','March'),('04','April'),
73
('05','May'),('06','June'),('07','July'),('08','August'),('09','September'),('10','October'),
74
('11','November'),('12','December')
75
], 'Periodo',states={'done':[('readonly',True)]}),
76
'devolucion_mensual' : fields.boolean("Devolución Mensual",help="Inscrito en el Registro de Devolución Mensual",states={'done':[('readonly',True)]}),
77
'complementaria' : fields.boolean("Autoliquidación Complementaria",help="Autoliquidación Complementaria",states={'done':[('readonly',True)]}),
78
'contact_name': fields.char("Full Name", size=40),
79
'total_devengado' : fields.float("IVA Devengado",readonly=True), ## 21
80
'total_deducir' : fields.float("IVA a Deducir",readonly=True), ## 37
81
'diferencia' : fields.float("Diferencia",readonly=True,help="( IVA devengado - IVA deducible )"), ## 38
82
'porcentaje_atribuible_estado' : fields.float("%", help="""Los sujetos pasivos que tributen conjuntamente a la Administración del Estado y a las Diputaciones Forales del País Vasco o a la ComunidadForal de Navarra, consignarán en esta casilla el porcentaje del volumen de operaciones en territorio común. Los demás sujetos pasivos consignarán en esta casilla el 100%""",states={'done':[('readonly',True)]}), ## 39
83
'atribuible_estado' : fields.float("Atribuible a la Administracion",readonly=True), ## 40
84
'cuota_compensar' : fields.float("Cuotas a Compensar",help="Cuota a compensar de periodos anteriores",states={'done':[('readonly',True)]}), ## 41
85
'regularizacion_anual' : fields.float("Regularización Anual",help="""En la última autoliquidación del año (la del período 4T o mes 12) se hará constar, con el signo que corresponda, el resultado de la regularización anual conforme disponen las Leyes por las que se aprueban el Concierto Económico entre el Estado y la Comunidad Autónoma del País Vasco y el Convenio Económico entre el Estado y la Comunidad Foral de Navarra.""",states={'done':[('readonly',True)]}), ## 45
86
'resultado_casilla_46' : fields.float("Resultado",help="""Atribuible a la admistracion [40] - Cuotas a compensar [41] + Regularización Anual [45]""",readonly=True), ## 46
88
'previus_result' : fields.float("A Deducir",help="Resultado de la anterior o anteriores del mismo concepto, ejercicio y periodo",states={'done':[('readonly',True)]}), ## 47
89
'resultado_liquidacion' : fields.float("Resultado Liquidación",readonly=True), ## 48
91
'compensar' : fields.float("Compensar",states={'done':[('readonly',True)]}), ## 49
93
"devolver" : fields.float("Devolver",states={'done':[('readonly',True)]}),
94
"ingresar" : fields.float("Ingresar",states={'done':[('readonly',True)]}),
96
'cuenta_devolucion_id' : fields.many2one("res.partner.bank","CCC Devolución",states={'done':[('readonly',True)]}),
97
'cuenta_ingreso_id' : fields.many2one("res.partner.bank","CCC Ingreso",states={'done':[('readonly',True)]}),
99
'sin_actividad' : fields.boolean("Sin Actividad",states={'done':[('readonly',True)]}),
102
# 'type': fields.selection([
103
# ('C','Solicitud de compensación'),
104
# ('D','Devolución'),
105
# ('G','CC Tributaria-Ingreso'),
107
# ('N','Sin Actividad'),
108
# ('V','CC Tributaria-Devolución'),
109
# ('U','Domicilación de CCC'),], 'Statement Type',
114
'number' : lambda *a: '303',
115
'porcentaje_atribuible_estado': lambda *a: 100,
116
'cuota_compensar' : lambda *a: 0
120
def _get_period(self,cr,uid,ids,context=None):
122
period_obj = self.pool.get("account.period")
123
quarter_dict = {"1T" : 'first',
128
account_period_id = []
130
for mod303 in self.browse(cr, uid, ids, context):
135
dec_year = mod303.fiscalyear_id.date_start.split('-')[0]
139
if mod >= '01' and mod <= '12':
140
fecha_ini = datetime.strptime('%s-%s-01' % (dec_year, mod), '%Y-%m-%d')
141
fecha_fin = fecha_ini + relativedelta(months=+1, days=-1)
142
account_period_id = period_obj.search(cr,uid,[('date_start','=',fecha_ini),('date_stop','=',fecha_fin)])
144
if mod in ('1T', '2T', '3T', '4T'):
145
month = ( ( int(mod[0])-1 ) * 3 ) + 1
146
fecha_ini = datetime.strptime('%s-%s-01' % (dec_year, month), '%Y-%m-%d')
147
fecha_fin = fecha_ini + relativedelta(months=+3, days=-1)
149
account_period_id = period_obj.search(cr,uid,[('date_start','=',fecha_ini),('date_stop','=',fecha_fin)])
150
if not account_period_id:
151
account_period_id = period_obj.search(cr,uid,[('quarter','=',quarter_dict[mod])])
152
if not account_period_id:
153
raise osv.except_osv(_('El periodo seleccionado no coincide con los periodos del año fiscal:'), dec_year)
155
return account_period_id
158
def _get_report_lines(self, cr, uid, ids, context=None):
159
"""get report lines"""
162
dict_code_values = {}
163
for i in range(1,51):
164
dict_code_values["[%.2d]" % i] = 0
166
for mod303 in self.browse(cr, uid, ids, context):
168
generate_line = tax_report(cr,uid,"account.vat.declaration")
169
generate_line.period_ids = self._get_period(cr,uid,[mod303.id],context)
170
generate_line.display_detail = False
171
lines = generate_line._get_lines( 'invoices', mod303.company_id.id)
173
ordered_lines = sorted(lines, key=lambda k: k['code'])
176
for code in dict_code_values.keys():
177
for line in ordered_lines:
178
if code == line["code"]:
179
dict_code_values[code] += line["tax_amount"]
181
return dict_code_values
186
def action_confirm(self, cr, uid, ids, context=None):
187
"""set to done the report and check its records"""
188
if context is None: context = {}
189
for mod303 in self.browse(cr, uid, ids, context):
190
report_lines = self._get_report_lines(cr, uid, ids, context)
191
regularizacion_anual = mod303.regularizacion_anual if ( mod303.period == "4T" or mod303.period == "12" ) else 0
192
total_devengado = report_lines.get("[21]")
193
total_deducir = report_lines.get("[37]")
194
atribuible_estado = (total_devengado - total_deducir) * mod303.porcentaje_atribuible_estado / 100 ## casilla 40
195
casilla_46 = atribuible_estado - mod303.cuota_compensar + regularizacion_anual
196
previus_result = mod303.previus_result if mod303.complementaria else 0
197
resultado_liquidacion = casilla_46 - previus_result
199
'state': 'calculated',
200
'calculation_date':time.strftime('%Y-%m-%d'),
201
'total_devengado':total_devengado,
202
'total_deducir':total_deducir,
203
'diferencia': total_devengado - total_deducir,
204
'atribuible_estado' : atribuible_estado,
205
'resultado_casilla_46' : casilla_46,
206
'resultado_liquidacion' : resultado_liquidacion,
207
'compensar' : abs(resultado_liquidacion) if resultado_liquidacion < 0 and mod303.devolver == 0 else 0,
208
'ingresar' : resultado_liquidacion if resultado_liquidacion > 0 else 0
211
if mod303.regularizacion_anual > 0 and not ( mod303.period == "4T" and mod303.period == "12" ):
212
self.log(cr,uid,mod303.id,_("El valor añadido para la regularizacion anual no se ha tendio en cuenta por no ser un periodo de cierre (12 o 4T)"),context)
214
self.write(cr, uid, mod303.id, vals)
218
def confirm(self, cr, uid, ids, context=None):
219
"""set to done the report and check its records"""
222
for mod303 in self.browse(cr,uid,ids,context):
224
if mod303.ingresar > 0 and not mod303.cuenta_ingreso_id:
225
msg_validation = _('Seleccione una cuenta para ingresar el importe')
226
if mod303.devolver > 0 and not mod303.cuenta_devolucion_id:
227
msg_validation = _('Seleccione una cuenta para realizar la devolución')
228
if mod303.resultado_liquidacion == 0 and not mod303.sin_actividad:
229
msg_validation = _("No hay actividad en el periodo seleccionado, marque la casilla correspondinte")
233
raise osv.except_osv("",msg_validation)
235
self.write(cr, uid, ids, {'state': 'done'})
239
def cancel(self, cr, uid, ids, context=None):
240
"""set to done the report and check its records"""
241
self.write(cr, uid, ids, {'state': 'canceled'})
245
l10n_es_aeat_mod303_report()