You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
5.3 KiB
126 lines
5.3 KiB
# -*- coding: utf-8 -*-
|
|
|
|
import itertools
|
|
from odoo import models, fields, api
|
|
|
|
|
|
class PayrollStructure(models.Model):
|
|
_inherit = 'hr.payroll.structure'
|
|
|
|
timesheet_structure = fields.Boolean(string='Timesheet Based Structure', default=False,
|
|
help='Flag Which says the Structure is based on Timesheets submitted by employee')
|
|
|
|
|
|
class HrContract(models.Model):
|
|
_inherit = 'hr.contract'
|
|
|
|
timesheet_payroll = fields.Boolean(string='Timesheet Based Payroll', default=False,
|
|
help='Flag Which says the payroll is based on Timesheets submitted by employee')
|
|
|
|
@api.onchange('timesheet_payroll')
|
|
def onchange_timesheet_payroll(self):
|
|
if self.timesheet_payroll:
|
|
self.struct_id = False
|
|
return {
|
|
'domain': {
|
|
'struct_id': [('timesheet_structure', '=', True)]
|
|
},
|
|
}
|
|
else:
|
|
return {
|
|
'domain': {'struct_id': []},
|
|
}
|
|
|
|
|
|
class HrPayslip(models.Model):
|
|
_inherit = 'hr.payslip'
|
|
|
|
timesheet_hours = fields.Integer(string='Timesheet Hours', states={'done': [('readonly', True)]},
|
|
help='Total Timesheet hours approved for employee.')
|
|
total_hours = fields.Integer(string='Total Hours', states={'done': [('readonly', True)]},
|
|
help='Total Hours By Working schedule')
|
|
timesheet_payroll = fields.Boolean(related='contract_id.timesheet_payroll')
|
|
|
|
def compute_timesheet_hours(self, contract_id, date_from, date_to):
|
|
"""
|
|
Function which computes total hours, timesheethours, attendances, timehseet difference,
|
|
:param employee_id:
|
|
:param date_from:
|
|
:param date_to:
|
|
:return: computed total timesheet hours within duration, total hours by working schedule
|
|
"""
|
|
if not contract_id:
|
|
return {}
|
|
env = self.env
|
|
employee_id = contract_id.employee_id
|
|
timesheet_object = env['hr_timesheet_sheet.sheet']
|
|
total_hours = 0.0
|
|
timesheet_hours = timesheet_attendance = timesheet_difference = 0.0
|
|
for line in self.worked_days_line_ids:
|
|
total_hours += line.number_of_hours if line.code == 'WORK100' else 0.0
|
|
sheets = timesheet_object.search([
|
|
('employee_id', '=', employee_id.id),
|
|
('date_from', '>=', date_from),
|
|
('date_to', '<=', date_to),
|
|
('state', '=', 'done')
|
|
|
|
])
|
|
period_ids = []
|
|
period_ids += [sheet.period_ids.ids for sheet in sheets]
|
|
period_ids = list(itertools.chain.from_iterable(period_ids))
|
|
if len(period_ids):
|
|
self.env.cr.execute("""
|
|
SELECT
|
|
sum(total_attendance) as total_attendance,
|
|
sum(total_timesheet) as total_timesheet,
|
|
sum(total_difference) as total_difference
|
|
FROM hr_timesheet_sheet_sheet_day
|
|
WHERE id IN %s
|
|
""", (tuple(period_ids),))
|
|
data = self.env.cr.dictfetchall()
|
|
for x in data:
|
|
timesheet_hours = x.pop('total_timesheet')
|
|
timesheet_attendance = x.pop('total_attendance')
|
|
timesheet_difference = x.pop('total_difference')
|
|
|
|
return {
|
|
'timesheet_hours': timesheet_hours,
|
|
'timesheet_attendance': timesheet_attendance,
|
|
'timesheet_difference': timesheet_difference,
|
|
'total_hours': total_hours,
|
|
}
|
|
|
|
@api.onchange('employee_id', 'date_from')
|
|
def onchange_employee(self):
|
|
super(HrPayslip, self).onchange_employee()
|
|
if self.contract_id.timesheet_payroll:
|
|
datas = self.compute_timesheet_hours(self.contract_id, self.date_from, self.date_to)
|
|
self.timesheet_hours = datas.get('timesheet_hours') or 0.0
|
|
self.total_hours = datas.get('total_hours') or 0.0
|
|
return
|
|
|
|
@api.model
|
|
def get_payslip_lines(self, contract_ids, payslip_id):
|
|
class BrowsableObject(object):
|
|
def __init__(self, employee_id, dict):
|
|
self.employee_id = employee_id
|
|
self.dict = dict
|
|
|
|
def __getattr__(self, attr):
|
|
return attr in self.dict and self.dict.__getitem__(attr) or 0.0
|
|
class Payslips(BrowsableObject):
|
|
"""a class that will be used into the python code, mainly for usability purposes"""
|
|
|
|
def sum(self, code, from_date, to_date=None):
|
|
if to_date is None:
|
|
to_date = fields.Date.today()
|
|
self.env.cr.execute("""SELECT sum(case when hp.credit_note = False then (pl.total) else (-pl.total) end)
|
|
FROM hr_payslip as hp, hr_payslip_line as pl
|
|
WHERE hp.employee_id = %s AND hp.state = 'done'
|
|
AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s""",
|
|
(self.employee_id, from_date, to_date, code))
|
|
res = self.env.cr.fetchone()
|
|
return res and res[0] or 0.0
|
|
timesheet_hours = self.timesheet_hours
|
|
total_hours = self.total_hours
|
|
return super(HrPayslip, self).get_payslip_lines(contract_ids, payslip_id)
|