Initial commit
This commit is contained in:
178
fusion_payroll/models/payroll_report_employee.py
Normal file
178
fusion_payroll/models/payroll_report_employee.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Employee Reports
|
||||
================
|
||||
- Employee Directory (Payroll Item List)
|
||||
- Time Off Report
|
||||
"""
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class PayrollReportEmployeeDirectory(models.AbstractModel):
|
||||
"""
|
||||
Employee Directory / Payroll Item List Report
|
||||
Shows employees with their pay rates and status.
|
||||
"""
|
||||
_name = 'payroll.report.employee.directory'
|
||||
_inherit = 'payroll.report'
|
||||
_description = 'Employee Directory Report'
|
||||
|
||||
report_name = 'Payroll Item List'
|
||||
report_code = 'employee_directory'
|
||||
filter_date_range = False # Not date-dependent
|
||||
filter_employee = False
|
||||
|
||||
def _get_columns(self):
|
||||
return [
|
||||
{'name': _('Name'), 'field': 'name', 'type': 'char', 'sortable': True},
|
||||
{'name': _('Salary'), 'field': 'salary', 'type': 'monetary', 'sortable': True},
|
||||
{'name': _('Regular Pay'), 'field': 'regular_pay', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Hourly 2'), 'field': 'hourly_2', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Overtime Pay'), 'field': 'overtime_pay', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Double Overtime Pay'), 'field': 'double_overtime', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Stat Holiday Pay'), 'field': 'stat_holiday', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Bonus'), 'field': 'bonus', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Status'), 'field': 'status', 'type': 'char', 'sortable': True},
|
||||
]
|
||||
|
||||
def _get_lines(self, options):
|
||||
# Get all employees
|
||||
employees = self.env['hr.employee'].search([
|
||||
('company_id', '=', self.env.company.id),
|
||||
], order='name')
|
||||
|
||||
lines = []
|
||||
for emp in employees:
|
||||
# Get pay info directly from employee (Fusion Payroll fields)
|
||||
salary = ''
|
||||
regular_pay = ''
|
||||
|
||||
# Use Fusion Payroll fields if available
|
||||
pay_type = getattr(emp, 'pay_type', None)
|
||||
if pay_type == 'salary':
|
||||
salary_amount = getattr(emp, 'salary_amount', 0) or 0
|
||||
if salary_amount:
|
||||
salary = f"${salary_amount * 12:,.2f}/year"
|
||||
elif pay_type == 'hourly':
|
||||
hourly_rate = getattr(emp, 'hourly_rate', 0) or 0
|
||||
if hourly_rate:
|
||||
regular_pay = f"${hourly_rate:,.2f}/hr"
|
||||
else:
|
||||
# Fallback to hourly_cost if available
|
||||
hourly_cost = getattr(emp, 'hourly_cost', 0) or 0
|
||||
if hourly_cost:
|
||||
regular_pay = f"${hourly_cost:,.2f}/hr"
|
||||
|
||||
status = 'Active'
|
||||
if hasattr(emp, 'employment_status') and 'employment_status' in emp._fields:
|
||||
if hasattr(emp._fields['employment_status'], 'selection'):
|
||||
status = dict(emp._fields['employment_status'].selection).get(
|
||||
emp.employment_status, 'Active'
|
||||
)
|
||||
|
||||
# Calculate salary value for sorting
|
||||
salary_value = 0
|
||||
if pay_type == 'salary':
|
||||
salary_value = (getattr(emp, 'salary_amount', 0) or 0) * 12
|
||||
|
||||
lines.append({
|
||||
'id': f'emp_{emp.id}',
|
||||
'name': emp.name,
|
||||
'values': {
|
||||
'name': emp.name,
|
||||
'salary': salary_value if salary_value else '',
|
||||
'regular_pay': regular_pay,
|
||||
'hourly_2': '',
|
||||
'overtime_pay': '',
|
||||
'double_overtime': '',
|
||||
'stat_holiday': '',
|
||||
'bonus': '',
|
||||
'status': status,
|
||||
},
|
||||
'level': 0,
|
||||
'model': 'hr.employee',
|
||||
'res_id': emp.id,
|
||||
})
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
class PayrollReportTimeOff(models.AbstractModel):
|
||||
"""
|
||||
Time Off Report
|
||||
Shows vacation/leave balances by employee.
|
||||
"""
|
||||
_name = 'payroll.report.time.off'
|
||||
_inherit = 'payroll.report'
|
||||
_description = 'Time Off Report'
|
||||
|
||||
report_name = 'Time Off'
|
||||
report_code = 'time_off'
|
||||
filter_date_range = False
|
||||
|
||||
def _get_columns(self):
|
||||
return [
|
||||
{'name': _('Employee'), 'field': 'employee', 'type': 'char', 'sortable': True},
|
||||
{'name': _('Vacation'), 'field': 'vacation', 'type': 'char', 'sortable': False},
|
||||
{'name': _('Balance'), 'field': 'balance', 'type': 'float', 'sortable': True},
|
||||
{'name': _('YTD Used'), 'field': 'ytd_used', 'type': 'float', 'sortable': True},
|
||||
{'name': _('Amount Available'), 'field': 'amount_available', 'type': 'monetary', 'sortable': True},
|
||||
{'name': _('YTD Amount Used'), 'field': 'ytd_amount_used', 'type': 'monetary', 'sortable': True},
|
||||
]
|
||||
|
||||
def _get_lines(self, options):
|
||||
# Get employees with vacation policy
|
||||
domain = [('company_id', '=', self.env.company.id)]
|
||||
if 'employment_status' in self.env['hr.employee']._fields:
|
||||
domain.append(('employment_status', '=', 'active'))
|
||||
employees = self.env['hr.employee'].search(domain, order='name')
|
||||
|
||||
lines = []
|
||||
for emp in employees:
|
||||
# Try to get leave allocation info if hr_holidays is installed
|
||||
balance = 0
|
||||
ytd_used = 0
|
||||
|
||||
try:
|
||||
# Check for vacation allocations
|
||||
allocations = self.env['hr.leave.allocation'].search([
|
||||
('employee_id', '=', emp.id),
|
||||
('state', '=', 'validate'),
|
||||
('holiday_status_id.name', 'ilike', 'vacation'),
|
||||
])
|
||||
balance = sum(allocations.mapped('number_of_days'))
|
||||
|
||||
# Get used days this year
|
||||
year_start = fields.Date.today().replace(month=1, day=1)
|
||||
leaves = self.env['hr.leave'].search([
|
||||
('employee_id', '=', emp.id),
|
||||
('state', '=', 'validate'),
|
||||
('holiday_status_id.name', 'ilike', 'vacation'),
|
||||
('date_from', '>=', year_start),
|
||||
])
|
||||
ytd_used = sum(leaves.mapped('number_of_days'))
|
||||
except:
|
||||
pass # hr_holidays may not be installed or different structure
|
||||
|
||||
# Get vacation pay rate from employee
|
||||
vacation_rate = getattr(emp, 'vacation_pay_rate', 4.0)
|
||||
vacation_policy = f"{vacation_rate}% Paid out each pay period"
|
||||
|
||||
lines.append({
|
||||
'id': f'time_{emp.id}',
|
||||
'name': emp.name,
|
||||
'values': {
|
||||
'employee': emp.name,
|
||||
'vacation': vacation_policy,
|
||||
'balance': balance - ytd_used,
|
||||
'ytd_used': ytd_used,
|
||||
'amount_available': 0, # Would need to calculate
|
||||
'ytd_amount_used': 0,
|
||||
},
|
||||
'level': 0,
|
||||
'model': 'hr.employee',
|
||||
'res_id': emp.id,
|
||||
})
|
||||
|
||||
return lines
|
||||
Reference in New Issue
Block a user