[MIG] l10n_in_hr_payroll : Migrated to new API.
This commit is contained in:
committed by
Yannick Tivisse
parent
0b4b508ddd
commit
a7886df35f
@@ -1,4 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import models
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Indian Payroll',
|
||||
'category': 'Localization',
|
||||
'depends': ['hr_payroll'],
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
Indian Payroll Salary Rules.
|
||||
============================
|
||||
@@ -21,7 +21,6 @@ Indian Payroll Salary Rules.
|
||||
- Payroll Advice and Report
|
||||
- Yearly Salary by Head and Yearly Salary by Employee Report
|
||||
""",
|
||||
'active': False,
|
||||
'data': [
|
||||
'views/l10n_in_hr_payroll_view.xml',
|
||||
'data/l10n_in_hr_payroll_data.xml',
|
||||
@@ -42,7 +41,5 @@ Indian Payroll Salary Rules.
|
||||
'test/payment_advice.yml',
|
||||
'test/payment_advice_batch.yml'
|
||||
],
|
||||
|
||||
'demo': ['demo/l10n_in_hr_payroll_demo.xml'],
|
||||
'installable': True
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<!-- Contribution Register -->
|
||||
|
||||
<record id="hr_houserent_allowance_register" model="hr.contribution.register">
|
||||
@@ -580,5 +579,4 @@ or - (contract.wage * 0.12))</field>
|
||||
<field name="name">Medical Reimbursement</field>
|
||||
<field name="input_id" ref="hr_salary_rule_medical"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="seq_payment_advice" model="ir.sequence">
|
||||
@@ -9,4 +9,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<!-- Salary Structure -->
|
||||
|
||||
<record id="hr_payroll_salary_structure_ind_emp" model="hr.payroll.structure">
|
||||
@@ -11,6 +9,4 @@
|
||||
<field name="company_id" ref="base.main_company"/>
|
||||
<field name="parent_id" ref="hr_payroll.structure_base"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import l10n_in_hr_payroll
|
||||
|
||||
@@ -1,246 +1,195 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from calendar import isleap
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv import fields, osv
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
DATETIME_FORMAT = "%Y-%m-%d"
|
||||
|
||||
class hr_contract(osv.osv):
|
||||
class HrContract(models.Model):
|
||||
"""
|
||||
Employee contract allows to add different values in fields.
|
||||
Fields are used in salary rule computation.
|
||||
"""
|
||||
|
||||
_inherit = 'hr.contract'
|
||||
_description = 'HR Contract'
|
||||
|
||||
_columns = {
|
||||
'tds': fields.float('TDS', digits_compute=dp.get_precision('Payroll'), help="Amount for Tax Deduction at Source"),
|
||||
'driver_salay': fields.boolean('Driver Salary', help="Check this box if you provide allowance for driver"),
|
||||
'medical_insurance': fields.float('Medical Insurance', digits_compute=dp.get_precision('Payroll'), help="Deduction towards company provided medical insurance"),
|
||||
'voluntary_provident_fund': fields.float('Voluntary Provident Fund (%)', digits_compute=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('House Rent Allowance (%)', digits_compute=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% and for non metro 40%. \nHRA computed as percentage(%)"),
|
||||
'supplementary_allowance': fields.float('Supplementary Allowance', digits_compute=dp.get_precision('Payroll')),
|
||||
}
|
||||
tds = fields.Float(string='TDS', digits_compute=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_compute=dp.get_precision('Payroll'),
|
||||
help='Deduction towards company provided medical insurance')
|
||||
voluntary_provident_fund = fields.Float(string='Voluntary Provident Fund (%)', digits_compute=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_compute=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% and for non metro 40%. \nHRA computed as percentage(%)')
|
||||
supplementary_allowance = fields.Float(string='Supplementary Allowance', digits_compute=dp.get_precision('Payroll'))
|
||||
|
||||
|
||||
class payroll_advice(osv.osv):
|
||||
class HrPayrollAdvice(models.Model):
|
||||
'''
|
||||
Bank Advice
|
||||
'''
|
||||
_name = 'hr.payroll.advice'
|
||||
_description = 'Bank Advice'
|
||||
_columns = {
|
||||
'name':fields.char('Name', readonly=True, required=True, states={'draft': [('readonly', False)]},),
|
||||
'note': fields.text('Description'),
|
||||
'date': fields.date('Date', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="Advice Date is used to search Payslips"),
|
||||
'state':fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('confirm', 'Confirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
], 'Status', select=True, readonly=True),
|
||||
'number': fields.char('Reference', readonly=True),
|
||||
'line_ids': fields.one2many('hr.payroll.advice.line', 'advice_id', 'Employee Salary', states={'draft': [('readonly', False)]}, readonly=True, copy=True),
|
||||
'chaque_nos': fields.char('Cheque Numbers'),
|
||||
'neft': fields.boolean('NEFT Transaction', help="Check this box if your company use online transfer for salary"),
|
||||
'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'bank_id':fields.many2one('res.bank', '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', 'Batch', readonly=True)
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'date': lambda * a: time.strftime('%Y-%m-%d'),
|
||||
'state': lambda * a: 'draft',
|
||||
'company_id': lambda self, cr, uid, context: \
|
||||
self.pool.get('res.users').browse(cr, uid, uid,
|
||||
context=context).company_id.id,
|
||||
'note': "Please make the payroll transfer from above account number to the below mentioned account numbers towards employee salaries:"
|
||||
}
|
||||
def _get_default_date(self):
|
||||
return fields.Date.from_string(fields.Date.today())
|
||||
|
||||
def compute_advice(self, cr, uid, ids, context=None):
|
||||
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.
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Advice’s IDs
|
||||
@return: Advice lines
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
payslip_pool = self.pool.get('hr.payslip')
|
||||
advice_line_pool = self.pool.get('hr.payroll.advice.line')
|
||||
payslip_line_pool = self.pool.get('hr.payslip.line')
|
||||
|
||||
for advice in self.browse(cr, uid, ids, context=context):
|
||||
old_line_ids = advice_line_pool.search(cr, uid, [('advice_id', '=', advice.id)], context=context)
|
||||
if old_line_ids:
|
||||
advice_line_pool.unlink(cr, uid, old_line_ids, context=context)
|
||||
slip_ids = payslip_pool.search(cr, uid, [('date_from', '<=', advice.date), ('date_to', '>=', advice.date), ('state', '=', 'done')], context=context)
|
||||
for slip in payslip_pool.browse(cr, uid, slip_ids, context=context):
|
||||
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,))
|
||||
line_ids = payslip_line_pool.search(cr, uid, [ ('slip_id', '=', slip.id), ('code', '=', 'NET')], context=context)
|
||||
if line_ids:
|
||||
line = payslip_line_pool.browse(cr, uid, line_ids, context=context)[0]
|
||||
advice_line = {
|
||||
'advice_id': advice.id,
|
||||
'name': slip.employee_id.bank_account_id.acc_number,
|
||||
'employee_id': slip.employee_id.id,
|
||||
'bysal': line.total
|
||||
}
|
||||
advice_line_pool.create(cr, uid, advice_line, context=context)
|
||||
payslip_pool.write(cr, uid, slip_ids, {'advice_id': advice.id}, context=context)
|
||||
return True
|
||||
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,
|
||||
'employee_id': slip.employee_id.id,
|
||||
'bysal': payslip_line.total
|
||||
})
|
||||
slip.advice_id = advice.id
|
||||
|
||||
def confirm_sheet(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def confirm_sheet(self):
|
||||
"""
|
||||
confirm Advice - confirmed Advice after computing Advice Lines..
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of confirm Advice’s IDs
|
||||
@return: confirmed Advice lines and set sequence of Advice.
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
seq_obj = self.pool.get('ir.sequence')
|
||||
for advice in self.browse(cr, uid, ids, context=context):
|
||||
for advice in self:
|
||||
if not advice.line_ids:
|
||||
raise UserError(_('You can not confirm Payment advice without advice lines.'))
|
||||
advice_date = datetime.strptime(advice.date, DATETIME_FORMAT)
|
||||
advice_year = advice_date.strftime('%m') + '-' + advice_date.strftime('%Y')
|
||||
number = seq_obj.next_by_code(cr, uid, 'payment.advice')
|
||||
sequence_num = 'PAY' + '/' + advice_year + '/' + number
|
||||
self.write(cr, uid, [advice.id], {'number': sequence_num, 'state': 'confirm'}, context=context)
|
||||
return True
|
||||
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',
|
||||
})
|
||||
|
||||
def set_to_draft(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def set_to_draft(self):
|
||||
"""Resets Advice as draft.
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state':'draft'}, context=context)
|
||||
self.write({'state': 'draft'})
|
||||
|
||||
def cancel_sheet(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def cancel_sheet(self):
|
||||
"""Marks Advice as cancelled.
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state':'cancel'}, context=context)
|
||||
self.write({'state': 'cancel'})
|
||||
|
||||
def onchange_company_id(self, cr, uid, ids, company_id=False, context=None):
|
||||
res = {}
|
||||
if company_id:
|
||||
company = self.pool.get('res.company').browse(cr, uid, [company_id], context=context)[0]
|
||||
if company.partner_id.bank_ids:
|
||||
res.update({'bank_id': company.partner_id.bank_ids[0].bank_id.id})
|
||||
return {
|
||||
'value':res
|
||||
}
|
||||
@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 hr_payslip_run(osv.osv):
|
||||
|
||||
class HrPayslipRun(models.Model):
|
||||
_inherit = 'hr.payslip.run'
|
||||
_description = 'Payslip Batches'
|
||||
_columns = {
|
||||
'available_advice': fields.boolean('Made Payment Advice?',
|
||||
help="If this box is checked which means that Payment Advice exists for current batch",
|
||||
readonly=False, copy=False),
|
||||
}
|
||||
|
||||
def draft_payslip_run(self, cr, uid, ids, context=None):
|
||||
res = super(hr_payslip_run, self).draft_payslip_run(cr, uid, ids, context=context)
|
||||
self.write(cr, uid, ids, {'available_advice': False}, context=context)
|
||||
return res
|
||||
|
||||
def create_advice(self, cr, uid, ids, context=None):
|
||||
payslip_pool = self.pool.get('hr.payslip')
|
||||
payslip_line_pool = self.pool.get('hr.payslip.line')
|
||||
advice_pool = self.pool.get('hr.payroll.advice')
|
||||
advice_line_pool = self.pool.get('hr.payroll.advice.line')
|
||||
users = self.pool.get('res.users').browse(cr, uid, [uid], context=context)
|
||||
for run in self.browse(cr, uid, ids, context=context):
|
||||
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,))
|
||||
advice_data = {
|
||||
company = self.env.user.company_id
|
||||
advice = self.env['hr.payroll.advice'].create({
|
||||
'batch_id': run.id,
|
||||
'company_id': users[0].company_id.id,
|
||||
'company_id': company.id,
|
||||
'name': run.name,
|
||||
'date': run.date_end,
|
||||
'bank_id': users[0].company_id.partner_id.bank_ids and users[0].company_id.partner_id.bank_ids[0].id or False
|
||||
}
|
||||
advice_id = advice_pool.create(cr, uid, advice_data, context=context)
|
||||
slip_ids = []
|
||||
for slip_id in run.slip_ids:
|
||||
'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 ?
|
||||
payslip_pool.signal_workflow(cr, uid, [slip_id.id], 'hr_verify_sheet')
|
||||
payslip_pool.signal_workflow(cr, uid, [slip_id.id], 'process_sheet')
|
||||
slip_ids.append(slip_id.id)
|
||||
|
||||
for slip in payslip_pool.browse(cr, uid, slip_ids, context=context):
|
||||
slip.signal_workflow('hr_verify_sheet')
|
||||
slip.signal_workflow('process_sheet')
|
||||
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))
|
||||
line_ids = payslip_line_pool.search(cr, uid, [('slip_id', '=', slip.id), ('code', '=', 'NET')], context=context)
|
||||
if line_ids:
|
||||
line = payslip_line_pool.browse(cr, uid, line_ids, context=context)[0]
|
||||
advice_line = {
|
||||
'advice_id': advice_id,
|
||||
'name': slip.employee_id.bank_account_id.acc_number,
|
||||
'employee_id': slip.employee_id.id,
|
||||
'bysal': line.total
|
||||
}
|
||||
advice_line_pool.create(cr, uid, advice_line, context=context)
|
||||
return self.write(cr, uid, ids, {'available_advice' : True})
|
||||
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,
|
||||
'employee_id': slip.employee_id.id,
|
||||
'bysal': payslip_line.total
|
||||
})
|
||||
run.available_advice = True
|
||||
|
||||
|
||||
class payroll_advice_line(osv.osv):
|
||||
class HrPayrollAdviceLine(models.Model):
|
||||
'''
|
||||
Bank Advice Lines
|
||||
'''
|
||||
def onchange_employee_id(self, cr, uid, ids, employee_id=False, context=None):
|
||||
res = {}
|
||||
hr_obj = self.pool.get('hr.employee')
|
||||
if not employee_id:
|
||||
return {'value': res}
|
||||
employee = hr_obj.browse(cr, uid, [employee_id], context=context)[0]
|
||||
res.update({'name': employee.bank_account_id.acc_number , 'ifsc_code': employee.bank_account_id.bank_bic or ''})
|
||||
return {'value': res}
|
||||
|
||||
_name = 'hr.payroll.advice.line'
|
||||
_description = 'Bank Advice Lines'
|
||||
_columns = {
|
||||
'advice_id': fields.many2one('hr.payroll.advice', 'Bank Advice'),
|
||||
'name': fields.char('Bank Account No.', size=25, required=True),
|
||||
'ifsc_code': fields.char('IFSC Code', size=16),
|
||||
'employee_id': fields.many2one('hr.employee', 'Employee', required=True),
|
||||
'bysal': fields.float('By Salary', digits_compute=dp.get_precision('Payroll')),
|
||||
'debit_credit': fields.char('C/D', size=3, required=False),
|
||||
'company_id': fields.related('advice_id', 'company_id', type='many2one', required=False, relation='res.company', string='Company', store=True),
|
||||
'ifsc': fields.related('advice_id', 'neft', type='boolean', string='IFSC'),
|
||||
}
|
||||
_defaults = {
|
||||
'debit_credit': 'C',
|
||||
}
|
||||
|
||||
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_compute=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.write({
|
||||
'name': self.employee_id.bank_account_id.acc_number,
|
||||
'ifsc_code': self.employee_id.bank_account_id.bank_bic or ''
|
||||
})
|
||||
|
||||
|
||||
class hr_payslip(osv.osv):
|
||||
class HrPayslip(models.Model):
|
||||
'''
|
||||
Employee Pay Slip
|
||||
'''
|
||||
_inherit = 'hr.payslip'
|
||||
_description = 'Pay Slips'
|
||||
_columns = {
|
||||
'advice_id': fields.many2one('hr.payroll.advice', 'Bank Advice', copy=False)
|
||||
}
|
||||
|
||||
class res_company(osv.osv):
|
||||
advice_id = fields.Many2one('hr.payroll.advice', string='Bank Advice', copy=False)
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
_columns = {
|
||||
'dearness_allowance': fields.boolean('Dearness Allowance', help="Check this box if your company provide Dearness Allowance to employee")
|
||||
}
|
||||
_defaults = {
|
||||
'dearness_allowance': True,
|
||||
}
|
||||
|
||||
dearness_allowance = fields.Boolean(string='Dearness Allowance', default=True,
|
||||
help='Check this box if your company provide Dearness Allowance to employee')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import report_payslip_details
|
||||
|
||||
@@ -1,40 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import fields, osv
|
||||
from odoo import fields, models
|
||||
from odoo.tools.sql import drop_view_if_exists
|
||||
|
||||
class payment_advice_report(osv.osv):
|
||||
|
||||
class PaymentAdviceReport(models.Model):
|
||||
_name = "payment.advice.report"
|
||||
_description = "Payment Advice Analysis"
|
||||
_auto = False
|
||||
_columns = {
|
||||
'name':fields.char('Name', readonly=True),
|
||||
'date': fields.date('Date', readonly=True,),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
|
||||
('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
|
||||
('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'state':fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('confirm', 'Confirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
], 'Status', select=True, readonly=True),
|
||||
'employee_id': fields.many2one('hr.employee', 'Employee', readonly=True),
|
||||
'nbr': fields.integer('# Payment Lines', readonly=True),
|
||||
'number':fields.char('Number', readonly=True),
|
||||
'bysal': fields.float('By Salary', readonly=True),
|
||||
'bank_id':fields.many2one('res.bank', 'Bank', readonly=True),
|
||||
'company_id':fields.many2one('res.company', 'Company', readonly=True),
|
||||
'cheque_nos':fields.char('Cheque Numbers', readonly=True),
|
||||
'neft': fields.boolean('NEFT Transaction', readonly=True),
|
||||
'ifsc_code': fields.char('IFSC Code', size=32, readonly=True),
|
||||
'employee_bank_no': fields.char('Employee Bank Account', required=True),
|
||||
}
|
||||
def init(self, cr):
|
||||
tools.drop_view_if_exists(cr, 'payment_advice_report')
|
||||
cr.execute("""
|
||||
|
||||
name = fields.Char(readonly=True)
|
||||
date = fields.Date(readonly=True)
|
||||
year = fields.Char(size=4, readonly=True)
|
||||
month = fields.Selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
|
||||
('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
|
||||
('10', 'October'), ('11', 'November'), ('12', 'December')], readonly=True)
|
||||
day = fields.Char(size=128, readonly=True)
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('confirm', 'Confirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
], string='Status', index=True, readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', string='Employee', readonly=True)
|
||||
nbr = fields.Integer(string='# Payment Lines', readonly=True)
|
||||
number = fields.Char(readonly=True)
|
||||
bysal = fields.Float(string='By Salary', readonly=True)
|
||||
bank_id = fields.Many2one('res.bank', string='Bank', readonly=True)
|
||||
company_id = fields.Many2one('res.company', string='Company', readonly=True)
|
||||
cheque_nos = fields.Char(string='Cheque Numbers', readonly=True)
|
||||
neft = fields.Boolean(string='NEFT Transaction', readonly=True)
|
||||
ifsc_code = fields.Char(string='IFSC Code', size=32, readonly=True)
|
||||
employee_bank_no = fields.Char(string='Employee Bank Account', required=True)
|
||||
|
||||
def init(self):
|
||||
drop_view_if_exists(self.env.cr, self._table)
|
||||
self.env.cr.execute("""
|
||||
create or replace view payment_advice_report as (
|
||||
select
|
||||
min(l.id) as id,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<record id="view_payment_advice_tree" model="ir.ui.view">
|
||||
<field name="name">payment.advice.report.tree</field>
|
||||
<field name="model">payment.advice.report</field>
|
||||
@@ -80,6 +78,4 @@
|
||||
|
||||
<menuitem name="Reports" id="menu_l10n_in_hr_payroll_report" parent="hr_payroll.menu_hr_payroll_root" sequence="99" groups="base.group_hr_manager"/>
|
||||
<menuitem action="action_payment_advice_report_all" id="menu_reporting_payment_advice" parent="menu_l10n_in_hr_payroll_report" sequence="5" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import fields, osv
|
||||
from odoo import fields, models
|
||||
from odoo.tools.sql import drop_view_if_exists
|
||||
|
||||
class payslip_report(osv.osv):
|
||||
|
||||
class PayslipReport(models.Model):
|
||||
_name = "payslip.report"
|
||||
_description = "Payslip Analysis"
|
||||
_auto = False
|
||||
_columns = {
|
||||
'name':fields.char('Name', readonly=True),
|
||||
'date_from': fields.date('Date From', readonly=True,),
|
||||
'date_to': fields.date('Date To', readonly=True,),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
|
||||
('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
|
||||
('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
('cancel', 'Rejected'),
|
||||
], 'Status', readonly=True),
|
||||
'employee_id': fields.many2one('hr.employee', 'Employee', readonly=True),
|
||||
'nbr': fields.integer('# Payslip lines', readonly=True),
|
||||
'number': fields.char('Number', readonly=True),
|
||||
'struct_id': fields.many2one('hr.payroll.structure', 'Structure', readonly=True),
|
||||
'company_id':fields.many2one('res.company', 'Company', readonly=True),
|
||||
'paid': fields.boolean('Made Payment Order ? ', readonly=True),
|
||||
'total': fields.float('Total', readonly=True),
|
||||
'category_id':fields.many2one('hr.salary.rule.category', 'Category', readonly=True),
|
||||
}
|
||||
def init(self, cr):
|
||||
tools.drop_view_if_exists(cr, 'payslip_report')
|
||||
cr.execute("""
|
||||
|
||||
name = fields.Char(readonly=True)
|
||||
date_from = fields.Date(string='Date From', readonly=True)
|
||||
date_to = fields.Date(string='Date To', readonly=True)
|
||||
year = fields.Char(size=4, readonly=True)
|
||||
month = fields.Selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
|
||||
('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
|
||||
('10', 'October'), ('11', 'November'), ('12', 'December')], readonly=True)
|
||||
day = fields.Char(size=128, readonly=True)
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('done', 'Done'),
|
||||
('cancel', 'Rejected'),
|
||||
], string='Status', readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', string='Employee', readonly=True)
|
||||
nbr = fields.Integer(string='# Payslip lines', readonly=True)
|
||||
number = fields.Char(readonly=True)
|
||||
struct_id = fields.Many2one('hr.payroll.structure', string='Structure', readonly=True)
|
||||
company_id = fields.Many2one('res.company', string='Company', readonly=True)
|
||||
paid = fields.Boolean(string='Made Payment Order ? ', readonly=True)
|
||||
total = fields.Float(readonly=True)
|
||||
category_id = fields.Many2one('hr.salary.rule.category', string='Category', readonly=True)
|
||||
|
||||
def init(self):
|
||||
drop_view_if_exists(self.env.cr, self._table)
|
||||
self.env.cr.execute("""
|
||||
create or replace view payslip_report as (
|
||||
select
|
||||
min(l.id) as id,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<record id="view_payslip_tree" model="ir.ui.view">
|
||||
<field name="name">payslip.report.tree</field>
|
||||
<field name="model">payslip.report</field>
|
||||
@@ -97,6 +95,4 @@
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<report
|
||||
id="payslip_details_report"
|
||||
model="hr.payslip"
|
||||
@@ -35,6 +33,4 @@
|
||||
file="l10n_in_hr_payroll.report_hryearlysalary"
|
||||
report_type="qweb-pdf"
|
||||
string="Yearly Salary by Employee" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
|
||||
<data>
|
||||
|
||||
<odoo>
|
||||
<record id="hr_contract_form_in_inherit" model="ir.ui.view">
|
||||
<field name="name">hr.contract.form.in.inherit</field>
|
||||
<field name="model">hr.contract</field>
|
||||
@@ -216,6 +213,4 @@
|
||||
view_id ="hr_payroll.view_hr_payslip_tree"
|
||||
id="act_hr_emp_payslip_list"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report_hrsalarybymonth">
|
||||
<t t-call="report.html_container">
|
||||
<t t-call="report.internal_layout">
|
||||
@@ -56,5 +55,4 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report_hryearlysalary">
|
||||
<t t-call="report.html_container">
|
||||
<t t-foreach="get_employee(data['form'])" t-as="employee">
|
||||
@@ -117,5 +116,4 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report_payrolladvice">
|
||||
<t t-call="report.html_container">
|
||||
<t t-call="report.external_layout">
|
||||
@@ -88,5 +87,4 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<template id="report_payslipdetails">
|
||||
<t t-call="report.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
@@ -94,5 +93,4 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,46 +1,39 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
from openerp.osv import fields, osv
|
||||
from odoo import api, fields, models
|
||||
|
||||
class hr_salary_employee_bymonth(osv.osv_memory):
|
||||
|
||||
class HrSalaryEmployeeBymonth(models.TransientModel):
|
||||
|
||||
_name = 'hr.salary.employee.month'
|
||||
_description = 'Hr Salary Employee By Month Report'
|
||||
_columns = {
|
||||
'start_date': fields.date('Start Date', required=True),
|
||||
'end_date': fields.date('End Date', required=True),
|
||||
'employee_ids': fields.many2many('hr.employee', 'payroll_year_rel', 'payroll_year_id', 'employee_id', 'Employees', required=True),
|
||||
'category_id': fields.many2one('hr.salary.rule.category', 'Category', required=True),
|
||||
}
|
||||
|
||||
def _get_default_category(self, cr, uid, context=None):
|
||||
category_ids = self.pool.get('hr.salary.rule.category').search(cr, uid, [('code', '=', 'NET')], context=context)
|
||||
return category_ids and category_ids[0] or False
|
||||
def _get_default_category(self):
|
||||
return self.env['hr.salary.rule.category'].search([('code', '=', 'NET')], limit=1)
|
||||
|
||||
_defaults = {
|
||||
'start_date': lambda *a: time.strftime('%Y-01-01'),
|
||||
'end_date': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
'category_id': _get_default_category
|
||||
}
|
||||
def _get_default_start_date(self):
|
||||
year = fields.Date.from_string(fields.Date.today()).strftime('%Y')
|
||||
return '{}-01-01'.format(year)
|
||||
|
||||
def print_report(self, cr, uid, ids, context=None):
|
||||
def _get_default_end_date(self):
|
||||
date = fields.Date.from_string(fields.Date.today())
|
||||
return date.strftime('%Y') + '-' + date.strftime('%m') + '-' + date.strftime('%d')
|
||||
|
||||
start_date = fields.Date(string='Start Date', required=True, default=_get_default_start_date)
|
||||
end_date = fields.Date(string='End Date', required=True, default=_get_default_end_date)
|
||||
employee_ids = fields.Many2many('hr.employee', 'payroll_year_rel', 'payroll_year_id', 'employee_id', string='Employees', required=True)
|
||||
category_id = fields.Many2one('hr.salary.rule.category', string='Category', required=True, default=_get_default_category)
|
||||
|
||||
@api.multi
|
||||
def print_report(self):
|
||||
"""
|
||||
To get the date and print the report
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param context: A standard dictionary
|
||||
@return: return report
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
datas = {'ids': context.get('active_ids', [])}
|
||||
|
||||
res = self.read(cr, uid, ids, context=context)
|
||||
self.ensure_one()
|
||||
data = {'ids': self.env.context.get('active_ids', [])}
|
||||
res = self.read()
|
||||
res = res and res[0] or {}
|
||||
datas.update({'form': res})
|
||||
return self.pool['report'].get_action(cr, uid, ids,
|
||||
'l10n_in_hr_payroll.report_hrsalarybymonth',
|
||||
data=datas, context=context)
|
||||
data.update({'form': res})
|
||||
return self.env['report'].get_action(self, 'l10n_in_hr_payroll.report_hrsalarybymonth', data=data)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="view_salary_employee_month" model="ir.ui.view">
|
||||
<field name="name">Hr monthly Employee Salary</field>
|
||||
<field name="model">hr.salary.employee.month</field>
|
||||
@@ -39,6 +38,4 @@
|
||||
id="menu_salary_employee_month"
|
||||
groups="base.group_hr_manager,base.group_hr_user"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
from odoo import api, fields, models
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
class yearly_salary_detail(osv.osv_memory):
|
||||
class YearlySalaryDetail(models.TransientModel):
|
||||
_name = 'yearly.salary.detail'
|
||||
_description = 'Hr Salary Employee By Category Report'
|
||||
|
||||
_name ='yearly.salary.detail'
|
||||
_description = 'Hr Salary Employee By Category Report'
|
||||
_columns = {
|
||||
'employee_ids': fields.many2many('hr.employee', 'payroll_emp_rel', 'payroll_id', 'employee_id', 'Employees', required=True),
|
||||
'date_from': fields.date('Start Date', required=True),
|
||||
'date_to': fields.date('End Date', required=True),
|
||||
}
|
||||
def _get_default_date_from(self):
|
||||
year = fields.Date.from_string(fields.Date.today()).strftime('%Y')
|
||||
return '{}-01-01'.format(year)
|
||||
|
||||
_defaults = {
|
||||
'date_from': lambda *a: time.strftime('%Y-01-01'),
|
||||
'date_to': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
def _get_default_date_to(self):
|
||||
date = fields.Date.from_string(fields.Date.today())
|
||||
return date.strftime('%Y') + '-' + date.strftime('%m') + '-' + date.strftime('%d')
|
||||
|
||||
}
|
||||
employee_ids = fields.Many2many('hr.employee', 'payroll_emp_rel', 'payroll_id', 'employee_id', string='Employees', required=True)
|
||||
date_from = fields.Date(string='Start Date', required=True, default=_get_default_date_from)
|
||||
date_to = fields.Date(string='End Date', required=True, default=_get_default_date_to)
|
||||
|
||||
def print_report(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def print_report(self):
|
||||
"""
|
||||
To get the date and print the report
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param context: A standard dictionary
|
||||
@return: return report
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
datas = {'ids': context.get('active_ids', [])}
|
||||
|
||||
res = self.read(cr, uid, ids, context=context)
|
||||
self.ensure_one()
|
||||
data = {'ids': self.env.context.get('active_ids', [])}
|
||||
res = self.read()
|
||||
res = res and res[0] or {}
|
||||
datas.update({'form':res})
|
||||
return self.pool['report'].get_action(cr, uid, ids, 'l10n_in_hr_payroll.report_hryearlysalary', data=datas, context=context)
|
||||
data.update({'form': res})
|
||||
return self.env['report'].get_action(self, 'l10n_in_hr_payroll.report_hryearlysalary', data=data)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="view_yearly_salary_detail" model="ir.ui.view">
|
||||
<field name="name">Employee Yearly Salary</field>
|
||||
<field name="model">yearly.salary.detail</field>
|
||||
@@ -38,6 +37,4 @@
|
||||
id="menu_yearly_salary_detail"
|
||||
groups="base.group_hr_manager,base.group_hr_user"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user