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

« back to all changes in this revision

Viewing changes to l10n_es_extras/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()