add new module

This commit is contained in:
sonal arora
2020-07-21 10:09:46 +00:00
parent 800e7fdceb
commit c0d10e3fbe
1063 changed files with 243750 additions and 5 deletions

View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from . import gratuity_configuration
from . import hr_gratuity
from . import gratuity_accounting_configuration
from . import hr_employee
from . import hr_leave
from . import hr_training
from . import hr_contract

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
import datetime
from odoo import fields, models, api, exceptions, _
from odoo.exceptions import ValidationError,UserError
date_format = "%Y-%m-%d"
class EmployeeGratuity(models.Model):
_name = 'hr.gratuity'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Employee Gratuity"
state = fields.Selection([
('draft', 'Draft'),
('validate', 'Validated'),
('approve', 'Approved'),
('cancel', 'Cancelled')],
default='draft', track_visibility='onchange')
name = fields.Char(string='Reference', required=True, copy=False, readonly=True,
default=lambda self: _('New'))
employee_id = fields.Many2one('hr.resignation', string='Employee', required=True,
domain="[('state', '=', 'approved')]")
joined_date = fields.Date(string="Joined Date", readonly=True)
worked_years = fields.Integer(string="Total Work Years", readonly=True)
last_month_salary = fields.Integer(string="Last Salary", required=True, default=0)
allowance = fields.Char(string="Dearness Allowance", default=0)
gratuity_amount = fields.Integer(string="Gratuity Payable", required=True, default=0,
readony=True, help=("Gratuity is calculated based on the "
"equation Last salary * Number of years of service * 15 / 26 "))
currency_id = fields.Many2one('res.currency', string='Currency', required=True,
default=lambda self: self.env.user.company_id.currency_id)
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.user.company_id)
# assigning the sequence for the record
@api.model
def create(self, vals):
vals['name'] = self.env['ir.sequence'].next_by_code('hr.gratuity')
return super(EmployeeGratuity, self).create(vals)
# Check whether any Gratuity request already exists
@api.onchange('employee_id')
@api.depends('employee_id')
def check_request_existence(self):
for rec in self:
if rec.employee_id:
gratuity_request = self.env['hr.gratuity'].search([('employee_id', '=', rec.employee_id.id),
('state', 'in', ['draft', 'validate', 'approve', 'cancel'])])
if gratuity_request:
raise ValidationError(_('A Settlement request is already processed'
' for this employee'))
def validate_function(self):
# calculating the years of work by the employee
worked_years = int(datetime.datetime.now().year) - int(str(self.joined_date).split('-')[0])
if worked_years < 5:
self.write({
'state': 'draft'})
worked_years = int(datetime.datetime.now().year) - int(str(self.joined_date).split('-')[0])
self.worked_years = worked_years
raise exceptions.except_orm(_('Employee Working Period is less than 5 Year'),
_('Only an Employee with minimum 5 years of working, will get the Gratuity'))
else:
worked_years = int(datetime.datetime.now().year) - int(str(self.joined_date).split('-')[0])
self.worked_years = worked_years
cr = self._cr # find out the correct date of last salary of employee
query = """select amount from hr_payslip_line psl
inner join hr_payslip ps on ps.id=psl.slip_id
where ps.employee_id="""+str(self.employee_id.employee_id.id)+\
"""and ps.state='done' and psl.code='NET'
order by ps.date_from desc limit 1"""
cr.execute(query)
data = cr.fetchall()
if data :
last_salary = data[0][0]
else :
last_salary = 0
self.last_month_salary = last_salary
amount = ((self.last_month_salary + int(self.allowance)) * int(worked_years) * 15) / 26
self.gratuity_amount = round(amount) if self.state == 'approve' else 0
self.write({
'state': 'validate'})
def approve_function(self):
if not self.allowance.isdigit():
raise ValidationError(_('Allowance value should be numeric !!'))
self.write({
'state': 'approve'
})
amount = ((self.last_month_salary + int(self.allowance)) * int(self.worked_years) * 15) / 26
self.gratuity_amount = round(amount) if self.state == 'approve' else 0
def cancel_function(self):
self.write({
'state': 'cancel'
})
def draft_function(self):
self.write({
'state': 'draft'
})
# assigning the join date of the selected employee
@api.onchange('employee_id')
def _on_change_employee_id(self):
rec = self.env['hr.resignation'].search([['id', '=', self.employee_id.id]])
if rec:
self.joined_date = rec.joined_date
else:
self.joined_date = ''

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class GratuityAccountingConfiguration(models.Model):
_name = 'hr.gratuity.accounting.configuration'
_rec_name = 'name'
_description = "Gratuity Accounting Configuration"
name = fields.Char()
active = fields.Boolean(default=True)
gratuity_start_date = fields.Date(string='Start Date', help="Starting date of the gratuity")
gratuity_end_date = fields.Date(string='End Date', help="Ending date of the gratuity")
gratuity_credit_account = fields.Many2one('account.account', help="Credit account for the gratuity")
gratuity_debit_account = fields.Many2one('account.account', help="Debit account for the gratuity")
gratuity_journal = fields.Many2one('account.journal', help="Journal for the gratuity")
config_contract_type = fields.Selection(
[('limited', 'Limited'),
('unlimited', 'Unlimited')], default="limited", required=True,
string='Contract Type')
gratuity_configuration_table = fields.One2many('gratuity.configuration',
'gratuity_accounting_configuration_id')
@api.onchange('gratuity_start_date', 'gratuity_end_date')
def onchange_date(self):
""" Function to check date """
if self.gratuity_start_date and self.gratuity_end_date:
if not self.gratuity_start_date < self.gratuity_end_date:
raise UserError(_("Invalid date configuration!"))
_sql_constraints = [('name_uniq', 'unique(name)',
'Gratuity configuration name should be unique!')]

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api, _
from odoo.exceptions import UserError
class GratuityConfiguration(models.Model):
""" Model for gratuity duration configuration details """
_name = 'gratuity.configuration'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Gratuity Configuration"
_rec_name = "name"
gratuity_accounting_configuration_id = fields.Many2one('hr.gratuity.accounting.configuration')
name = fields.Char(string="Name", required=True)
active = fields.Boolean(default=True)
from_year = fields.Float(string="From Year")
to_year = fields.Float(string="To Year")
yr_from_flag = fields.Boolean(compute="_compute_yr_field_required",
store=True)
yr_to_flag = fields.Boolean(compute="_compute_yr_field_required",
store=True)
company_id = fields.Many2one('res.company', 'Company', required=True, help="Company",
index=True,
default=lambda self: self.env.company)
employee_daily_wage_days = fields.Integer(default=30, help="Total number of employee wage days")
employee_working_days = fields.Integer(string='Working Days', default=21,
help='Number of working days per month')
percentage = fields.Float(default=1)
@api.onchange('from_year', 'to_year')
def onchange_year(self):
""" Function to check year configuration """
if self.from_year and self.to_year:
if not self.from_year < self.to_year:
raise UserError(_("Invalid year configuration!"))
@api.depends('from_year', 'to_year')
def _compute_yr_field_required(self):
""" Compute year from and to required """
for rec in self:
rec.yr_from_flag = True if not rec.to_year else False
rec.yr_to_flag = True if not rec.from_year else False

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class Probation(models.Model):
_inherit = 'hr.contract'
training_info = fields.Text(string='Probationary Info')
waiting_for_approval = fields.Boolean()
is_approve = fields.Boolean()
state = fields.Selection(
selection=[
('draft', 'New'),
('probation', 'Probation'),
('open', 'Running'),
('close', 'Expired'),
('cancel', 'Cancelled'),
],
)
probation_id = fields.Many2one('hr.training')
half_leave_ids = fields.Many2many('hr.leave', string="Half Leave")
training_amount = fields.Float(string='Training Amount', help="amount for the employee during training")
@api.onchange('trial_date_end')
def state_probation(self):
"""
function used for changing state draft to probation
when the end of trail date setting
"""
if self.trial_date_end:
self.state = 'probation'
@api.onchange('employee_id')
def change_employee_id(self):
"""
function for changing employee id of hr.training if changed
"""
if self.probation_id and self.employee_id:
self.probation_id.employee_id = self.employee_id.id
def action_approve(self):
"""
function used for changing the state probation into
running when approves a contract
"""
self.write({'is_approve': True})
if self.state == 'probation':
self.write({'state': 'open',
'is_approve': False})
@api.model
def create(self, vals_list):
"""
function for create a record based on probation
details in a model
"""
if vals_list['trial_date_end'] and vals_list['state'] == 'probation':
dtl = self.env['hr.training'].create({
'employee_id': vals_list['employee_id'],
'start_date': vals_list['date_start'],
'end_date': vals_list['trial_date_end'],
})
vals_list['probation_id'] = dtl.id
res = super(Probation, self).create(vals_list)
return res
def write(self, vals):
"""
function for checking stage changing and creating probation
record based on contract stage
"""
if self.state == 'probation':
if vals.get('state') == 'open' and not self.is_approve:
raise UserError(_("You cannot change the status of non-approved Contracts"))
if vals.get('state') == 'cancel' or vals.get('state') == 'close' or vals.get('state') == 'draft':
raise UserError(_("You cannot change the status of non-approved Contracts"))
training_dtl = self.env['hr.training'].search([('employee_id', '=', self.employee_id.id)])
if training_dtl:
return super(Probation, self).write(vals)
if not training_dtl:
if self.trial_date_end and self.state == 'probation':
self.env['hr.training'].create({
'employee_id': self.employee_id.id,
'start_date': self.date_start,
'end_date': self.trial_date_end,
})
return super(Probation, self).write(vals)

View File

@@ -0,0 +1,39 @@
from odoo import fields, models
from odoo.osv import expression
class HrEmployeeProbation(models.Model):
_inherit = 'hr.employee'
def generate_work_entries(self, date_start, date_stop):
"""
function is used for Generate work entries When
Contract State in Probation,Running,Expired
"""
date_start = fields.Date.to_date(date_start)
date_stop = fields.Date.to_date(date_stop)
if self:
current_contracts = self._get_contracts(date_start, date_stop, states=['probation', 'open', 'close'])
else:
current_contracts = self._get_all_contracts(date_start, date_stop, states=['probation', 'open', 'close'])
return bool(current_contracts._generate_work_entries(date_start, date_stop))
# override the existing function for considering the probation contracts
def _get_contracts(self, date_from, date_to, states=['open', 'probation'], kanban_state=False):
"""
Returns the contracts of the employee between date_from and date_to
"""
state_domain = [('state', 'in', states)]
if kanban_state:
state_domain = expression.AND([state_domain, [('kanban_state', 'in', kanban_state)]])
return self.env['hr.contract'].search(
expression.AND([[('employee_id', 'in', self.ids)],
state_domain,
[('date_start', '<=', date_to),
'|',
('date_end', '=', False),
('date_end', '>=', date_from)]]))

View File

@@ -0,0 +1,232 @@
# -*- coding: utf-8 -*-
from datetime import date
from odoo import fields, models, api, _
from odoo.exceptions import Warning, UserError
class EmployeeGratuity(models.Model):
_name = 'hr.gratuity'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Employee Gratuity"
state = fields.Selection([
('draft', 'Draft'),
('submit', 'Submitted'),
('approve', 'Approved'),
('cancel', 'Cancelled')],
default='draft', track_visibility='onchange')
name = fields.Char(string='Reference', required=True, copy=False,
readonly=True,
default=lambda self: _('New'))
employee_id = fields.Many2one('hr.employee', string='Employee',
required=True, help="Employee")
employee_contract_type = fields.Selection([
('limited', 'Limited'),
('unlimited', 'Unlimited')], string='Contract Type', readonly=True,
store=True, help="Choose the contract type."
"if contract type is limited then during gratuity settlement if you have not specify the end date for contract, gratuity configration of limited type will be taken or"
"if contract type is Unlimited then during gratuity settlement if you have specify the end date for contract, gratuity configration of limited type will be taken.")
employee_joining_date = fields.Date(string='Joining Date', readonly=True,
store=True, help="Employee joining date")
wage_type = fields.Selection([('monthly', 'Monthly Fixed Wage'), ('hourly', 'Hourly Wage')],
help="Select the wage type monthly or hourly")
total_working_years = fields.Float(string='Total Years Worked', readonly=True, store=True,
help="Total working years")
employee_probation_years = fields.Float(string='Leaves Taken(Years)', readonly=True, store=True,
help="Employee probation years")
employee_gratuity_years = fields.Float(string='Gratuity Calculation Years',
readonly=True, store=True, help="Employee gratuity years")
employee_basic_salary = fields.Float(string='Basic Salary',
readonly=True,
help="Employee's basic salary.")
employee_gratuity_duration = fields.Many2one('gratuity.configuration',
readonly=True,
string='Configuration Line')
employee_gratuity_configuration = fields.Many2one('hr.gratuity.accounting.configuration',
readonly=True,
string='Gratuity Configuration')
employee_gratuity_amount = fields.Float(string='Gratuity Payment', readonly=True, store=True,
help="Gratuity amount for the employee. \it is calculated If the wage type is hourly then gratuity payment is calculated as employee basic salary * Employee Daily Wage Days * gratuity configration rule percentage * gratuity calculation years.orIf the wage type is monthly then gratuity payment is calculated as employee basic salary * (Working Days/Employee Daily Wage Days) * gratuity configration rule percentage * gratuity calculation years.")
hr_gratuity_credit_account = fields.Many2one('account.account', help="Gratuity credit account")
hr_gratuity_debit_account = fields.Many2one('account.account', help="Gratuity debit account")
hr_gratuity_journal = fields.Many2one('account.journal', help="Gratuity journal")
company_id = fields.Many2one('res.company', 'Company', required=True,
default=lambda self: self.env.company, help="Company")
currency_id = fields.Many2one(related="company_id.currency_id",
string="Currency", readonly=True, help="Currency")
@api.model
def create(self, vals):
""" assigning the sequence for the record """
vals['name'] = self.env['ir.sequence'].next_by_code('hr.gratuity')
return super(EmployeeGratuity, self).create(vals)
@api.depends('employee_id')
@api.onchange('employee_id')
def _onchange_employee_id(self):
""" calculating the gratuity pay based on the contract and gratuity
configurations """
if self.employee_id.id:
current_date = date.today()
probation_ids = self.env['hr.training'].search([('employee_id', '=', self.employee_id.id)])
contract_ids = self.env['hr.contract'].search([('employee_id', '=', self.employee_id.id)])
contract_sorted = contract_ids.sorted(lambda line: line.date_start)
if not contract_sorted:
raise Warning(_('No contracts found for the selected employee...!\n'
'Employee must have at least one contract to compute gratuity settelement.'))
self.employee_joining_date = joining_date = contract_sorted[0].date_start
employee_probation_days = 0
# find total probation days
for probation in probation_ids:
start_date = probation.start_date
end_date = probation.end_date
employee_probation_days += (end_date - start_date).days
# get running contract
hr_contract_id = self.env['hr.contract'].search(
[('employee_id', '=', self.employee_id.id), ('state', '=', 'open')])
if len(hr_contract_id) > 1 or not hr_contract_id:
raise Warning(_('Selected employee have multiple or no running contracts!'))
self.wage_type = hr_contract_id.wage_type
if self.wage_type == 'hourly':
self.employee_basic_salary = hr_contract_id.hourly_wage
else:
self.employee_basic_salary = hr_contract_id.wage
if hr_contract_id.date_end:
self.employee_contract_type = 'limited'
employee_working_days = (hr_contract_id.date_end - joining_date).days
self.total_working_years = employee_working_days / 365
self.employee_probation_years = employee_probation_days / 365
employee_gratuity_years = (employee_working_days - employee_probation_days) / 365
self.employee_gratuity_years = employee_gratuity_years
else:
self.employee_contract_type = 'unlimited'
employee_working_days = (current_date - joining_date).days
self.total_working_years = employee_working_days / 365
self.employee_probation_years = employee_probation_days / 365
employee_gratuity_years = (employee_working_days - employee_probation_days) / 365
self.employee_gratuity_years = round(employee_gratuity_years, 2)
gratuity_duration_id = False
hr_accounting_configuration_id = self.env[
'hr.gratuity.accounting.configuration'].search(
[('active', '=', True), ('config_contract_type', '=', self.employee_contract_type),
'|', ('gratuity_end_date', '>=', current_date), ('gratuity_end_date', '=', False),
'|', ('gratuity_start_date', '<=', current_date), ('gratuity_start_date', '=', False)])
if len(hr_accounting_configuration_id) > 1:
raise UserError(_(
"There is a date conflict in Gratuity accounting configuration. "
"Please remove the conflict and try again!"))
elif not hr_accounting_configuration_id:
raise UserError(
_('No gratuity accounting configuration found '
'or please set proper start date and end date for gratuity configuration!'))
# find configuration ids related to the gratuity accounting configuration
self.employee_gratuity_configuration = hr_accounting_configuration_id.id
conf_ids = hr_accounting_configuration_id.gratuity_configuration_table.mapped('id')
hr_duration_config_ids = self.env['gratuity.configuration'].browse(conf_ids)
for duration in hr_duration_config_ids:
if duration.from_year and duration.to_year and duration.from_year <= self.total_working_years <= duration.to_year:
gratuity_duration_id = duration
break
elif duration.from_year and not duration.to_year and duration.from_year <= self.total_working_years:
gratuity_duration_id = duration
break
elif duration.to_year and not duration.from_year and self.total_working_years <= duration.to_year:
gratuity_duration_id = duration
break
if gratuity_duration_id:
self.employee_gratuity_duration = gratuity_duration_id.id
else:
raise Warning(_('No suitable gratuity durations found !'))
# show warning when the employee's working years is less than
# one year or no running employee found.
if self.total_working_years < 1 and self.employee_id.id:
raise Warning(_('Selected Employee is not eligible for Gratuity Settlement'))
self.hr_gratuity_journal = hr_accounting_configuration_id.gratuity_journal.id
self.hr_gratuity_credit_account = hr_accounting_configuration_id.gratuity_credit_account.id
self.hr_gratuity_debit_account = hr_accounting_configuration_id.gratuity_debit_account.id
if self.employee_gratuity_duration and self.wage_type == 'hourly':
if self.employee_gratuity_duration.employee_working_days != 0:
if self.employee_id.resource_calendar_id and self.employee_id.resource_calendar_id.hours_per_day:
daily_wage = self.employee_basic_salary * self.employee_id.resource_calendar_id.hours_per_day
else:
daily_wage = self.employee_basic_salary * 8
working_days_salary = daily_wage * self.employee_gratuity_duration.employee_working_days
gratuity_pay_per_year = working_days_salary * self.employee_gratuity_duration.percentage
employee_gratuity_amount = gratuity_pay_per_year * self.employee_gratuity_years
self.employee_gratuity_amount = round(employee_gratuity_amount, 2)
else:
raise Warning(_("Employee working days is not configured in "
"the gratuity configuration..!"))
elif self.employee_gratuity_duration and self.wage_type == 'monthly':
if self.employee_gratuity_duration.employee_daily_wage_days != 0:
daily_wage = self.employee_basic_salary / self.employee_gratuity_duration.employee_daily_wage_days
working_days_salary = daily_wage * self.employee_gratuity_duration.employee_working_days
gratuity_pay_per_year = working_days_salary * self.employee_gratuity_duration.percentage
employee_gratuity_amount = gratuity_pay_per_year * self.employee_gratuity_years
self.employee_gratuity_amount = round(employee_gratuity_amount, 2)
else:
raise Warning(_("Employee wage days is not configured in "
"the gratuity configuration..!"))
# Changing state to submit
def submit_request(self):
self.write({'state': 'submit'})
# Canceling the gratuity request
def cancel_request(self):
self.write({'state': 'cancel'})
# Set the canceled request to draft
def set_to_draft(self):
self.write({'state': 'draft'})
# function for creating the account move with gratuity amount and
# account credentials
def approved_request(self):
for hr_gratuity_id in self:
debit_vals = {
'name': hr_gratuity_id.employee_id.name,
'account_id': hr_gratuity_id.hr_gratuity_debit_account.id,
'partner_id': hr_gratuity_id.employee_id.address_home_id.id or False,
'journal_id': hr_gratuity_id.hr_gratuity_journal.id,
'date': date.today(),
'debit': hr_gratuity_id.employee_gratuity_amount > 0.0 and hr_gratuity_id.employee_gratuity_amount or 0.0,
'credit': hr_gratuity_id.employee_gratuity_amount < 0.0 and -hr_gratuity_id.employee_gratuity_amount or 0.0,
}
credit_vals = {
'name': hr_gratuity_id.employee_id.name,
'account_id': hr_gratuity_id.hr_gratuity_credit_account.id,
'partner_id': hr_gratuity_id.employee_id.address_home_id.id or False,
'journal_id': hr_gratuity_id.hr_gratuity_journal.id,
'date': date.today(),
'debit': hr_gratuity_id.employee_gratuity_amount < 0.0 and -hr_gratuity_id.employee_gratuity_amount or 0.0,
'credit': hr_gratuity_id.employee_gratuity_amount > 0.0 and hr_gratuity_id.employee_gratuity_amount or 0.0,
}
vals = {
'name': hr_gratuity_id.name + " - " + 'Gratuity for' + ' ' + hr_gratuity_id.employee_id.name,
'narration': hr_gratuity_id.employee_id.name,
'ref': hr_gratuity_id.name,
'partner_id': hr_gratuity_id.employee_id.address_home_id.id or False,
'journal_id': hr_gratuity_id.hr_gratuity_journal.id,
'date': date.today(),
'line_ids': [(0, 0, debit_vals), (0, 0, credit_vals)],
}
move = hr_gratuity_id.env['account.move'].create(vals)
move.post()
self.write({'state': 'approve'})
class EmployeeContractWage(models.Model):
_inherit = 'hr.contract'
# structure_type_id = fields.Many2one('hr.payroll.structure.type', string="Salary Structure Type")
company_country_id = fields.Many2one('res.country', string="Company country", related='company_id.country_id',
readonly=True)
wage_type = fields.Selection([('monthly', 'Monthly Fixed Wage'), ('hourly', 'Hourly Wage')])
hourly_wage = fields.Monetary('Hourly Wage', digits=(16, 2), default=0, required=True, tracking=True,
help="Employee's hourly gross wage.")

View File

@@ -0,0 +1,81 @@
import datetime
from datetime import date
from odoo import models
class LeaveDetails(models.Model):
_inherit = 'hr.leave'
def action_validate(self):
"""
function for calculating leaves and updating
probation period upon the leave days
"""
res = super(LeaveDetails, self).action_validate()
contract = self.env['hr.contract'].search(
[('employee_id', '=', self.employee_id.id),
('state', '=', 'probation')], limit=1)
# check valid contract and probation details.
if contract and contract.probation_id:
training_dtl = contract.probation_id
leave_type = self.env.ref('hr_holidays.holiday_status_unpaid')
no_of_days = 0
leave_info = []
# calculating half day leave :
if self.request_unit_half:
for half in contract.half_leave_ids:
leave_info.append(half.id)
leave_info.append(self.id)
contract.write({'half_leave_ids': leave_info})
if len(contract.half_leave_ids) == 2:
no_of_days = 1
contract.half_leave_ids = False
# calculating full day leaves and updating period :
if self.holiday_status_id.id == leave_type.id \
and contract.state == "probation" and training_dtl and \
not self.request_unit_half and not self.request_unit_hours:
from_date = date(self.request_date_from.year,
self.request_date_from.month,
self.request_date_from.day)
to_date = date(self.request_date_to.year,
self.request_date_to.month,
self.request_date_to.day)
if from_date >= training_dtl.start_date and \
to_date <= training_dtl.end_date:
updated_date = training_dtl.end_date + datetime.timedelta(
days=self.number_of_days)
leave_info = []
for leave in training_dtl.leave_ids:
leave_info.append(leave.id)
leave_info.append(self.id)
training_dtl.write({
'end_date': updated_date,
'state': "extended",
'leave_ids': leave_info
})
contract.write({'trial_date_end': updated_date})
# updating period based on half day leave:
elif self.holiday_status_id.id == leave_type.id \
and contract.state == "probation" and training_dtl \
and self.request_unit_half:
from_date = date(self.request_date_from.year,
self.request_date_from.month,
self.request_date_from.day)
if training_dtl.end_date >= from_date >= training_dtl.start_date:
updated_date = training_dtl.end_date + datetime.timedelta(
days=no_of_days)
for leave in training_dtl.leave_ids:
leave_info.append(leave.id)
leave_info.append(self.id)
training_dtl.write({
'end_date': updated_date,
'state': "extended",
'leave_ids': leave_info
})
contract.write({'trial_date_end': updated_date})
return res

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class TrainingDetails(models.Model):
_name = 'hr.training'
_rec_name = 'employee_id'
_description = 'HR Training'
employee_id = fields.Many2one('hr.employee', string="Employee", help="Employee")
start_date = fields.Date(string="Start Date", help="Probation starting date")
end_date = fields.Date(string="End Date", help="Probation end date")
state = fields.Selection([('new', 'New'), ('extended', 'Extended')], required=True, default='new')
leave_ids = fields.Many2many('hr.leave', string="Leaves")

View File

@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
import datetime
from odoo import fields, models, api, exceptions, _
from odoo.exceptions import ValidationError,UserError
date_format = "%Y-%m-%d"
class OtherSettlements(models.Model):
_name = 'other.settlements'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Settlement"
state = fields.Selection([
('draft', 'Draft'),
('validate', 'Validated'),
('approve', 'Approved'),
('cancel', 'Cancelled'),
], default='draft', track_visibility='onchange')
name = fields.Char(string='Reference', required=True, copy=False, readonly=True,
default=lambda self: _('New'))
employee_id = fields.Many2one('hr.employee', string='Employee', required=True)
joined_date = fields.Date(string="Joined Date")
worked_years = fields.Integer(string="Total Work Years")
last_month_salary = fields.Integer(string="Last Salary", required=True, default=0)
allowance = fields.Char(string="Dearness Allowance", default=0)
gratuity_amount = fields.Integer(string="Gratuity Payable", required=True, default=0, readony=True, help=("Gratuity is calculated based on the equation Last salary * Number of years of service * 15 / 26 "))
reason = fields.Many2one('settlement.reason', string="Settlement Reason", required="True")
currency_id = fields.Many2one('res.currency', string='Currency', required=True,
default=lambda self: self.env.user.company_id.currency_id)
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.user.company_id)
# assigning the sequence for the record
@api.model
def create(self, vals):
vals['name'] = self.env['ir.sequence'].next_by_code('other.settlements')
return super(OtherSettlements, self).create(vals)
# Check whether any Settlement request already exists
@api.onchange('employee_id')
@api.depends('employee_id')
def check_request_existence(self):
for rec in self:
if rec.employee_id:
settlement_request = self.env['other.settlements'].search([('employee_id', '=', rec.employee_id.id),
('state', 'in', ['draft', 'validate', 'approve'])])
if settlement_request:
raise ValidationError(_('A Settlement request is already processed'
' for this employee'))
def validate_function(self):
# calculating the years of work by the employee
worked_years = int(datetime.datetime.now().year) - int(str(self.joined_date).split('-')[0])
if worked_years >= 1:
self.worked_years = worked_years
cr = self._cr # find out the correct date of last salary of employee
query = """select amount from hr_payslip_line psl
inner join hr_payslip ps on ps.id=psl.slip_id
where ps.employee_id="""+str(self.employee_id.id)+\
"""and ps.state='done' and psl.code='NET'
order by ps.date_from desc limit 1"""
cr.execute(query)
data = cr.fetchall()
if data:
last_salary = data[0][0]
else:
last_salary = 0
self.last_month_salary = last_salary
amount = ((self.last_month_salary + int(self.allowance)) * int(worked_years) * 15) / 26
self.gratuity_amount = round(amount) if self.state == 'approve' else 0
self.write({
'state': 'validate'})
else:
self.write({
'state': 'draft'})
self.worked_years = worked_years
raise exceptions.except_orm(_('Employee Working Period is less than 1 Year'),
_('Only an Employee with minimum 1 years of working, will get the Settlement advantage'))
def approve_function(self):
if not self.allowance.isdigit() :
raise ValidationError(_('Allowance value should be numeric !!'))
self.write({
'state': 'approve'
})
amount = ((self.last_month_salary + int(self.allowance)) * int(self.worked_years) * 15) / 26
self.gratuity_amount = round(amount) if self.state == 'approve' else 0
def cancel_function(self):
self.write({
'state': 'cancel'
})
def draft_function(self):
self.write({
'state': 'draft'
})
class SettlementReason(models.Model):
_name = 'settlement.reason'
_rec_name = 'settlement_reason'
settlement_reason = fields.Char(string="Reason",required=True)
description = fields.Text(string="Description")