2010-06-05 06:39:12 +00:00
#-*- coding:utf-8 -*-
##############################################################################
#
2010-07-01 07:31:46 +00:00
# OpenERP, Open Source Management Solution
2010-06-05 06:39:12 +00:00
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# d$
#
# This program is free software: you can redistribute it and/or modify
2010-10-28 06:54:18 +00:00
# it under the terms of the GNU Affero General Public License as published by
2010-06-05 06:39:12 +00:00
# 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
2010-10-28 06:54:18 +00:00
# GNU Affero General Public License for more details.
2010-06-05 06:39:12 +00:00
#
2010-10-28 06:54:18 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-06-05 06:39:12 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2010-06-05 07:32:16 +00:00
import time
2010-10-06 12:44:54 +00:00
from datetime import date
from datetime import datetime
from datetime import timedelta
2010-07-27 07:11:45 +00:00
2010-10-06 12:44:54 +00:00
import netsvc
2010-07-27 07:11:45 +00:00
from osv import fields , osv
2010-12-24 12:05:44 +00:00
import tools
2010-06-05 07:32:16 +00:00
from tools . translate import _
2010-11-03 08:04:42 +00:00
import decimal_precision as dp
2010-06-05 07:32:16 +00:00
2010-06-18 03:11:40 +00:00
def prev_bounds ( cdate = False ) :
when = date . fromtimestamp ( time . mktime ( time . strptime ( cdate , " % Y- % m- %d " ) ) )
this_first = date ( when . year , when . month , 1 )
month = when . month + 1
year = when . year
if month > 12 :
month = 1
year + = 1
next_month = date ( year , month , 1 )
prev_end = next_month - timedelta ( days = 1 )
return this_first , prev_end
2010-06-06 18:26:08 +00:00
class hr_payroll_structure ( osv . osv ) :
"""
Salary structure used to defined
2010-06-09 14:38:22 +00:00
- Basic
2011-02-25 13:43:14 +00:00
- Allowances
2010-06-09 14:38:22 +00:00
- Deductions
2010-06-06 18:26:08 +00:00
"""
2010-10-26 12:23:32 +00:00
2010-06-06 18:26:08 +00:00
_name = ' hr.payroll.structure '
_description = ' Salary Structure '
2010-06-05 07:32:16 +00:00
_columns = {
2011-03-08 06:36:37 +00:00
' name ' : fields . char ( ' Name ' , size = 256 , required = True ) ,
' code ' : fields . char ( ' Code ' , size = 64 , required = True ) ,
2011-03-07 07:18:29 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
2010-06-06 16:29:11 +00:00
' note ' : fields . text ( ' Description ' ) ,
2011-03-07 07:18:29 +00:00
' parent_id ' : fields . many2one ( ' hr.payroll.structure ' , ' Parent ' ) ,
2010-06-05 07:32:16 +00:00
}
_defaults = {
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
}
2010-07-01 07:31:46 +00:00
2010-06-05 07:32:16 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
2010-06-06 18:26:08 +00:00
"""
Create a new record in hr_payroll_structure model from existing one
@param cr : cursor to database
@param user : id of current user
@param id : list of record ids on which copy method executes
@param default : dict type contains the values to be override during copy of object
@param context : context arguments , like lang , time zone
2010-07-01 07:31:46 +00:00
2010-06-06 18:26:08 +00:00
@return : returns a id of newly created record
"""
2010-06-05 07:32:16 +00:00
default = {
2011-03-08 06:36:37 +00:00
' code ' : self . browse ( cr , uid , id , context = context ) . code + " (copy) " ,
2011-02-25 13:43:14 +00:00
' company_id ' : self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context ) . company_id . id
2010-06-05 07:32:16 +00:00
}
2010-10-27 13:10:19 +00:00
return super ( hr_payroll_structure , self ) . copy ( cr , uid , id , default , context = context )
2010-07-01 07:31:46 +00:00
2010-06-06 18:26:08 +00:00
hr_payroll_structure ( )
2010-06-05 07:32:16 +00:00
class hr_contract ( osv . osv ) :
2010-06-06 19:09:53 +00:00
"""
Employee contract based on the visa , work permits
2011-02-25 13:43:14 +00:00
allows to configure different Salary structure
2010-06-06 19:09:53 +00:00
"""
2010-10-26 12:23:32 +00:00
2010-06-05 07:32:16 +00:00
_inherit = ' hr.contract '
_description = ' Employee Contract '
_columns = {
2010-10-27 12:49:59 +00:00
' struct_id ' : fields . many2one ( ' hr.payroll.structure ' , ' Salary Structure ' ) ,
2011-03-08 06:36:37 +00:00
' basic ' : fields . float ( ' Basic Salary ' , digits_compute = dp . get_precision ( ' Account ' ) ) , # i think we can remove this because we have wage field on contract ?
2011-03-18 13:13:33 +00:00
' schedule_pay ' : fields . selection ( [
( ' monthly ' , ' Monthly ' ) ,
( ' quarterly ' , ' Quarterly ' ) ,
( ' semi-annually ' , ' Semi-annually ' ) ,
( ' annually ' , ' Annually ' ) ,
( ' weekly ' , ' Weekly ' ) ,
( ' bi-weekly ' , ' Bi-weekly ' ) ,
( ' bi-monthly ' , ' Bi-monthly ' ) ,
] , ' Scheduled Pay ' , select = True ) ,
2010-06-18 03:11:40 +00:00
}
2011-03-03 13:17:54 +00:00
2010-06-05 07:32:16 +00:00
hr_contract ( )
2010-06-06 16:29:11 +00:00
class payroll_register ( osv . osv ) :
2010-06-09 14:38:22 +00:00
"""
2010-06-06 16:29:11 +00:00
Payroll Register
2010-06-09 14:38:22 +00:00
"""
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_name = ' hr.payroll.register '
_description = ' Payroll Register '
2010-07-01 07:31:46 +00:00
2011-03-03 12:49:03 +00:00
# def _calculate(self, cr, uid, ids, field_names, arg, context=None):
# res = {}
# allounce = 0.0
# deduction = 0.0
# net = 0.0
# grows = 0.0
# for register in self.browse(cr, uid, ids, context=context):
# for slip in register.line_ids:
# allounce += slip.allounce
# deduction += slip.deduction
## net += slip.net
## grows += slip.grows
#
# res[register.id] = {
# 'allounce':allounce,
# 'deduction':deduction,
## 'net':net,
## 'grows':grows
# }
# return res
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
_columns = {
' name ' : fields . char ( ' Name ' , size = 64 , required = True , readonly = False ) ,
' date ' : fields . date ( ' Date ' , required = True ) ,
' number ' : fields . char ( ' Number ' , size = 64 , required = False , readonly = True ) ,
' line_ids ' : fields . one2many ( ' hr.payslip ' , ' register_id ' , ' Payslips ' , required = False ) ,
' state ' : fields . selection ( [
( ' new ' , ' New Slip ' ) ,
( ' draft ' , ' Wating for Verification ' ) ,
( ' hr_check ' , ' Wating for HR Verification ' ) ,
( ' accont_check ' , ' Wating for Account Verification ' ) ,
( ' confirm ' , ' Confirm Sheet ' ) ,
( ' done ' , ' Paid Salary ' ) ,
( ' cancel ' , ' Reject ' ) ,
] , ' State ' , select = True , readonly = True ) ,
' active ' : fields . boolean ( ' Active ' , required = False ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = False ) ,
2011-02-25 13:43:14 +00:00
# 'grows': fields.function(_calculate, method=True, store=True, multi='dc', string='Gross Salary', type='float', digits=(16, 4)),
# 'net': fields.function(_calculate, method=True, store=True, multi='dc', string='Net Salary', digits=(16, 4)),
2011-03-03 12:49:03 +00:00
# 'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits=(16, 4)),
# 'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits=(16, 4)),
2010-06-06 16:29:11 +00:00
' note ' : fields . text ( ' Description ' ) ,
2011-03-03 12:49:03 +00:00
' bank_id ' : fields . many2one ( ' res.bank ' , ' Bank ' , required = False , help = " Select the Bank Address from which the salary is going to be paid " ) ,
2010-06-06 16:29:11 +00:00
}
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
_defaults = {
' date ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
2011-02-25 13:43:14 +00:00
' state ' : ' new ' ,
' active ' : True ,
2010-06-06 16:29:11 +00:00
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
}
2010-07-27 07:11:45 +00:00
def compute_sheet ( self , cr , uid , ids , context = None ) :
2010-06-06 16:29:11 +00:00
emp_pool = self . pool . get ( ' hr.employee ' )
slip_pool = self . pool . get ( ' hr.payslip ' )
2011-03-16 11:43:02 +00:00
slip_line_pool = self . pool . get ( ' hr.payslip.line ' )
2010-06-06 16:29:11 +00:00
wf_service = netsvc . LocalService ( " workflow " )
2011-03-08 06:36:37 +00:00
2010-07-27 07:11:45 +00:00
if context is None :
context = { }
2010-10-06 12:44:54 +00:00
vals = self . browse ( cr , uid , ids [ 0 ] , context = context )
2010-07-27 07:11:45 +00:00
emp_ids = emp_pool . search ( cr , uid , [ ] , context = context )
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
for emp in emp_pool . browse ( cr , uid , emp_ids , context = context ) :
old_slips = slip_pool . search ( cr , uid , [ ( ' employee_id ' , ' = ' , emp . id ) , ( ' date ' , ' = ' , vals . date ) ] , context = context )
2010-06-06 16:29:11 +00:00
if old_slips :
2010-07-27 07:11:45 +00:00
slip_pool . write ( cr , uid , old_slips , { ' register_id ' : ids [ 0 ] } , context = context )
2010-07-02 10:37:15 +00:00
else :
res = {
' employee_id ' : emp . id ,
2011-03-09 06:11:11 +00:00
' basic_amount ' : 0.0 ,
2010-07-02 10:37:15 +00:00
' register_id ' : ids [ 0 ] ,
' name ' : vals . name ,
' date ' : vals . date ,
}
2010-07-27 07:11:45 +00:00
slip_id = slip_pool . create ( cr , uid , res , context = context )
2011-03-16 11:43:02 +00:00
data = slip_pool . onchange_employee_id ( cr , uid , [ slip_id ] , vals . date , emp . id , context = context )
2011-03-16 13:14:07 +00:00
for line in data [ ' value ' ] [ ' line_ids ' ] :
line . update ( { ' slip_id ' : slip_id } )
slip_line_pool . create ( cr , uid , line , context = context )
data [ ' value ' ] . pop ( ' line_ids ' )
slip_pool . write ( cr , uid , [ slip_id ] , data [ ' value ' ] , context = context )
2010-06-06 16:29:11 +00:00
number = self . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' salary.register ' )
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' draft ' , ' number ' : number } , context = context )
2010-06-06 16:29:11 +00:00
2010-10-26 12:23:32 +00:00
def set_to_draft ( self , cr , uid , ids , context = None ) :
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' draft ' } , context = context )
2010-10-26 12:23:32 +00:00
def cancel_sheet ( self , cr , uid , ids , context = None ) :
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' cancel ' } , context = context )
2010-10-26 12:23:32 +00:00
2010-07-27 07:11:45 +00:00
def verify_sheet ( self , cr , uid , ids , context = None ) :
2010-06-06 16:29:11 +00:00
slip_pool = self . pool . get ( ' hr.payslip ' )
for id in ids :
2010-07-27 07:11:45 +00:00
sids = slip_pool . search ( cr , uid , [ ( ' register_id ' , ' = ' , id ) ] , context = context )
2010-06-06 16:29:11 +00:00
wf_service = netsvc . LocalService ( " workflow " )
for sid in sids :
wf_service . trg_validate ( uid , ' hr.payslip ' , sid , ' verify_sheet ' , cr )
2010-07-01 07:31:46 +00:00
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' hr_check ' } , context = context )
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def final_verify_sheet ( self , cr , uid , ids , context = None ) :
2010-06-06 16:29:11 +00:00
slip_pool = self . pool . get ( ' hr.payslip ' )
2010-07-27 07:11:45 +00:00
sequence_pool = self . pool . get ( ' ir.sequence ' )
users_pool = self . pool . get ( ' res.users ' )
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
for id in ids :
2010-07-27 07:11:45 +00:00
sids = slip_pool . search ( cr , uid , [ ( ' register_id ' , ' = ' , id ) , ( ' state ' , ' = ' , ' hr_check ' ) ] , context = context )
2010-06-06 16:29:11 +00:00
wf_service = netsvc . LocalService ( " workflow " )
for sid in sids :
wf_service . trg_validate ( uid , ' hr.payslip ' , sid , ' final_verify_sheet ' , cr )
2010-10-26 12:23:32 +00:00
2010-10-06 12:44:54 +00:00
company_name = users_pool . browse ( cr , uid , uid , context = context ) . company_id . name
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' confirm ' } , context = context )
2010-06-06 16:29:11 +00:00
2010-07-27 07:11:45 +00:00
def process_sheet ( self , cr , uid , ids , context = None ) :
2010-06-06 16:29:11 +00:00
slip_pool = self . pool . get ( ' hr.payslip ' )
for id in ids :
2010-07-27 07:11:45 +00:00
sids = slip_pool . search ( cr , uid , [ ( ' register_id ' , ' = ' , id ) , ( ' state ' , ' = ' , ' confirm ' ) ] , context = context )
2010-06-06 16:29:11 +00:00
wf_service = netsvc . LocalService ( " workflow " )
for sid in sids :
wf_service . trg_validate ( uid , ' hr.payslip ' , sid , ' process_sheet ' , cr )
2011-03-08 06:36:37 +00:00
return self . write ( cr , uid , ids , { ' state ' : ' done ' } , context = context )
2010-06-06 16:29:11 +00:00
payroll_register ( )
class contrib_register ( osv . osv ) :
'''
Contribution Register
'''
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_name = ' hr.contibution.register '
_description = ' Contribution Register '
2010-07-01 07:31:46 +00:00
2010-11-19 13:48:01 +00:00
def _total_contrib ( self , cr , uid , ids , field_names , arg , context = None ) :
2010-06-06 16:29:11 +00:00
line_pool = self . pool . get ( ' hr.contibution.register.line ' )
2010-10-06 12:44:54 +00:00
2010-06-06 16:29:11 +00:00
res = { }
2010-07-27 07:11:45 +00:00
for cur in self . browse ( cr , uid , ids , context = context ) :
2010-10-06 12:44:54 +00:00
current = line_pool . search ( cr , uid , [ ( ' register_id ' , ' = ' , cur . id ) ] , context = context )
2010-06-06 16:29:11 +00:00
e_month = 0.0
c_month = 0.0
2010-07-27 07:11:45 +00:00
for i in line_pool . browse ( cr , uid , current , context = context ) :
2010-06-06 16:29:11 +00:00
e_month + = i . emp_deduction
c_month + = i . comp_deduction
res [ cur . id ] = {
' monthly_total_by_emp ' : e_month ,
' monthly_total_by_comp ' : c_month ,
}
return res
_columns = {
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = False ) ,
' name ' : fields . char ( ' Name ' , size = 256 , required = True , readonly = False ) ,
' register_line_ids ' : fields . one2many ( ' hr.contibution.register.line ' , ' register_id ' , ' Register Line ' , readonly = True ) ,
2010-10-06 12:44:54 +00:00
' monthly_total_by_emp ' : fields . function ( _total_contrib , method = True , multi = ' dc ' , string = ' Total By Employee ' , digits = ( 16 , 4 ) ) ,
' monthly_total_by_comp ' : fields . function ( _total_contrib , method = True , multi = ' dc ' , string = ' Total By Company ' , digits = ( 16 , 4 ) ) ,
2010-06-06 16:29:11 +00:00
' note ' : fields . text ( ' Description ' ) ,
}
_defaults = {
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
}
2011-03-08 06:36:37 +00:00
2010-06-06 16:29:11 +00:00
contrib_register ( )
class contrib_register_line ( osv . osv ) :
'''
Contribution Register Line
'''
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_name = ' hr.contibution.register.line '
_description = ' Contribution Register Line '
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def _total ( self , cr , uid , ids , field_names , arg , context = None ) :
2010-06-06 16:29:11 +00:00
res = { }
2010-07-27 07:11:45 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2010-06-06 16:29:11 +00:00
res [ line . id ] = line . emp_deduction + line . comp_deduction
return res
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
_columns = {
' name ' : fields . char ( ' Name ' , size = 256 , required = True , readonly = False ) ,
' register_id ' : fields . many2one ( ' hr.contibution.register ' , ' Register ' , required = False ) ,
' code ' : fields . char ( ' Code ' , size = 64 , required = False , readonly = False ) ,
' employee_id ' : fields . many2one ( ' hr.employee ' , ' Employee ' , required = True ) ,
2010-10-06 12:44:54 +00:00
' date ' : fields . date ( ' Date ' ) ,
2010-07-07 06:21:07 +00:00
' emp_deduction ' : fields . float ( ' Employee Deduction ' , digits = ( 16 , 4 ) ) ,
' comp_deduction ' : fields . float ( ' Company Deduction ' , digits = ( 16 , 4 ) ) ,
' total ' : fields . function ( _total , method = True , store = True , string = ' Total ' , digits = ( 16 , 4 ) ) ,
2010-06-06 16:29:11 +00:00
}
2010-10-06 12:44:54 +00:00
_defaults = {
' date ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
}
2010-06-06 16:29:11 +00:00
contrib_register_line ( )
2011-03-02 12:00:23 +00:00
class hr_salary_head_type ( osv . osv ) :
2010-06-09 14:38:22 +00:00
"""
2011-02-25 13:07:26 +00:00
Salary Head Type
2010-06-09 14:38:22 +00:00
"""
2010-07-01 07:31:46 +00:00
2011-03-02 12:00:23 +00:00
_name = ' hr.salary.head.type '
2011-02-25 13:07:26 +00:00
_description = ' Salary Head Type '
2010-06-06 16:29:11 +00:00
_columns = {
2011-03-08 06:36:37 +00:00
' name ' : fields . char ( ' Type Name ' , size = 64 , required = True ) ,
' code ' : fields . char ( ' Type Code ' , size = 16 , required = True ) ,
2010-06-09 14:38:22 +00:00
}
2011-03-02 12:00:23 +00:00
hr_salary_head_type ( )
2011-02-25 13:07:26 +00:00
2011-03-03 09:52:26 +00:00
class hr_salary_head ( osv . osv ) :
2010-06-09 14:38:22 +00:00
"""
2011-03-08 06:36:37 +00:00
HR Salary Head
2010-06-09 14:38:22 +00:00
"""
2010-07-01 07:31:46 +00:00
2011-03-03 09:52:26 +00:00
_name = ' hr.salary.head '
_description = ' Salary Head '
2010-06-09 14:38:22 +00:00
_columns = {
2011-03-07 07:18:29 +00:00
' name ' : fields . char ( ' Name ' , size = 64 , required = True , readonly = False ) ,
' code ' : fields . char ( ' Code ' , size = 64 , required = True , readonly = False ) ,
2011-03-02 12:00:23 +00:00
' type ' : fields . many2one ( ' hr.salary.head.type ' , ' Type ' , required = True , help = " It is used only for the reporting purpose. " ) ,
2010-06-09 14:54:48 +00:00
' note ' : fields . text ( ' Description ' ) ,
2010-06-09 14:38:22 +00:00
' user_id ' : fields . char ( ' User ' , size = 64 , required = False , readonly = False ) ,
' state ' : fields . char ( ' Label ' , size = 64 , required = False , readonly = False ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = False ) ,
2011-03-08 06:36:37 +00:00
' dispaly_payslip_report ' : fields . boolean ( ' Display on payslip report ' , help = " Used for the display of head on Payslip Report " ) ,
2011-03-03 09:52:26 +00:00
# 'computation_based':fields.selection([
# ('rules','List of Rules'),
# ('exp','Expression'),
# ],'Computation Based On', select=True, required=True),
2010-06-06 16:29:11 +00:00
}
2011-03-08 06:36:37 +00:00
2010-06-06 16:29:11 +00:00
_defaults = {
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
2011-03-01 13:29:38 +00:00
' dispaly_payslip_report ' : 1 ,
2010-06-06 16:29:11 +00:00
}
2011-03-08 06:36:37 +00:00
2011-03-03 09:52:26 +00:00
hr_salary_head ( )
2010-06-06 16:29:11 +00:00
class hr_holidays_status ( osv . osv ) :
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_inherit = " hr.holidays.status "
_columns = {
2011-03-08 06:36:37 +00:00
# improve help
' code ' : fields . char ( ' Code ' , size = 16 , readonly = False , help = " It is used to define the code for Leave Type which will then be used in Salary Rules. " ) ,
2010-06-06 16:29:11 +00:00
}
2011-03-08 06:36:37 +00:00
2010-06-06 16:29:11 +00:00
hr_holidays_status ( )
class hr_payslip ( osv . osv ) :
'''
Pay Slip
'''
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_name = ' hr.payslip '
_description = ' Pay Slip '
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def _calculate ( self , cr , uid , ids , field_names , arg , context = None ) :
2011-02-25 13:43:14 +00:00
if not ids : return { }
2010-06-06 16:29:11 +00:00
res = { }
2010-07-27 07:11:45 +00:00
for rs in self . browse ( cr , uid , ids , context = context ) :
2010-06-06 16:29:11 +00:00
allow = 0.0
deduct = 0.0
others = 0.0
2011-03-11 12:23:26 +00:00
for line in rs . line_ids :
2011-03-07 13:13:29 +00:00
contrib = 0.0
2011-03-11 12:23:26 +00:00
if line . total < 0 :
deduct + = line . total
2011-03-07 13:13:29 +00:00
others + = contrib
2011-03-11 12:23:26 +00:00
# amount -= contrib
2011-03-07 13:13:29 +00:00
else :
2011-03-11 12:23:26 +00:00
allow + = line . total
2011-03-07 13:13:29 +00:00
others - = contrib
2011-03-11 12:23:26 +00:00
# amount += contrib
2011-03-07 13:13:29 +00:00
record = {
' allounce ' : allow ,
' deduction ' : deduct ,
2011-03-11 12:23:26 +00:00
' grows_amount ' : rs . basic_amount + allow ,
' net_amount ' : rs . basic_amount + allow + deduct ,
2011-03-07 13:13:29 +00:00
' other_pay ' : others ,
' state ' : ' draft ' ,
2011-03-11 12:23:26 +00:00
' total_pay ' : rs . basic_amount + allow + deduct
2011-03-07 13:13:29 +00:00
}
res [ rs . id ] = record
2010-06-06 16:29:11 +00:00
return res
2010-07-01 07:31:46 +00:00
2011-03-14 06:16:21 +00:00
def _get_holidays ( self , cr , uid , ids , field_name , arg , context = None ) :
result = { }
for record in self . browse ( cr , uid , ids , context = context ) :
result [ record . id ] = [ ]
dates = prev_bounds ( record . date )
sql = ''' SELECT id FROM hr_holidays
WHERE date_from > = ' %s ' AND date_to < = ' %s '
AND employee_id = % s
''' % (dates[0], dates[1], record.employee_id.id)
cr . execute ( sql )
res = cr . fetchall ( )
if res :
result [ record . id ] = [ x [ 0 ] for x in res ]
return result
2011-03-18 11:46:19 +00:00
def _compute ( self , cr , uid , id , value , context = None ) :
rule_obj = self . pool . get ( ' hr.salary.rule ' )
contrib = rule_obj . browse ( cr , uid , id , context = context )
if contrib . amt_type == ' fix ' :
return contrib . contribute_per
elif contrib . amt_type == ' per ' :
return value * contrib . contribute_per
return 0.0
2011-03-14 06:16:21 +00:00
2010-06-06 16:29:11 +00:00
_columns = {
2011-03-14 08:57:50 +00:00
' struct_id ' : fields . many2one ( ' hr.payroll.structure ' , ' Designation ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' register_id ' : fields . many2one ( ' hr.payroll.register ' , ' Register ' , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' name ' : fields . char ( ' Name ' , size = 64 , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' number ' : fields . char ( ' Number ' , size = 64 , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' employee_id ' : fields . many2one ( ' hr.employee ' , ' Employee ' , required = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' date ' : fields . date ( ' Date ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2010-06-06 16:29:11 +00:00
' state ' : fields . selection ( [
( ' draft ' , ' Wating for Verification ' ) ,
( ' hr_check ' , ' Wating for HR Verification ' ) ,
( ' accont_check ' , ' Wating for Account Verification ' ) ,
( ' confirm ' , ' Confirm Sheet ' ) ,
( ' done ' , ' Paid Salary ' ) ,
( ' cancel ' , ' Reject ' ) ,
] , ' State ' , select = True , readonly = True ) ,
2011-03-09 06:11:11 +00:00
' basic_before_leaves ' : fields . float ( ' Basic Salary ' , readonly = True , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2010-11-03 08:04:42 +00:00
' leaves ' : fields . float ( ' Leave Deductions ' , readonly = True , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2011-03-09 06:11:11 +00:00
' basic_amount ' : fields . related ( ' contract_id ' , ' wage ' , type = ' float ' , relation = ' hr.contract ' , store = True , string = ' Basic Amount ' ) ,
' gross_amount ' : fields . function ( _calculate , method = True , store = True , multi = ' dc ' , string = ' Gross Salary ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
' net_amount ' : fields . function ( _calculate , method = True , store = True , multi = ' dc ' , string = ' Net Salary ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2011-03-08 06:36:37 +00:00
# 'allounce': fields.function(_calculate, method=True, store=True, multi='dc', string='Allowance', digits_compute=dp.get_precision('Account')),
# 'deduction': fields.function(_calculate, method=True, store=True, multi='dc', string='Deduction', digits_compute=dp.get_precision('Account')),
# 'other_pay': fields.function(_calculate, method=True, store=True, multi='dc', string='Others', digits_compute=dp.get_precision('Account')),
2011-03-02 09:34:07 +00:00
' total_pay ' : fields . function ( _calculate , method = True , store = True , multi = ' dc ' , string = ' Total Payment ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
# 'total_pay': fields.float('Total Payment', readonly=True, digits_compute=dp.get_precision('Account')),
2011-03-14 08:57:50 +00:00
' line_ids ' : fields . one2many ( ' hr.payslip.line ' , ' slip_id ' , ' Payslip Line ' , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2010-10-06 12:44:54 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' holiday_days ' : fields . float ( ' No of Leaves ' , readonly = True ) ,
' worked_days ' : fields . float ( ' Worked Day ' , readonly = True ) ,
' working_days ' : fields . float ( ' Working Days ' , readonly = True ) ,
2011-03-14 08:57:50 +00:00
' paid ' : fields . boolean ( ' Paid ? ' , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2010-06-06 16:29:11 +00:00
' note ' : fields . text ( ' Description ' ) ,
2011-03-14 08:57:50 +00:00
' contract_id ' : fields . many2one ( ' hr.contract ' , ' Contract ' , required = False , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2011-03-08 06:36:37 +00:00
' igross ' : fields . float ( ' Calculaton Field ' , readonly = True , digits = ( 16 , 2 ) , help = " Calculation field used for internal calculation, do not place this on form " ) ,
' inet ' : fields . float ( ' Calculaton Field ' , readonly = True , digits = ( 16 , 2 ) , help = " Calculation field used for internal calculation, do not place this on form " ) ,
2011-03-14 06:16:21 +00:00
' holiday_ids ' : fields . function ( _get_holidays , method = True , type = ' one2many ' , relation = ' hr.holidays ' , string = ' Holiday Lines ' , required = False ) ,
2010-06-06 16:29:11 +00:00
}
_defaults = {
' date ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
2011-03-14 08:57:50 +00:00
' state ' : ' draft ' ,
2010-06-06 16:29:11 +00:00
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
}
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
def copy ( self , cr , uid , id , default = None , context = None ) :
company_id = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context ) . company_id . id
default = {
' line_ids ' : False ,
' move_ids ' : False ,
' move_line_ids ' : False ,
' move_payment_ids ' : False ,
' company_id ' : company_id ,
' period_id ' : False ,
' basic_before_leaves ' : 0 ,
2011-03-09 06:11:11 +00:00
' basic_amount ' : 0
2010-06-06 16:29:11 +00:00
}
2011-03-14 11:22:27 +00:00
return super ( hr_payslip , self ) . copy ( cr , uid , id , default , context = context )
#
# def create_voucher(self, cr, uid, ids, name, voucher, sequence=5):
# slip_move = self.pool.get('hr.payslip.account.move')
# for slip in ids:
# res = {
# 'slip_id':slip,
# 'move_id':voucher,
# 'sequence':sequence,
# 'name':name
# }
# slip_move.create(cr, uid, res)
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def set_to_draft ( self , cr , uid , ids , context = None ) :
self . write ( cr , uid , ids , { ' state ' : ' draft ' } , context = context )
2010-06-06 16:29:11 +00:00
return True
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def cancel_sheet ( self , cr , uid , ids , context = None ) :
self . write ( cr , uid , ids , { ' state ' : ' cancel ' } , context = context )
2010-06-06 16:29:11 +00:00
return True
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def account_check_sheet ( self , cr , uid , ids , context = None ) :
self . write ( cr , uid , ids , { ' state ' : ' accont_check ' } , context = context )
2010-06-06 16:29:11 +00:00
return True
2010-07-01 07:31:46 +00:00
2010-07-27 07:11:45 +00:00
def hr_check_sheet ( self , cr , uid , ids , context = None ) :
self . write ( cr , uid , ids , { ' state ' : ' hr_check ' } , context = context )
2010-06-06 16:29:11 +00:00
return True
2010-07-27 07:11:45 +00:00
def process_sheet ( self , cr , uid , ids , context = None ) :
2010-10-06 12:44:54 +00:00
self . write ( cr , uid , ids , { ' paid ' : True , ' state ' : ' done ' } , context = context )
2010-07-02 10:37:15 +00:00
return True
2010-10-26 12:23:32 +00:00
2010-11-19 13:48:01 +00:00
def verify_sheet ( self , cr , uid , ids , context = None ) :
2010-10-06 12:44:54 +00:00
register_line_pool = self . pool . get ( ' hr.contibution.register.line ' )
2011-03-18 11:46:19 +00:00
line_tot = 0.0
2010-10-06 12:44:54 +00:00
for slip in self . browse ( cr , uid , ids , context = context ) :
base = {
2011-03-18 11:46:19 +00:00
' basic ' : slip . basic_amount ,
2010-10-06 12:44:54 +00:00
}
2011-03-18 11:46:19 +00:00
rules = slip . contract_id . struct_id . rule_ids
if rules :
for rl in rules :
if rl . company_contribution :
base [ rl . code . lower ( ) ] = rl . contribute_per
if rl . register_id :
for sl in slip . line_ids :
if sl . name == rl . name :
line_tot = sl . total
value = eval ( rl . computational_expression , base )
company_contrib = self . _compute ( cr , uid , rl . id , value , context )
reg_line = {
' name ' : rl . name ,
' register_id ' : rl . register_id . id ,
' code ' : rl . code ,
' employee_id ' : slip . employee_id . id ,
' emp_deduction ' : line_tot ,
' comp_deduction ' : company_contrib ,
' total ' : rl . contribute_per + line_tot
}
register_line_pool . create ( cr , uid , reg_line )
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , ids , { ' state ' : ' confirm ' } , context = context )
2010-06-06 16:29:11 +00:00
return True
2010-07-27 07:11:45 +00:00
def get_contract ( self , cr , uid , employee , date , context = None ) :
2011-02-25 13:43:14 +00:00
# sql_req= '''
# SELECT c.id as id, c.wage as wage, struct_id as function
# FROM hr_contract c
# LEFT JOIN hr_employee emp on (c.employee_id=emp.id)
# LEFT JOIN hr_contract_wage_type cwt on (cwt.id = c.wage_type_id)
# LEFT JOIN hr_contract_wage_type_period p on (cwt.period_id = p.id) #PSI@ improve as we need period but wage_type_id field removed
# WHERE
# (emp.id=%s) AND
# (date_start <= %s) AND
# (date_end IS NULL OR date_end >= %s)
# LIMIT 1
# '''
2010-06-18 00:51:41 +00:00
sql_req = '''
SELECT c . id as id , c . wage as wage , struct_id as function
FROM hr_contract c
LEFT JOIN hr_employee emp on ( c . employee_id = emp . id )
WHERE
( emp . id = % s ) AND
( date_start < = % s ) AND
( date_end IS NULL OR date_end > = % s )
LIMIT 1
'''
cr . execute ( sql_req , ( employee . id , date , date ) )
2010-07-01 07:31:46 +00:00
contract = cr . dictfetchone ( )
2011-03-11 12:23:26 +00:00
return contract and contract or { }
2010-07-01 07:31:46 +00:00
2011-03-11 12:23:26 +00:00
# def _get_leaves(self, cr, user, slip, employee, context=None):
# """
# Compute leaves for an employee
#
# @param cr: cursor to database
# @param user: id of current user
# @param slip: object of the hr.payroll.slip model
# @param employee: object of the hr.employee model
# @param context: context arguments, like lang, time zone
#
# @return: return a result
# """
# result = []
# dates = prev_bounds(slip.date)
# sql = '''select id from hr_holidays
# where date_from >= '%s' and date_to <= '%s'
# and employee_id = %s
# and state = 'validate' ''' % (dates[0], dates[1], slip.employee_id.id)
# cr.execute(sql)
# res = cr.fetchall()
# if res:
# result = [x[0] for x in res]
# return result
2011-02-25 13:43:14 +00:00
def _get_leaves1 ( self , cr , user , ddate , employee , context = None ) :
"""
Compute leaves for an employee
@param cr : cursor to database
@param user : id of current user
@param slip : object of the hr . payroll . slip model
@param employee : object of the hr . employee model
@param context : context arguments , like lang , time zone
2010-07-01 07:31:46 +00:00
2011-02-25 13:43:14 +00:00
@return : return a result
"""
result = [ ]
dates = prev_bounds ( ddate )
2011-03-14 06:16:21 +00:00
sql = ''' SELECT id FROM hr_holidays
WHERE date_from > = ' %s ' AND date_to < = ' %s '
AND employee_id = % s
AND state = ' validate ' ''' % (dates[0], dates[1], employee.id)
2011-02-25 13:43:14 +00:00
cr . execute ( sql )
res = cr . fetchall ( )
if res :
result = [ x [ 0 ] for x in res ]
2010-06-18 03:11:40 +00:00
return result
2010-07-01 07:31:46 +00:00
2011-03-02 09:34:07 +00:00
# def compute_sheet(self, cr, uid, ids, context=None):
# func_pool = self.pool.get('hr.payroll.structure')
# slip_line_pool = self.pool.get('hr.payslip.line')
# holiday_pool = self.pool.get('hr.holidays')
# sequence_obj = self.pool.get('ir.sequence')
# if context is None:
# context = {}
# date = self.read(cr, uid, ids, ['date'], context=context)[0]['date']
# #Check for the Holidays
# def get_days(start, end, month, year, calc_day):
# import datetime
# count = 0
# for day in range(start, end):
# if datetime.date(year, month, day).weekday() == calc_day:
# count += 1
# return count
#
# for slip in self.browse(cr, uid, ids, context=context):
# old_slip_ids = slip_line_pool.search(cr, uid, [('slip_id','=',slip.id)], context=context)
# slip_line_pool.unlink(cr, uid, old_slip_ids, context=context)
# update = {}
# ttyme = datetime.fromtimestamp(time.mktime(time.strptime(slip.date,"%Y-%m-%d")))
# contracts = self.get_contract(cr, uid, slip.employee_id, date, context)
# if contracts.get('id', False) == False:
# update.update({
# 'basic': round(0.0),
# 'basic_before_leaves': round(0.0),
# 'name':'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))),
# 'state':'draft',
# 'contract_id':False,
# 'company_id':slip.employee_id.company_id.id
# })
# self.write(cr, uid, [slip.id], update, context=context)
# continue
#
# contract = slip.employee_id.contract_id
## sal_type = contract.wage_type_id.type
# function = contract.struct_id.id
# lines = []
# if function:
# func = func_pool.read(cr, uid, function, ['line_ids'], context=context)
# lines = slip_line_pool.browse(cr, uid, func['line_ids'], context=context)
#
# #lines += slip.employee_id.line_ids
#
# ad = []
# all_per = 0.0
# ded_per = 0.0
# all_fix = 0.0
# ded_fix = 0.0
#
# obj = {'basic':0.0}
## if contract.wage_type_id.type == 'gross':
## obj['gross'] = contract.wage
## update['igross'] = contract.wage
## if contract.wage_type_id.type == 'net':
## obj['net'] = contract.wage
## update['inet'] = contract.wage
## if contract.wage_type_id.type == 'basic':
## obj['basic'] = contract.wage
## update['basic'] = contract.wage
#
# for line in lines:
# cd = line.code.lower()
# obj[cd] = line.amount or 0.0
#
# for line in lines:
# if line.category_id.code in ad:
# continue
# ad.append(line.category_id.code)
# cd = line.category_id.code.lower()
# calculate = False
# try:
# exp = line.category_id.condition
# calculate = eval(exp, obj)
# except Exception, e:
# raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
#
# if not calculate:
# continue
#
# percent = 0.0
# value = 0.0
# base = False
## company_contrib = 0.0
# base = line.category_id.base
#
# try:
# #Please have a look at the configuration guide.
# amt = eval(base, obj)
# except Exception, e:
# raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s ') % (e))
#
## if sal_type in ('gross', 'net'):
## if line.amount_type == 'per':
## percent = line.amount
## if amt > 1:
## value = percent * amt
## elif amt > 0 and amt <= 1:
## percent = percent * amt
## if value > 0:
## percent = 0.0
## elif line.amount_type == 'fix':
## value = line.amount
## elif line.amount_type == 'func':
## value = slip_line_pool.execute_function(cr, uid, line.id, amt, context)
## line.amount = value
## else:
# if line.amount_type in ('fix', 'per'):
# value = line.amount
# elif line.amount_type == 'func':
# value = slip_line_pool.execute_function(cr, uid, line.id, amt, context)
# line.amount = value
# if line.type == 'allowance':
# all_per += percent
# all_fix += value
# elif line.type == 'deduction':
# ded_per += percent
# ded_fix += value
# vals = {
# 'amount':line.amount,
# 'slip_id':slip.id,
# 'employee_id':False,
# 'function_id':False,
# 'base':base
# }
# slip_line_pool.copy(cr, uid, line.id, vals, {})
## if sal_type in ('gross', 'net'):
## sal = contract.wage
## if sal_type == 'net':
## sal += ded_fix
## sal -= all_fix
## per = 0.0
## if sal_type == 'net':
## per = (all_per - ded_per)
## else:
## per = all_per
## if per <=0:
## per *= -1
## final = (per * 100) + 100
## basic = (sal * 100) / final
## else:
# basic = contract.wage
#
# number = sequence_obj.get(cr, uid, 'salary.slip')
# update.update({
2011-03-03 12:49:03 +00:00
# 'struct_id':function,
2011-03-02 09:34:07 +00:00
# 'number':number,
# 'basic': round(basic),
# 'basic_before_leaves': round(basic),
# 'name':'Salary Slip of %s for %s' % (slip.employee_id.name, tools.ustr(ttyme.strftime('%B-%Y'))),
# 'state':'draft',
# 'contract_id':contract.id,
# 'company_id':slip.employee_id.company_id.id
# })
#
# for line in slip.employee_id.line_ids:
# vals = {
# 'amount':line.amount,
# 'slip_id':slip.id,
# 'employee_id':False,
# 'function_id':False,
# 'base':base
# }
# slip_line_pool.copy(cr, uid, line.id, vals, {})
#
# self.write(cr, uid, [slip.id], update, context=context)
#
# for slip in self.browse(cr, uid, ids, context=context):
# if not slip.contract_id:
# continue
#
# basic_before_leaves = slip.basic
# working_day = 0
# off_days = 0
# dates = prev_bounds(slip.date)
#
# days_arr = [0, 1, 2, 3, 4, 5, 6]
# for dy in range(slip.employee_id.contract_id.working_days_per_week, 7):
# off_days += get_days(1, dates[1].day, dates[1].month, dates[1].year, days_arr[dy])
# total_off = off_days
# working_day = dates[1].day - total_off
# perday = slip.basic / working_day
# total = 0.0
# leave = 0.0
# leave_ids = self._get_leaves(cr, uid, slip, slip.employee_id, context)
# total_leave = 0.0
# paid_leave = 0.0
# h_ids = holiday_pool.browse(cr, uid, leave_ids, context=context)
# for hday in holiday_pool.browse(cr, uid, leave_ids, context=context):
# if not hday.holiday_status_id.head_id:
# raise osv.except_osv(_('Error !'), _('Please check configuration of %s, payroll head is missing') % (hday.holiday_status_id.name))
#
# res = {
# 'slip_id':slip.id,
# 'name':hday.holiday_status_id.name + '-%s' % (hday.number_of_days),
# 'code':hday.holiday_status_id.code,
# 'amount_type':'fix',
# 'category_id':hday.holiday_status_id.head_id.id,
# 'sequence':hday.holiday_status_id.head_id.sequence
# }
# days = hday.number_of_days
# if hday.number_of_days < 0:
# days = hday.number_of_days * -1
# total_leave += days
# if hday.holiday_status_id.type == 'paid':
# paid_leave += days
# continue
## res['name'] = hday.holiday_status_id.name + '-%s' % (days)
## res['amount'] = perday * days
## res['type'] = 'allowance'
## leave += days
## total += perday * days
#
# elif hday.holiday_status_id.type == 'halfpaid':
# paid_leave += (days / 2)
# res['name'] = hday.holiday_status_id.name + '-%s/2' % (days)
# res['amount'] = perday * (days/2)
# total += perday * (days/2)
# leave += days / 2
# res['type'] = 'deduction'
2011-02-25 13:43:14 +00:00
# else:
2010-10-06 12:44:54 +00:00
# res['name'] = hday.holiday_status_id.name + '-%s' % (days)
# res['amount'] = perday * days
2011-03-02 09:34:07 +00:00
# res['type'] = 'deduction'
2010-10-06 12:44:54 +00:00
# leave += days
# total += perday * days
2011-03-02 09:34:07 +00:00
#
# slip_line_pool.create(cr, uid, res, context=context)
# holiday_pool.write(cr, uid, leave_ids, {'payslip_id': slip.id}, context=context)
# basic = basic - total
## leaves = total
# update.update({
# 'basic':basic,
# 'basic_before_leaves': round(basic_before_leaves),
# 'leaves':total,
# 'holiday_days':leave,
# 'worked_days':working_day - leave,
# 'working_days':working_day,
# })
# self.write(cr, uid, [slip.id], update, context=context)
# return True
2011-02-25 13:43:14 +00:00
2011-03-11 11:41:55 +00:00
def _get_parent_structure ( self , cr , uid , struct_id , context = None ) :
2011-03-14 11:22:27 +00:00
if not struct_id :
return [ ]
2011-03-11 11:41:55 +00:00
parent = [ ]
for line in self . pool . get ( ' hr.payroll.structure ' ) . browse ( cr , uid , struct_id ) :
if line . parent_id :
parent . append ( line . parent_id . id )
if parent :
parent = self . _get_parent_structure ( cr , uid , parent , context )
return struct_id + parent
2011-03-14 05:00:10 +00:00
2011-03-14 11:22:27 +00:00
def onchange_employee_id ( self , cr , uid , ids , ddate , employee_id = False , context = None ) :
2011-02-25 13:43:14 +00:00
func_pool = self . pool . get ( ' hr.payroll.structure ' )
slip_line_pool = self . pool . get ( ' hr.payslip.line ' )
2011-03-04 09:44:14 +00:00
salary_rule_pool = self . pool . get ( ' hr.salary.rule ' )
2011-02-25 13:43:14 +00:00
holiday_pool = self . pool . get ( ' hr.holidays ' )
sequence_obj = self . pool . get ( ' ir.sequence ' )
empolyee_obj = self . pool . get ( ' hr.employee ' )
2011-03-03 12:49:03 +00:00
resource_attendance_pool = self . pool . get ( ' resource.calendar.attendance ' )
2011-03-14 11:22:27 +00:00
2011-02-25 13:43:14 +00:00
if context is None :
context = { }
old_slip_ids = ids and slip_line_pool . search ( cr , uid , [ ( ' slip_id ' , ' = ' , ids [ 0 ] ) ] , context = context ) or False
if old_slip_ids :
slip_line_pool . unlink ( cr , uid , old_slip_ids )
2011-03-09 06:11:11 +00:00
update = { ' value ' : { ' line_ids ' : [ ] , ' holiday_ids ' : [ ] , ' name ' : ' ' , ' working_days ' : 0.0 , ' holiday_days ' : 0.0 , ' worked_days ' : 0.0 , ' basic_before_leaves ' : 0.0 , ' basic_amount ' : 0.0 , ' leaves ' : 0.0 , ' total_pay ' : 0.0 } }
2011-02-25 13:43:14 +00:00
if not employee_id :
return update
2011-03-14 11:22:27 +00:00
# if not employee_id and ids:
# old_slip_ids = salary_rule_pool.search(cr, uid, [('slip_id', '=', ids[0])], context=context)
# if old_slip_ids:
# line_pool.unlink(cr, uid, old_slip_ids)
# return update
2011-02-25 13:43:14 +00:00
#Check for the Holidays
def get_days ( start , end , month , year , calc_day ) :
import datetime
count = 0
2011-03-03 12:49:03 +00:00
for day in range ( start , end + 1 ) :
2011-02-25 13:43:14 +00:00
if datetime . date ( year , month , day ) . weekday ( ) == calc_day :
count + = 1
return count
employee_id = empolyee_obj . browse ( cr , uid , employee_id , context = context )
ttyme = datetime . fromtimestamp ( time . mktime ( time . strptime ( ddate , " % Y- % m- %d " ) ) )
2011-03-14 11:22:27 +00:00
contracts = self . get_contract ( cr , uid , employee_id , ddate , context = context )
if not contracts . get ( ' id ' , False ) :
2011-02-25 13:43:14 +00:00
update [ ' value ' ] . update ( {
2011-03-09 06:11:11 +00:00
' basic_amount ' : round ( 0.0 ) ,
2011-02-25 13:43:14 +00:00
' basic_before_leaves ' : round ( 0.0 ) ,
' name ' : ' Salary Slip of %s for %s ' % ( employee_id . name , tools . ustr ( ttyme . strftime ( ' % B- % Y ' ) ) ) ,
' contract_id ' : False ,
' company_id ' : employee_id . company_id . id
} )
2011-03-02 09:34:07 +00:00
return update
2011-02-25 13:43:14 +00:00
contract = employee_id . contract_id
2011-03-11 10:12:20 +00:00
2011-03-11 08:57:40 +00:00
sal_structure = [ ]
2011-02-25 13:43:14 +00:00
function = contract . struct_id . id
2011-03-11 11:41:55 +00:00
if function :
sal_structure = self . _get_parent_structure ( cr , uid , [ function ] , context = context )
2011-03-14 05:00:10 +00:00
2011-02-25 13:43:14 +00:00
lines = [ ]
2011-03-11 08:57:40 +00:00
rules = [ ]
2011-03-14 07:23:17 +00:00
for struct in sal_structure :
lines = func_pool . browse ( cr , uid , struct , context = context ) . rule_ids
for rl in lines :
2011-03-15 13:33:22 +00:00
if rl . child_ids :
for r in rl . child_ids :
lines . append ( r )
2011-03-14 07:23:17 +00:00
rules . append ( rl )
2011-02-25 13:43:14 +00:00
ad = [ ]
2011-03-07 09:26:49 +00:00
total = 0.0
2011-03-14 11:22:27 +00:00
obj = { ' basic ' : contract . wage }
2011-03-11 08:57:40 +00:00
for line in rules :
2011-02-25 13:43:14 +00:00
cd = line . code . lower ( )
obj [ cd ] = line . amount or 0.0
2011-03-11 08:57:40 +00:00
for line in rules :
2011-02-25 13:43:14 +00:00
if line . category_id . code in ad :
continue
ad . append ( line . category_id . code )
cd = line . category_id . code . lower ( )
calculate = False
try :
2011-03-04 09:44:14 +00:00
exp = line . conditions
2011-02-25 13:43:14 +00:00
calculate = eval ( exp , obj )
except Exception , e :
raise osv . except_osv ( _ ( ' Variable Error ! ' ) , _ ( ' Variable Error: %s ' ) % ( e ) )
if not calculate :
continue
value = 0.0
base = False
# company_contrib = 0.0
2011-03-04 09:44:14 +00:00
base = line . computational_expression
2011-02-25 13:43:14 +00:00
try :
#Please have a look at the configuration guide.
amt = eval ( base , obj )
except Exception , e :
raise osv . except_osv ( _ ( ' Variable Error ! ' ) , _ ( ' Variable Error: %s ' ) % ( e ) )
if line . amount_type == ' per ' :
try :
2011-03-17 13:29:13 +00:00
if line . child_depend == False :
if line . parent_rule_id :
for rul in [ line . parent_rule_id ] :
val = rul . amount * amt
amt = val
value = line . amount * amt
if line . condition_range_min or line . condition_range_max :
if ( ( value < line . condition_range_min ) or ( value > line . condition_range_max ) ) :
value = 0.0
else :
value = value
2011-03-10 06:53:26 +00:00
else :
2011-03-14 09:44:29 +00:00
value = value
2011-02-25 13:43:14 +00:00
except Exception , e :
raise osv . except_osv ( _ ( ' Variable Error ! ' ) , _ ( ' Variable Error: %s ' ) % ( e ) )
2011-03-21 09:35:39 +00:00
2011-02-25 13:43:14 +00:00
elif line . amount_type == ' fix ' :
2011-03-17 13:29:13 +00:00
if line . child_depend == False :
if line . parent_rule_id :
2011-03-15 13:33:22 +00:00
for rul in [ line . parent_rule_id ] :
value = value
2011-03-17 13:29:13 +00:00
if line . condition_range_min or line . condition_range_max :
if ( ( line . amount < line . condition_range_min ) or ( line . amount > line . condition_range_max ) ) :
value = value
else :
value = line . amount
2011-03-10 06:53:26 +00:00
else :
value = line . amount
2011-03-22 13:37:13 +00:00
2011-03-14 13:34:28 +00:00
elif line . amount_type == ' code ' :
2011-03-17 11:35:35 +00:00
localdict = { ' basic ' : amt , ' employee ' : employee_id , ' contract ' : contract }
exec line . python_compute in localdict
2011-03-22 13:37:13 +00:00
val = localdict [ ' result ' ]
if line . child_depend == False :
if line . parent_rule_id :
for rul in [ line . parent_rule_id ] :
value = val
if line . condition_range_min or line . condition_range_max :
if ( ( line . amount < line . condition_range_min ) or ( line . amount > line . condition_range_max ) ) :
value = value
else :
value = val
else :
value = val
2011-03-07 09:26:49 +00:00
total + = value
2011-02-25 13:43:14 +00:00
vals = {
' category_id ' : line . category_id . id ,
' name ' : line . name ,
' sequence ' : line . sequence ,
2011-03-04 09:44:14 +00:00
' type ' : line . type . id ,
2011-02-25 13:43:14 +00:00
' code ' : line . code ,
' amount_type ' : line . amount_type ,
2011-03-04 09:44:14 +00:00
' amount ' : line . amount ,
2011-02-25 13:43:14 +00:00
' total ' : value ,
2011-03-10 11:55:25 +00:00
' employee_id ' : employee_id . id ,
2011-03-09 06:11:11 +00:00
# 'function_id': False,
2011-03-07 09:26:49 +00:00
' base ' : line . computational_expression
2011-02-25 13:43:14 +00:00
}
2011-03-17 13:29:13 +00:00
if line . appears_on_payslip :
if line . parent_rule_id :
for l in salary_rule_pool . browse ( cr , uid , [ line . parent_rule_id . id ] , context = context ) :
if l . display_child_rules == True :
update [ ' value ' ] [ ' line_ids ' ] . append ( vals )
2011-03-10 06:53:26 +00:00
else :
2011-03-17 13:29:13 +00:00
if line . condition_range_min or line . condition_range_max :
if not ( ( value < line . condition_range_min ) or ( value > line . condition_range_max ) ) :
update [ ' value ' ] [ ' line_ids ' ] . append ( vals )
else :
update [ ' value ' ] [ ' line_ids ' ] . append ( vals )
2011-03-21 09:35:39 +00:00
2011-02-25 13:43:14 +00:00
basic = contract . wage
number = sequence_obj . get ( cr , uid , ' salary.slip ' )
update [ ' value ' ] . update ( {
2011-03-07 09:26:49 +00:00
' struct_id ' : function ,
' number ' : number ,
2011-03-09 06:11:11 +00:00
' basic_amount ' : round ( basic ) ,
2011-02-25 13:43:14 +00:00
' basic_before_leaves ' : round ( basic ) ,
2011-03-07 09:26:49 +00:00
' total_pay ' : round ( basic ) + total ,
2011-02-25 13:43:14 +00:00
' name ' : ' Salary Slip of %s for %s ' % ( employee_id . name , tools . ustr ( ttyme . strftime ( ' % B- % Y ' ) ) ) ,
2011-03-07 09:26:49 +00:00
' contract_id ' : contract . id ,
' company_id ' : employee_id . company_id . id
2011-02-25 13:43:14 +00:00
} )
2011-03-10 11:55:25 +00:00
# for line in employee_id.line_ids:
# vals = {
# 'category_id': line.category_id.id,
# 'name': line.name,
# 'sequence': line.sequence,
# 'type': line.type.id,
# 'code': line.code,
# 'amount_type': line.amount_type,
# 'amount': line.amount,
# 'employee_id': employee_id.id,
## 'function_id': False,
# 'base': base
# }
# update['value']['line_ids'].append(vals)
2011-02-25 13:43:14 +00:00
2011-03-09 06:11:11 +00:00
basic_before_leaves = update [ ' value ' ] [ ' basic_amount ' ]
2011-03-09 13:30:27 +00:00
total_before_leaves = update [ ' value ' ] [ ' total_pay ' ]
2011-02-25 13:43:14 +00:00
working_day = 0
off_days = 0
dates = prev_bounds ( ddate )
2011-03-03 12:49:03 +00:00
calendar_id = employee_id . contract_id . working_hours . id
if not calendar_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( " Please define working schedule on %s ' s contract " ) % ( employee_id . name ) )
week_days = { " 0 " : " mon " , " 1 " : " tue " , " 2 " : " wed " , " 3 " : " thu " , " 4 " : " fri " , " 5 " : " sat " , " 6 " : " sun " }
wk_days = { }
week_ids = resource_attendance_pool . search ( cr , uid , [ ( ' calendar_id ' , ' = ' , calendar_id ) ] , context = context )
weeks = resource_attendance_pool . read ( cr , uid , week_ids , [ ' dayofweek ' ] , context = context )
for week in weeks :
if week_days . has_key ( week [ ' dayofweek ' ] ) :
wk_days [ week [ ' dayofweek ' ] ] = week_days [ week [ ' dayofweek ' ] ]
2011-02-25 13:43:14 +00:00
days_arr = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ]
2011-03-03 12:49:03 +00:00
for dy in range ( len ( wk_days ) , 7 ) :
2011-02-25 13:43:14 +00:00
off_days + = get_days ( 1 , dates [ 1 ] . day , dates [ 1 ] . month , dates [ 1 ] . year , days_arr [ dy ] )
total_off = off_days
working_day = dates [ 1 ] . day - total_off
2011-03-03 12:49:03 +00:00
perday = working_day and basic / working_day or 0.0
2011-02-25 13:43:14 +00:00
total = 0.0
leave = 0.0
leave_ids = self . _get_leaves1 ( cr , uid , ddate , employee_id , context )
total_leave = 0.0
paid_leave = 0.0
2011-03-11 10:12:20 +00:00
2011-02-25 13:43:14 +00:00
for hday in holiday_pool . browse ( cr , uid , leave_ids , context = context ) :
2011-03-07 13:13:29 +00:00
# if not hday.holiday_status_id.code:
2011-03-11 10:12:20 +00:00
# raise osv.except_osv(_('Error !'), _('Please check configuration of %s, code is missing') % (hday.holiday_status_id.name))
2011-03-09 13:30:27 +00:00
slip_lines = salary_rule_pool . search ( cr , uid , [ ( ' code ' , ' = ' , hday . holiday_status_id . code ) ] , context = context )
2011-03-02 09:34:07 +00:00
head_sequence = 0
2011-03-09 13:30:27 +00:00
if not slip_lines :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' Please check configuration of %s , Salary rule is missing ' ) % ( hday . holiday_status_id . name ) )
2011-03-22 13:37:13 +00:00
hd_rule = salary_rule_pool . browse ( cr , uid , slip_lines , context = context ) [ 0 ]
leave_rule = [ ]
leave_rule . append ( hd_rule )
if hd_rule . child_ids :
leave_rule . append ( ( hd_rule . child_ids [ 0 ] ) )
for salary_rule in leave_rule :
base = salary_rule . computational_expression
res = {
' name ' : salary_rule . name + ' - %s ' % ( hday . number_of_days ) ,
' code ' : salary_rule . code ,
' amount_type ' : salary_rule . amount_type ,
' category_id ' : salary_rule . category_id . id ,
' sequence ' : salary_rule . sequence ,
' employee_id ' : employee_id . id ,
' base ' : base
}
days = hday . number_of_days
if hday . number_of_days < 0 :
days = hday . number_of_days * - 1
total_leave + = days
2011-03-09 13:30:27 +00:00
try :
2011-03-22 13:37:13 +00:00
#Please have a look at the configuration guide.
amt = eval ( base , obj )
2011-03-09 13:30:27 +00:00
except Exception , e :
raise osv . except_osv ( _ ( ' Variable Error ! ' ) , _ ( ' Variable Error: %s ' ) % ( e ) )
2011-03-22 13:37:13 +00:00
if salary_rule . amount_type == ' per ' :
try :
if salary_rule . child_depend == False :
if salary_rule . parent_rule_id :
for rul in [ line . parent_rule_id ] :
val = rul . amount * amt
amt = val
value = salary_rule . amount * amt * days
if salary_rule . condition_range_min or salary_rule . condition_range_max :
if ( ( value < salary_rule . condition_range_min ) or ( value > salary_rule . condition_range_max ) ) :
value = 0.0
else :
value = value
else :
value = value
except Exception , e :
raise osv . except_osv ( _ ( ' Variable Error ! ' ) , _ ( ' Variable Error: %s ' ) % ( e ) )
elif salary_rule . amount_type == ' fix ' :
if salary_rule . child_depend == False :
if salary_rule . parent_rule_id :
for rul in [ salary_rule . parent_rule_id ] :
value = salary_rule . amount * days
if salary_rule . condition_range_min or salary_rule . condition_range_max :
if ( ( salary_rule . amount < salary_rule . condition_range_min ) or ( salary_rule . amount > salary_rule . condition_range_max ) ) :
value = 0.0
else :
value = salary_rule . amount * days
else :
value = salary_rule . amount * days
# value = salary_rule.amount * days
elif salary_rule . amount_type == ' code ' :
localdict = { ' basic ' : amt , ' employee ' : employee_id , ' contract ' : contract }
exec salary_rule . python_compute in localdict
val = localdict [ ' result ' ] * days
if salary_rule . child_depend == False :
if salary_rule . parent_rule_id :
for rul in [ salary_rule . parent_rule_id ] :
value = val
if salary_rule . condition_range_min or salary_rule . condition_range_max :
if ( ( salary_rule . amount < salary_rule . condition_range_min ) or ( salary_rule . amount > salary_rule . condition_range_max ) ) :
value = value
else :
value = val
else :
value = val
res [ ' amount ' ] = salary_rule . amount
res [ ' type ' ] = salary_rule . type . id
leave + = days
total = value
res [ ' total ' ] = value
# update['value']['line_ids'].append(res)
if salary_rule . appears_on_payslip :
if salary_rule . parent_rule_id :
for l in salary_rule_pool . browse ( cr , uid , [ salary_rule . parent_rule_id . id ] , context = context ) :
if l . display_child_rules == True :
update [ ' value ' ] [ ' line_ids ' ] . append ( res )
else :
if salary_rule . condition_range_min or salary_rule . condition_range_max :
if not ( ( value < salary_rule . condition_range_min ) or ( value > salary_rule . condition_range_max ) ) :
update [ ' value ' ] [ ' line_ids ' ] . append ( res )
else :
update [ ' value ' ] [ ' line_ids ' ] . append ( res )
2011-02-25 13:43:14 +00:00
update [ ' value ' ] . update ( {
2011-03-09 06:11:11 +00:00
' basic_amount ' : basic ,
2011-02-25 13:43:14 +00:00
' basic_before_leaves ' : round ( basic_before_leaves ) ,
2011-03-09 13:30:27 +00:00
' total_pay ' : total_before_leaves + total ,
2011-02-28 12:10:15 +00:00
' leaves ' : total ,
' holiday_days ' : leave ,
' worked_days ' : working_day - leave ,
' working_days ' : working_day ,
2011-02-25 13:43:14 +00:00
} )
return update
2010-06-06 16:29:11 +00:00
hr_payslip ( )
2011-02-25 13:43:14 +00:00
class hr_holidays ( osv . osv ) :
_inherit = " hr.holidays "
_columns = {
2011-03-14 11:22:27 +00:00
' payslip_id ' : fields . many2one ( ' hr.payslip ' , ' Payslip ' ) ,
2011-02-25 13:43:14 +00:00
}
hr_holidays ( )
2010-06-06 16:29:11 +00:00
class hr_payslip_line ( osv . osv ) :
'''
Payslip Line
'''
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_name = ' hr.payslip.line '
_description = ' Payslip Line '
2010-07-01 07:31:46 +00:00
2011-03-14 11:22:27 +00:00
def onchange_category ( self , cr , uid , ids , category_id = False ) :
if not category_id :
return { }
2011-02-28 12:10:15 +00:00
res = { }
2011-03-14 11:22:27 +00:00
category = self . pool . get ( ' hr.salary.head ' ) . browse ( cr , uid , category_id )
res . update ( {
' name ' : category . name ,
' code ' : category . code ,
' type ' : category . type . id
} )
return { ' value ' : res }
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
def onchange_amount ( self , cr , uid , ids , amount , typ ) :
if typ and typ == ' per ' :
2011-03-14 11:22:27 +00:00
if int ( amount ) > 0 :
amount = amount / 100
return { ' value ' : { ' amount ' : amount } }
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
_columns = {
2011-03-09 06:11:11 +00:00
' slip_id ' : fields . many2one ( ' hr.payslip ' , ' Pay Slip ' , required = False ) , #FIXME: required = TRUE.We cannot make it to True because while creating salary rule(which is inherited from hr.payslip.line),we cannot have slip_id.
# 'function_id':fields.many2one('hr.payroll.structure', 'Function', required=False),#FIXME: function?should be struct_id or payroll_structure_id..We have rule_ids(many2many) on hr.payroll.structure,so this field is not required here.
' employee_id ' : fields . many2one ( ' hr.employee ' , ' Employee ' , required = False ) , #FIXME: required = TRUE.We cannot make it to True because while creating salary rule(which is inherited from hr.payslip.line),we cannot have employee_id.
2010-06-06 16:29:11 +00:00
' name ' : fields . char ( ' Name ' , size = 256 , required = True , readonly = False ) ,
' base ' : fields . char ( ' Formula ' , size = 1024 , required = False , readonly = False ) ,
2010-10-26 12:23:32 +00:00
' code ' : fields . char ( ' Code ' , size = 64 , required = False , readonly = False ) ,
2011-03-03 09:52:26 +00:00
' category_id ' : fields . many2one ( ' hr.salary.head ' , ' Category ' , required = True ) ,
2011-03-07 07:18:29 +00:00
' type ' : fields . many2one ( ' hr.salary.head.type ' , ' Type ' , required = True , help = " Used for the reporting purpose. " ) ,
2010-06-06 16:29:11 +00:00
' amount_type ' : fields . selection ( [
( ' per ' , ' Percentage ( % ) ' ) ,
( ' fix ' , ' Fixed Amount ' ) ,
2011-03-01 11:29:08 +00:00
( ' code ' , ' Python Code ' ) ,
2011-03-17 11:35:35 +00:00
] , ' Amount Type ' , select = True , required = True , help = " The computation method for the rule amount. " ) ,
' amount ' : fields . float ( ' Amount / Percentage ' , digits_compute = dp . get_precision ( ' Account ' ) , help = " For rule of type percentage, enter % r atio between 0-1. " ) ,
2011-03-10 11:55:25 +00:00
' total ' : fields . float ( ' Sub Total ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2011-03-17 11:35:35 +00:00
' company_contrib ' : fields . float ( ' Company Contribution ' , readonly = True , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2010-06-06 16:29:11 +00:00
' sequence ' : fields . integer ( ' Sequence ' ) ,
' note ' : fields . text ( ' Description ' ) ,
}
_order = ' sequence '
2010-10-07 06:31:56 +00:00
_defaults = {
2011-03-17 11:35:35 +00:00
' amount_type ' : ' per ' ,
' amount ' : 0.0 ,
2010-10-07 06:31:56 +00:00
}
2010-07-01 07:31:46 +00:00
2010-06-06 16:29:11 +00:00
hr_payslip_line ( )
2010-07-01 07:31:46 +00:00
2011-02-24 13:12:20 +00:00
class hr_salary_rule ( osv . osv ) :
2010-07-01 07:31:46 +00:00
2011-02-24 13:12:20 +00:00
_inherit = ' hr.payslip.line '
_name = ' hr.salary.rule '
_columns = {
2011-03-02 10:17:36 +00:00
' appears_on_payslip ' : fields . boolean ( ' Appears on Payslip ' , help = " Used for the display of rule on payslip " ) ,
2011-03-03 09:52:26 +00:00
' condition_range_min ' : fields . float ( ' Minimum Range ' , required = False , help = " The minimum amount, applied for this rule. " ) ,
' condition_range_max ' : fields . float ( ' Maximum Range ' , required = False , help = " The maximum amount, applied for this rule. " ) ,
2011-03-15 13:33:22 +00:00
' parent_rule_id ' : fields . many2one ( ' hr.salary.rule ' , ' Parent Salary Rule ' , select = True ) ,
2011-02-25 13:35:52 +00:00
' child_depend ' : fields . boolean ( ' Children Rule ' ) ,
2011-03-15 13:33:22 +00:00
' child_ids ' : fields . one2many ( ' hr.salary.rule ' , ' parent_rule_id ' , ' Child Salary Rule ' ) ,
2011-03-01 09:59:10 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = False ) ,
2011-03-03 12:44:06 +00:00
' register_id ' : fields . property (
' hr.contibution.register ' ,
type = ' many2one ' ,
relation = ' hr.contibution.register ' ,
string = " Contribution Register " ,
method = True ,
view_load = True ,
help = " Contribution register based on company " ,
required = False
) ,
' gratuity ' : fields . boolean ( ' Use for Gratuity ? ' , required = False ) ,
2011-03-03 09:52:26 +00:00
' computational_expression ' : fields . text ( ' Computational Expression ' , required = True , readonly = False , help = ' This will use to computer the % f ields values, in general its on basic, but You can use all heads code field in small letter as a variable name i.e. hra, ma, lta, etc...., also you can use, static varible basic ' ) ,
' conditions ' : fields . char ( ' Condition ' , size = 1024 , required = True , readonly = False , help = ' Applied this head for calculation if condition is true ' ) ,
' sequence ' : fields . integer ( ' Sequence ' , required = True , help = ' Use to arrange calculation sequence ' ) ,
2011-03-14 11:22:27 +00:00
' active ' : fields . boolean ( ' Active ' ) ,
2011-03-14 13:34:28 +00:00
' python_compute ' : fields . text ( ' Python Code ' ) ,
2011-03-17 13:29:13 +00:00
' display_child_rules ' : fields . boolean ( ' Display Child Rules ' , help = " Used for the display of Child Rules on payslip " ) ,
2011-03-18 11:46:19 +00:00
' amt_type ' : fields . selection ( [
( ' per ' , ' Percentage ( % ) ' ) ,
( ' fix ' , ' Fixed Amount ' ) ,
] , ' Company Amount Type ' , select = True ) ,
' contribute_per ' : fields . float ( ' Company Contribution ' , digits = ( 16 , 4 ) , help = ' Define Company contribution ratio 1.00=100 % c ontribution. ' ) ,
' company_contribution ' : fields . boolean ( ' Company Contribution ' , help = " This rule has Company Contributions. " ) ,
2011-02-24 13:12:20 +00:00
}
_defaults = {
2011-03-17 11:35:35 +00:00
' python_compute ' : ''' # basic \n # employee: hr.employee object or None \n # contract: hr.contract object or None \n \n result = basic * 0.10 ''' ,
2011-03-03 12:44:06 +00:00
' conditions ' : ' True ' ,
' computational_expression ' : ' basic ' ,
' sequence ' : 5 ,
' appears_on_payslip ' : True ,
' active ' : True ,
2011-03-07 09:47:10 +00:00
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
2011-02-24 13:12:20 +00:00
}
2010-06-06 16:29:11 +00:00
2011-03-08 06:36:37 +00:00
# def _execute_function(self, cr, uid, id, value, context=None):
# """
# self: pointer to self object
# cr: cursor to database
# uid: user id of current executer
# """
# line_pool = self.pool.get('company.contribution.line')
# res = 0
# ids = line_pool.search(cr, uid, [('category_id','=',id), ('to_val','>=',value),('from_val','<=',value)], context=context)
# if not ids:
# ids = line_pool.search(cr, uid, [('category_id','=',id), ('from','<=',value)], context=context)
# if not ids:
# res = 0
# else:
# res = line_pool.browse(cr, uid, ids, context=context)[0].value
# return res
#
# def compute(self, cr, uid, id, value, context=None):
# contrib = self.browse(cr, uid, id, context=context)
# if contrib.amount_type == 'fix':
# return contrib.contribute_per
# elif contrib.amount_type == 'per':
# return value * contrib.contribute_per
# elif contrib.amount_type == 'func':
# return self._execute_function(cr, uid, id, value, context)
# return 0.0
#
2011-02-24 13:12:20 +00:00
hr_salary_rule ( )
2010-10-26 12:23:32 +00:00
2011-02-24 13:12:20 +00:00
class hr_payroll_structure ( osv . osv ) :
_inherit = ' hr.payroll.structure '
2010-06-06 16:29:11 +00:00
_columns = {
2011-03-14 11:22:27 +00:00
' rule_ids ' : fields . many2many ( ' hr.salary.rule ' , ' hr_structure_salary_rule_rel ' , ' struct_id ' , ' rule_id ' , ' Salary Rules ' ) ,
2010-06-06 16:29:11 +00:00
}
2011-02-24 13:12:20 +00:00
hr_payroll_structure ( )
2010-06-06 16:29:11 +00:00
class hr_employee ( osv . osv ) :
'''
Employee
'''
2010-10-26 12:23:32 +00:00
2011-03-14 08:58:54 +00:00
_inherit = ' hr.employee '
_description = ' Employee '
2011-03-09 10:10:41 +00:00
def _calculate_basic ( self , cr , uid , ids , name , args , context ) :
if not ids : return { }
2011-03-14 08:58:54 +00:00
res = { }
2011-03-09 10:10:41 +00:00
current_date = datetime . now ( ) . strftime ( ' % Y- % m- %d ' )
for employee in self . browse ( cr , uid , ids , context = context ) :
2011-03-14 08:58:54 +00:00
if not employee . contract_ids :
res [ employee . id ] = { ' basic ' : 0.0 }
2011-03-09 10:10:41 +00:00
continue
cr . execute ( ' SELECT SUM(wage) ' \
' FROM hr_contract ' \
' WHERE employee_id = %s ' \
' AND date_start < %s ' \
' AND (date_end > %s OR date_end is NULL) ' ,
( employee . id , current_date , current_date ) )
result = dict ( cr . dictfetchone ( ) )
2011-03-14 08:58:54 +00:00
res [ employee . id ] = { ' basic ' : result [ ' sum ' ] }
return res
2010-10-26 12:23:32 +00:00
2010-06-06 16:29:11 +00:00
_columns = {
2011-03-14 08:45:55 +00:00
# 'line_ids':fields.one2many('hr.payslip.line', 'employee_id', 'Salary Structure', required=False),
2010-06-06 16:29:11 +00:00
' slip_ids ' : fields . one2many ( ' hr.payslip ' , ' employee_id ' , ' Payslips ' , required = False , readonly = True ) ,
2011-03-09 10:10:41 +00:00
' basic ' : fields . function ( _calculate_basic , method = True , multi = ' dc ' , type = ' float ' , string = ' Basic Salary ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2010-06-06 16:29:11 +00:00
}
2011-03-14 08:58:54 +00:00
2010-06-06 16:29:11 +00:00
hr_employee ( )
2011-03-14 08:58:54 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: