2018-01-16 06:58:15 +01:00
# -*- coding:utf-8 -*-
2018-01-16 11:34:37 +01:00
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
2018-01-16 06:58:15 +01:00
2018-01-16 11:34:37 +01:00
from flectra import api , fields , models , _
from flectra . addons import decimal_precision as dp
from flectra . exceptions import UserError
2018-01-16 06:58:15 +01:00
class HrContract ( models . Model ) :
"""
Employee contract allows to add different values in fields .
Fields are used in salary rule computation .
"""
_inherit = ' hr.contract '
tds = fields . Float ( string = ' TDS ' , digits = dp . get_precision ( ' Payroll ' ) ,
help = ' Amount for Tax Deduction at Source ' )
driver_salay = fields . Boolean ( string = ' Driver Salary ' , help = ' Check this box if you provide allowance for driver ' )
medical_insurance = fields . Float ( string = ' Medical Insurance ' , digits = dp . get_precision ( ' Payroll ' ) ,
help = ' Deduction towards company provided medical insurance ' )
voluntary_provident_fund = fields . Float ( string = ' Voluntary Provident Fund ( % ) ' , digits = dp . get_precision ( ' Payroll ' ) ,
help = ' VPF is a safe option wherein you can contribute more than the PF ceiling of 12 % that has been mandated by the government and VPF computed as percentage( % ) ' )
house_rent_allowance_metro_nonmetro = fields . Float ( string = ' House Rent Allowance ( % ) ' , digits = dp . get_precision ( ' Payroll ' ) ,
help = ' HRA is an allowance given by the employer to the employee for taking care of his rental or accommodation expenses for metro city it is 50 % a nd for non metro 40 % . \n HRA computed as percentage( % ) ' )
supplementary_allowance = fields . Float ( string = ' Supplementary Allowance ' , digits = dp . get_precision ( ' Payroll ' ) )
class HrPayrollAdvice ( models . Model ) :
'''
Bank Advice
'''
_name = ' hr.payroll.advice '
def _get_default_date ( self ) :
return fields . Date . from_string ( fields . Date . today ( ) )
name = fields . Char ( readonly = True , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } )
note = fields . Text ( string = ' Description ' , default = ' Please make the payroll transfer from above account number to the below mentioned account numbers towards employee salaries: ' )
date = fields . Date ( readonly = True , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , default = _get_default_date ,
help = ' Advice Date is used to search Payslips ' )
state = fields . Selection ( [
( ' draft ' , ' Draft ' ) ,
( ' confirm ' , ' Confirmed ' ) ,
( ' cancel ' , ' Cancelled ' ) ,
] , string = ' Status ' , default = ' draft ' , index = True , readonly = True )
number = fields . Char ( string = ' Reference ' , readonly = True )
line_ids = fields . One2many ( ' hr.payroll.advice.line ' , ' advice_id ' , string = ' Employee Salary ' ,
states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True , copy = True )
chaque_nos = fields . Char ( string = ' Cheque Numbers ' )
neft = fields . Boolean ( string = ' NEFT Transaction ' , help = ' Check this box if your company use online transfer for salary ' )
company_id = fields . Many2one ( ' res.company ' , string = ' Company ' , required = True , readonly = True ,
states = { ' draft ' : [ ( ' readonly ' , False ) ] } , default = lambda self : self . env . user . company_id )
bank_id = fields . Many2one ( ' res.bank ' , string = ' Bank ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ,
help = ' Select the Bank from which the salary is going to be paid ' )
batch_id = fields . Many2one ( ' hr.payslip.run ' , string = ' Batch ' , readonly = True )
@api.multi
def compute_advice ( self ) :
"""
Advice - Create Advice lines in Payment Advice and
compute Advice lines .
"""
for advice in self :
old_lines = self . env [ ' hr.payroll.advice.line ' ] . search ( [ ( ' advice_id ' , ' = ' , advice . id ) ] )
if old_lines :
old_lines . unlink ( )
payslips = self . env [ ' hr.payslip ' ] . search ( [ ( ' date_from ' , ' <= ' , advice . date ) , ( ' date_to ' , ' >= ' , advice . date ) , ( ' state ' , ' = ' , ' done ' ) ] )
for slip in payslips :
if not slip . employee_id . bank_account_id and not slip . employee_id . bank_account_id . acc_number :
raise UserError ( _ ( ' Please define bank account for the %s employee ' ) % ( slip . employee_id . name , ) )
payslip_line = self . env [ ' hr.payslip.line ' ] . search ( [ ( ' slip_id ' , ' = ' , slip . id ) , ( ' code ' , ' = ' , ' NET ' ) ] , limit = 1 )
if payslip_line :
self . env [ ' hr.payroll.advice.line ' ] . create ( {
' advice_id ' : advice . id ,
' name ' : slip . employee_id . bank_account_id . acc_number ,
' ifsc_code ' : slip . employee_id . bank_account_id . bank_bic or ' ' ,
' employee_id ' : slip . employee_id . id ,
' bysal ' : payslip_line . total
} )
slip . advice_id = advice . id
@api.multi
def confirm_sheet ( self ) :
"""
confirm Advice - confirmed Advice after computing Advice Lines . .
"""
for advice in self :
if not advice . line_ids :
raise UserError ( _ ( ' You can not confirm Payment advice without advice lines. ' ) )
date = fields . Date . from_string ( fields . Date . today ( ) )
advice_year = date . strftime ( ' % m ' ) + ' - ' + date . strftime ( ' % Y ' )
number = self . env [ ' ir.sequence ' ] . next_by_code ( ' payment.advice ' )
advice . write ( {
' number ' : ' PAY ' + ' / ' + advice_year + ' / ' + number ,
' state ' : ' confirm ' ,
} )
@api.multi
def set_to_draft ( self ) :
""" Resets Advice as draft.
"""
self . write ( { ' state ' : ' draft ' } )
@api.multi
def cancel_sheet ( self ) :
""" Marks Advice as cancelled.
"""
self . write ( { ' state ' : ' cancel ' } )
@api.onchange ( ' company_id ' )
def _onchange_company_id ( self ) :
self . bank_id = self . company_id . partner_id . bank_ids and self . company_id . partner_id . bank_ids [ 0 ] . bank_id . id or False
class HrPayslipRun ( models . Model ) :
_inherit = ' hr.payslip.run '
_description = ' Payslip Batches '
available_advice = fields . Boolean ( string = ' Made Payment Advice? ' ,
help = ' If this box is checked which means that Payment Advice exists for current batch ' ,
readonly = False , copy = False )
@api.multi
def draft_payslip_run ( self ) :
super ( HrPayslipRun , self ) . draft_payslip_run ( )
self . write ( { ' available_advice ' : False } )
@api.multi
def create_advice ( self ) :
for run in self :
if run . available_advice :
raise UserError ( _ ( " Payment advice already exists for %s , ' Set to Draft ' to create a new advice. " ) % ( run . name , ) )
company = self . env . user . company_id
advice = self . env [ ' hr.payroll.advice ' ] . create ( {
' batch_id ' : run . id ,
' company_id ' : company . id ,
' name ' : run . name ,
' date ' : run . date_end ,
' bank_id ' : company . partner_id . bank_ids and company . partner_id . bank_ids [ 0 ] . id or False
} )
for slip in run . slip_ids :
# TODO is it necessary to interleave the calls ?
slip . action_payslip_done ( )
if not slip . employee_id . bank_account_id or not slip . employee_id . bank_account_id . acc_number :
raise UserError ( _ ( ' Please define bank account for the %s employee ' ) % ( slip . employee_id . name ) )
payslip_line = self . env [ ' hr.payslip.line ' ] . search ( [ ( ' slip_id ' , ' = ' , slip . id ) , ( ' code ' , ' = ' , ' NET ' ) ] , limit = 1 )
if payslip_line :
self . env [ ' hr.payroll.advice.line ' ] . create ( {
' advice_id ' : advice . id ,
' name ' : slip . employee_id . bank_account_id . acc_number ,
' ifsc_code ' : slip . employee_id . bank_account_id . bank_bic or ' ' ,
' employee_id ' : slip . employee_id . id ,
' bysal ' : payslip_line . total
} )
self . write ( { ' available_advice ' : True } )
class HrPayrollAdviceLine ( models . Model ) :
'''
Bank Advice Lines
'''
_name = ' hr.payroll.advice.line '
_description = ' Bank Advice Lines '
advice_id = fields . Many2one ( ' hr.payroll.advice ' , string = ' Bank Advice ' )
name = fields . Char ( ' Bank Account No. ' , required = True )
ifsc_code = fields . Char ( string = ' IFSC Code ' )
employee_id = fields . Many2one ( ' hr.employee ' , string = ' Employee ' , required = True )
bysal = fields . Float ( string = ' By Salary ' , digits = dp . get_precision ( ' Payroll ' ) )
debit_credit = fields . Char ( string = ' C/D ' , default = ' C ' )
company_id = fields . Many2one ( ' res.company ' , related = ' advice_id.company_id ' , string = ' Company ' , store = True )
ifsc = fields . Boolean ( related = ' advice_id.neft ' , string = ' IFSC ' )
@api.onchange ( ' employee_id ' )
def onchange_employee_id ( self ) :
self . name = self . employee_id . bank_account_id . acc_number
self . ifsc_code = self . employee_id . bank_account_id . bank_bic or ' '
class HrPayslip ( models . Model ) :
'''
Employee Pay Slip
'''
_inherit = ' hr.payslip '
_description = ' Pay Slips '
advice_id = fields . Many2one ( ' hr.payroll.advice ' , string = ' Bank Advice ' , copy = False )
class ResCompany ( models . Model ) :
_inherit = ' res.company '
dearness_allowance = fields . Boolean ( string = ' Dearness Allowance ' , default = True ,
help = ' Check this box if your company provide Dearness Allowance to employee ' )