~openerp-spain-team/openerp-spain/6.0-git

« back to all changes in this revision

Viewing changes to l10n_es_hr_nominas/hr_nominas.py

  • Committer: Borja L.S.
  • Date: 2010-10-18 10:04:25 UTC
  • Revision ID: git-v1:271c47a993616dbba60585d48b8b98d603199d93
[REF] *: Refactorización para portar a 6.0 - Paso 1.

- Se han renombrado los módulos para usar la nomenclatura propuesta
  por OpenERP: l10n_es para el módulo base de localización (plan de 
  cuentas), l10n_es_* para el resto de módulos.

- Se eliminan los módulos extra_addons/* que deberían moverse a 
  los extra-addons genéricos (no son específicos de España).

- Se renombran los __terp__.py por __openerp__.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2009 Ting! (<http://www.ting.es>). All Rights Reserved
 
6
#    d$
 
7
#
 
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.
 
12
#
 
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.
 
17
#
 
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/>.
 
20
#
 
21
##############################################################################
 
22
 
 
23
from osv import osv
 
24
from osv import fields
 
25
import time
 
26
import datetime
 
27
import pooler
 
28
from tools.translate import _
 
29
 
 
30
class res_company(osv.osv):
 
31
        _name = 'res.company'
 
32
        _inherit = 'res.company'
 
33
        _columns = {
 
34
                'diario_destino': fields.many2one('account.journal', 'Diario de Destino', required=True),               
 
35
                'cuenta_ss_empresa': fields.many2one('account.account', 'Cuenta Seguridad Social a cargo de la empresa', required=True),
 
36
                'cuenta_ss_acreedores': fields.many2one('account.account', 'Cuenta Organismos de la S.S acreedores', required=True),
 
37
                'cuenta_hacienda_publica': fields.many2one('account.account', 'Cuenta H.P acreedor por retenciones practicadas', required=True),
 
38
                'cuenta_pendientes_pago': fields.many2one('account.account', 'Cuenta Remuneraciones pendientes de pago', required=True),
 
39
                'cuenta_bancos': fields.many2one('account.account', 'Cuenta Bancos e instituciones de crédito', required=True),
 
40
                'cuenta_anticipos': fields.many2one('account.account', 'Cuenta anticipos de remuneraciones', required=True),
 
41
        }
 
42
 
 
43
res_company()
 
44
 
 
45
def get_configuration(cr, uid, ids, context=None):
 
46
        pool = pooler.get_pool(cr.dbname)
 
47
        obj_user = pool.get('res.users').browse(cr, uid, uid)
 
48
        obj_company = pool.get('res.company').browse(cr, uid, obj_user.company_id.id)
 
49
        res = {}
 
50
        if obj_company.cuenta_ss_empresa:#Como las cuentas son obligatorias si esta definida esta cuenta estarán todas definidas
 
51
                res['diario_destino'] = obj_company.diario_destino.id
 
52
                res['cuenta_ss_empresa'] = obj_company.cuenta_ss_empresa.id
 
53
                res['cuenta_ss_acreedores'] = obj_company.cuenta_ss_acreedores.id
 
54
                res['cuenta_hacienda_publica'] = obj_company.cuenta_hacienda_publica.id
 
55
                res['cuenta_pendientes_pago'] = obj_company.cuenta_pendientes_pago.id
 
56
                res['cuenta_bancos'] = obj_company.cuenta_bancos.id
 
57
                res['cuenta_anticipos'] = obj_company.cuenta_anticipos.id                       
 
58
                return res
 
59
        else:
 
60
                company_name = str(obj_user.company_id.name)
 
61
                raise osv.except_osv(_('No hay una configuración de cuentas activa para la compañia ') + company_name, _('Debe configurar las cuentas!\nPor favor configure las cuentas en el menú de configuración de la compañia: ') + company_name)
 
62
 
 
63
class hr_employee(osv.osv):
 
64
        _name = 'hr.employee'
 
65
        _inherit = 'hr.employee'
 
66
        _columns = {
 
67
          'retribucion_bruta': fields.float('Retribución Bruta', digits=(16, 2)),
 
68
          'ss_empresa': fields.float('S.S a Cargo de la empresa', digits=(16, 2)),
 
69
          'ss_trabajador': fields.float('S.S a cargo del Trabajador', digits=(16, 2)),
 
70
          'irpf': fields.float('Retención IRPF (%)', digits=(16, 2)),
 
71
      'retribucion_bruta_extra': fields.float('Retribución Bruta', digits=(16, 2)),
 
72
      'ss_empresa_extra': fields.float('S.S a Cargo de la empresa', digits=(16, 2)),
 
73
      'ss_trabajador_extra': fields.float('S.S a cargo del Trabajador', digits=(16, 2)),
 
74
      'irpf_extra': fields.float('Retención IRPF (%)', digits=(16, 2)),
 
75
          'nominas_ids': fields.one2many('hr.nomina', 'employee_id', 'Nóminas del Empleado', readonly=True),
 
76
          'anticipos_ids': fields.one2many('hr.anticipo', 'employee_id', 'Anticipos del Empleado', readonly=True),
 
77
          'cuenta_id': fields.many2one('account.account', 'Cuenta', required=True, help="El empleado debe tener una cuenta para su nómina."),
 
78
        }
 
79
        _defaults = {
 
80
                'cuenta_id': lambda * a: 377 or None,
 
81
        }
 
82
 
 
83
        
 
84
hr_employee()
 
85
 
 
86
class hr_nomina(osv.osv):
 
87
    _name = 'hr.nomina'
 
88
    _description = 'Nominas de Empleados'
 
89
    _columns = {
 
90
       'name': fields.char('Nómina', size=20),
 
91
       'employee_id': fields.many2one('hr.employee', 'Empleado', required=True, select="1"),
 
92
       'retribucion_bruta': fields.float('Retribución Bruta', digits=(16, 2)),
 
93
       'ss_empresa': fields.float('S.S a Cargo de la empresa', digits=(16, 2)),
 
94
       'ss_trabajador': fields.float('S.S a cargo del Trabajador', digits=(16, 2)),
 
95
       'irpf': fields.float('Retención IRPF (%)', digits=(16, 2)),
 
96
       'fecha_nomina': fields.date('Fecha de la Nómina', select="1"),
 
97
       'state': fields.selection((('borrador', 'Borrador'),
 
98
                                  ('confirmada', 'Confirmada'),
 
99
                                  ('pagada', 'Pagada'),
 
100
                                  ('cancelada', 'Cancelada')), 'Estado Nómina', readonly=True, select="2"),
 
101
       'numero': fields.char('Número de nomina', size=32, readonly=True, help="Número único de nómina, se asigna automáticamente cuando se crea la nómina", select="1"),
 
102
       'extra': fields.boolean('Paga Extra'),
 
103
       'asiento_nomina_confirmada': fields.many2one('account.move', 'Asiento Nómina confirmada', readonly=True),
 
104
       'asiento_nomina_pagada': fields.many2one('account.move', 'Asiento Nómina pagada', readonly=True),
 
105
    }
 
106
 
 
107
    _defaults = {
 
108
        'state': lambda * a:'borrador',
 
109
    }
 
110
 
 
111
    def comprueba_mes(self, fecha_anticipo, fecha_nomina):
 
112
        anticipo = time.strptime(fecha_anticipo, '%Y-%m-%d')
 
113
        nomina = time.strptime(fecha_nomina, '%Y-%m-%d')
 
114
        dateNomina = datetime.datetime(nomina[0], nomina[1], nomina[2])
 
115
        dateAnterior = time.strptime((dateNomina - datetime.timedelta(nomina[2] + 1)).strftime('%Y-%m-%d'), '%Y-%m-%d')
 
116
 
 
117
        if (anticipo[0] == dateAnterior[0]) and (dateAnterior[1] == anticipo[1]): #Si se solicito anticipo el mes pasado
 
118
                return True
 
119
        else:
 
120
            return False
 
121
 
 
122
    def comprueba_anticipo(self, cr, uid, ids, fechaNomina, empleado_id):
 
123
        anticipo_ids = self.pool.get('hr.anticipo').search(cr, uid, [('employee_id', '=', empleado_id)])
 
124
        for anticipo in anticipo_ids:
 
125
                obj_anticipo = self.pool.get('hr.anticipo').browse(cr, uid, anticipo)
 
126
                if self.comprueba_mes(obj_anticipo.fecha_anticipo, fechaNomina) and obj_anticipo.state == 'pagado':
 
127
                        return obj_anticipo.cantidad
 
128
        
 
129
        return 0
 
130
 
 
131
    def confirmar_nomina(self, cr, uid, ids, *args):
 
132
        cuentas = get_configuration(cr, uid, ids)
 
133
        for nom in self.browse(cr, uid, ids):
 
134
            if nom.state != 'borrador':
 
135
                continue
 
136
            journal_id = cuentas['diario_destino']
 
137
            numero = self.pool.get('ir.sequence').get(cr, uid, 'hr.nomina')
 
138
            journal = self.pool.get('account.journal').browse(cr, uid, journal_id)
 
139
            fechaNomina = nom.fecha_nomina
 
140
            line = {}
 
141
 
 
142
            period_ids = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', fechaNomina or time.strftime('%Y-%m-%d')), ('date_stop', '>=', fechaNomina or time.strftime('%Y-%m-%d'))])
 
143
            if len(period_ids):
 
144
                periodo_id = period_ids[0]
 
145
            else:
 
146
                raise osv.except_osv(_('No existe un periodo para esa fecha de nomina!'), _('No se pueden generar nóminas cuya fecha esté en un periodo que no existe, \nsi desea generarla por favor cree el periodo contable correspondiente.'))
 
147
 
 
148
            referencia = numero + ' : ' + nom.employee_id.name + ' - ' + fechaNomina
 
149
            if nom.extra:
 
150
                referencia = "Paga Extra: " + nom.employee_id.name + ' - ' + fechaNomina
 
151
            move = {'ref': referencia, 'journal_id': journal_id, 'date': fechaNomina, 'period_id': periodo_id}
 
152
 
 
153
            move_id = self.pool.get('account.move').create(cr, uid, move)
 
154
 
 
155
            obj_linea = self.pool.get('account.move.line')
 
156
            #Cuenta del empleado
 
157
            cuenta_id = nom.employee_id.cuenta_id.id
 
158
            #si no tiene cuenta lanzamos un error
 
159
            if not cuenta_id:
 
160
                raise osv.except_osv(_('No existe una cuenta configurada para el empleado!'), _('Por favor configure una cuenta en la ficha del empleado en la que generar los asientos de la nómina.'))
 
161
            retencion_irpf = (nom.retribucion_bruta * nom.irpf) / 100
 
162
            anticipo = self.comprueba_anticipo(cr, uid, ids, fechaNomina, nom.employee_id.id)
 
163
 
 
164
            sueldo_neto = nom.retribucion_bruta - retencion_irpf - nom.ss_trabajador
 
165
            if anticipo and nom.extra == False:
 
166
                sueldo_neto -= anticipo
 
167
                obj_linea.create(cr, uid, {'account_id': cuentas['cuenta_anticipos'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Anticipo', 'credit': anticipo, 'ref': referencia})
 
168
                
 
169
            obj_linea.create(cr, uid, {'account_id': cuenta_id, 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Sueldo Bruto', 'debit': nom.retribucion_bruta , 'ref': referencia})
 
170
            obj_linea.create(cr, uid, {'account_id': cuentas['cuenta_ss_empresa'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'S.S. Empresa', 'debit': nom.ss_empresa, 'ref': referencia})
 
171
            obj_linea.create(cr, uid, {'account_id': cuentas['cuenta_hacienda_publica'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'IRPF', 'credit': retencion_irpf, 'ref': referencia})
 
172
            obj_linea.create(cr, uid, {'account_id': cuentas['cuenta_ss_acreedores'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'S.S. Acreedores ', 'credit': nom.ss_trabajador + nom.ss_empresa, 'ref': referencia})
 
173
            obj_linea.create(cr, uid, {'account_id': cuentas['cuenta_pendientes_pago'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Sueldo Neto', 'credit': sueldo_neto, 'ref': referencia})
 
174
 
 
175
            self.pool.get('account.move').write(cr, uid, [move_id], {'date': fechaNomina})
 
176
            self.pool.get('account.move').post(cr, uid, [move_id])
 
177
            self.write(cr, uid, ids, {'numero': numero})
 
178
            self.write(cr, uid, ids, {'state': 'confirmada', 'asiento_nomina_confirmada': move_id})
 
179
 
 
180
    def pagar_nomina(self, cr, uid, ids, *args):
 
181
        cuentas = get_configuration(cr, uid, ids)
 
182
        for nom in self.browse(cr, uid, ids):
 
183
            if nom.state != 'confirmada':
 
184
                continue
 
185
            journal_id = cuentas['diario_destino']
 
186
            journal = self.pool.get('account.journal').browse(cr, uid, journal_id)
 
187
            fechaNomina = nom.fecha_nomina
 
188
            line = {}
 
189
 
 
190
            period_ids = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', fechaNomina or time.strftime('%Y-%m-%d')), ('date_stop', '>=', fechaNomina or time.strftime('%Y-%m-%d'))])
 
191
            if len(period_ids):
 
192
                periodo_id = period_ids[0]
 
193
 
 
194
            referencia = nom.numero + ' : Pago ' + nom.employee_id.name + ' - ' + fechaNomina
 
195
            if nom.extra:
 
196
                referencia = "Pago de Paga Extra: " + nom.employee_id.name + ' - ' + fechaNomina
 
197
            move = {'ref': referencia, 'journal_id': journal_id, 'date': fechaNomina, 'period_id': periodo_id}
 
198
 
 
199
            move_id = self.pool.get('account.move').create(cr, uid, move)
 
200
 
 
201
            retencion_irpf = (nom.retribucion_bruta * nom.irpf) / 100
 
202
            sueldo_neto = nom.retribucion_bruta - retencion_irpf - nom.ss_trabajador
 
203
            anticipo = self.comprueba_anticipo(cr, uid, ids, fechaNomina, nom.employee_id.id)
 
204
            if anticipo and nom.extra == False:
 
205
                sueldo_neto -= anticipo
 
206
 
 
207
            self.pool.get('account.move.line').create(cr, uid, {'account_id': cuentas['cuenta_bancos'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Banco', 'credit': sueldo_neto, 'ref': referencia})
 
208
            self.pool.get('account.move.line').create(cr, uid, {'account_id': cuentas['cuenta_pendientes_pago'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Renumeraciones pendientes', 'debit': sueldo_neto, 'ref': referencia})
 
209
 
 
210
            self.write(cr, uid, ids, {'state': 'pagada', 'asiento_nomina_pagada':move_id})
 
211
            self.pool.get('account.move').write(cr, uid, [move_id], {'date': fechaNomina})
 
212
            self.pool.get('account.move').post(cr, uid, [move_id])
 
213
 
 
214
    def cancelar_nomina(self, cr, uid, ids, *args):
 
215
        for nom in self.browse(cr, uid, ids):
 
216
            acc_obj = self.pool.get('account.move')
 
217
            if nom.state == 'confirmada':
 
218
                acc_obj.button_cancel(cr, uid, [nom.asiento_nomina_confirmada.id])
 
219
                self.write(cr, uid, ids, {'state': 'cancelada'})
 
220
 
 
221
hr_nomina()
 
222
 
 
223
class hr_anticipo(osv.osv):
 
224
    _name = 'hr.anticipo'
 
225
    _description = 'Anticipos de Nominas'
 
226
    _columns = {
 
227
            'name': fields.char('Anticipo', size=30),
 
228
            'employee_id': fields.many2one('hr.employee', 'Empleado', required=True, select="1", readonly=True),
 
229
            'fecha_anticipo': fields.date('Fecha de Anticipo', select="1", readonly=True),
 
230
            'cantidad': fields.float('Cantidad Anticipo', digits=(16, 2), readonly=True),
 
231
            'state': fields.selection((('borrador', 'Borrador'),
 
232
                                       ('confirmado', 'Confirmado'),
 
233
                                       ('pagado', 'Pagado'),
 
234
                                       ('cancelado', 'Cancelado')), 'Estado de anticipo', readonly=True, select="1"),
 
235
            'asiento_anticipo': fields.many2one('account.move', 'Asiento Anticipo', readonly=True),
 
236
    }
 
237
 
 
238
    _defaults = {
 
239
            'state': lambda * a:'borrador',
 
240
    }
 
241
 
 
242
    def confirmar_anticipo(self, cr, uid, ids, *args):
 
243
        cuentas = get_configuration(cr, uid, ids)
 
244
        for anticipo in self.browse(cr, uid, ids):
 
245
            if anticipo.state != 'borrador':
 
246
                continue
 
247
            journal_id = cuentas['diario_destino']
 
248
            journal = self.pool.get('account.journal').browse(cr, uid, journal_id)
 
249
            fecha_anticipo = anticipo.fecha_anticipo
 
250
            #PERIODO
 
251
            period_ids = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', fecha_anticipo or time.strftime('%Y-%m-%d')), ('date_stop', '>=', fecha_anticipo or time.strftime('%Y-%m-%d'))])
 
252
            if len(period_ids):
 
253
                periodo_id = period_ids[0]
 
254
            referencia = 'Anticipo: ' + anticipo.employee_id.name + ' - ' + fecha_anticipo
 
255
            move_id = self.pool.get('account.move').create(cr, uid, {'ref': referencia, 'journal_id': journal_id, 'date': fecha_anticipo, 'period_id': periodo_id })
 
256
            self.pool.get('account.move.line').create(cr, uid, {'account_id': cuentas['cuenta_anticipos'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Anticipo', 'debit': anticipo.cantidad, 'ref': referencia})
 
257
            self.pool.get('account.move.line').create(cr, uid, {'account_id': cuentas['cuenta_bancos'], 'move_id': move_id, 'journal_id': journal_id, 'period_id': periodo_id, 'name': 'Bancos', 'credit': anticipo.cantidad, 'ref': referencia})
 
258
            self.write(cr, uid, ids, {'state': 'confirmado', 'asiento_anticipo': move_id})
 
259
            self.pool.get('account.move').write(cr, uid, [move_id], {'date': fecha_anticipo})
 
260
 
 
261
    def pagar_anticipo(self, cr, uid, ids, *args):
 
262
        for ant in self.browse(cr, uid, ids):
 
263
            if ant.state != 'confirmado':
 
264
                continue
 
265
            acc_obj = self.pool.get('account.move')
 
266
            acc_obj.post(cr, uid, [ant.asiento_anticipo.id])
 
267
            self.write(cr, uid, ids, {'state':'pagado'})
 
268
 
 
269
    def cancelar_anticipo(self, cr, uid, ids, *args):
 
270
        for ant in self.browse(cr, uid, ids):
 
271
            acc_obj = self.pool.get('account.move')
 
272
            if ant.state == 'confirmado':
 
273
                self.write(cr, uid, ids, {'state':'cancelado'})
 
274
hr_anticipo()