mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
This will make it possible to be more abstract with 'work_type' or 'worked days lines' and overtime.
159 lines
6.0 KiB
Python
Executable File
159 lines
6.0 KiB
Python
Executable File
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
|
|
|
|
from logging import getLogger
|
|
from sys import float_info as sys_float_info
|
|
from collections import defaultdict
|
|
|
|
from odoo.tests import common
|
|
from odoo.tools.float_utils import float_round as odoo_float_round
|
|
|
|
|
|
def process_payslip(payslip):
|
|
try:
|
|
return payslip.action_payslip_done()
|
|
except AttributeError:
|
|
# v9
|
|
return payslip.process_sheet()
|
|
|
|
|
|
class TestPayslip(common.TransactionCase):
|
|
debug = False
|
|
_logger = getLogger(__name__)
|
|
|
|
def process_payslip(self, payslip=None):
|
|
if not payslip:
|
|
return process_payslip(self.payslip)
|
|
return process_payslip(payslip)
|
|
|
|
def setUp(self):
|
|
super(TestPayslip, self).setUp()
|
|
self.contract_model = self.env['hr.contract']
|
|
self.env.user.tz = 'PST8PDT'
|
|
self.env.ref('resource.resource_calendar_std').tz = 'PST8PDT'
|
|
self.env['ir.config_parameter'].set_param('hr_payroll.payslip.sum_behavior', 'date_to')
|
|
self.structure_type = self.env['hr.payroll.structure.type'].create({
|
|
'name': 'Test Structure Type',
|
|
})
|
|
self.structure = self.env['hr.payroll.structure'].create({
|
|
'name': 'Test Structure',
|
|
'type_id': self.structure_type.id,
|
|
})
|
|
self._log('structue_type %s and structure %s' % (self.structure_type, self.structure))
|
|
self.structure_type.default_struct_id = self.structure
|
|
self.resource_calendar = self.ref('resource.resource_calendar_std')
|
|
|
|
float_info = sys_float_info
|
|
|
|
def float_round(self, value, digits):
|
|
return odoo_float_round(value, digits)
|
|
|
|
_payroll_digits = -1
|
|
|
|
@property
|
|
def payroll_digits(self):
|
|
if self._payroll_digits == -1:
|
|
self._payroll_digits = self.env['decimal.precision'].precision_get('Payroll')
|
|
return self._payroll_digits
|
|
|
|
def _log(self, message):
|
|
if self.debug:
|
|
self._logger.warning(message)
|
|
|
|
def _createEmployee(self):
|
|
return self.env['hr.employee'].create({
|
|
'birthday': '1985-03-14',
|
|
'country_id': self.ref('base.us'),
|
|
'department_id': self.ref('hr.dep_rd'),
|
|
'gender': 'male',
|
|
'name': 'Jared'
|
|
})
|
|
|
|
def _get_contract_defaults(self, contract_values):
|
|
if not contract_values.get('state'):
|
|
contract_values['state'] = 'open' # Running
|
|
if not contract_values.get('structure_type_id'):
|
|
contract_values['structure_type_id'] = self.structure_type.id
|
|
if not contract_values.get('date_start'):
|
|
contract_values['date_start'] = '2016-01-01'
|
|
if not contract_values.get('date_end'):
|
|
contract_values['date_end'] = '2030-12-31'
|
|
if not contract_values.get('resource_calendar_id'):
|
|
contract_values['resource_calendar_id'] = self.resource_calendar
|
|
|
|
# Compatibility with earlier Odoo versions
|
|
if not contract_values.get('journal_id') and hasattr(self.contract_model, 'journal_id'):
|
|
try:
|
|
contract_values['journal_id'] = self.env['account.journal'].search([('type', '=', 'general')], limit=1).id
|
|
except KeyError:
|
|
# Accounting not installed
|
|
pass
|
|
|
|
def _createContract(self, employee, **kwargs):
|
|
if not 'schedule_pay' in kwargs:
|
|
kwargs['schedule_pay'] = 'monthly'
|
|
schedule_pay = kwargs['schedule_pay']
|
|
contract_values = {
|
|
'name': 'Test Contract',
|
|
'employee_id': employee.id,
|
|
}
|
|
|
|
for key, val in kwargs.items():
|
|
# Assume any Odoo object is in a Many2one
|
|
if hasattr(val, 'id'):
|
|
val = val.id
|
|
found = False
|
|
if hasattr(self.contract_model, key):
|
|
contract_values[key] = val
|
|
found = True
|
|
if not found:
|
|
self._logger.warn('cannot locate attribute names "%s" on hr.contract().' % (key, ))
|
|
|
|
self._get_contract_defaults(contract_values)
|
|
contract = self.contract_model.create(contract_values)
|
|
|
|
# Compatibility with Odoo 14
|
|
contract.structure_type_id.default_struct_id.schedule_pay = schedule_pay
|
|
return contract
|
|
|
|
def _createPayslip(self, employee, date_from, date_to, skip_compute=False):
|
|
slip = self.env['hr.payslip'].create({
|
|
'name': 'Test %s From: %s To: %s' % (employee.name, date_from, date_to),
|
|
'employee_id': employee.id,
|
|
'date_from': date_from,
|
|
'date_to': date_to
|
|
})
|
|
# Included in hr.payslip.action_refresh_from_work_entries() as ov 14.0 EE
|
|
# slip._onchange_employee()
|
|
# as is the 'compute' that is almost always called immediaately after
|
|
if not skip_compute:
|
|
slip.action_refresh_from_work_entries()
|
|
return slip
|
|
|
|
def _getCategories(self, payslip):
|
|
categories = defaultdict(float)
|
|
for line in payslip.line_ids:
|
|
self._log(' line code: ' + str(line.code) +
|
|
' category code: ' + line.category_id.code +
|
|
' total: ' + str(line.total) +
|
|
' rate: ' + str(line.rate) +
|
|
' amount: ' + str(line.amount))
|
|
category_id = line.category_id
|
|
category_code = line.category_id.code
|
|
while category_code:
|
|
categories[category_code] += line.total
|
|
category_id = category_id.parent_id
|
|
category_code = category_id.code
|
|
return categories
|
|
|
|
def _getRules(self, payslip):
|
|
rules = defaultdict(float)
|
|
for line in payslip.line_ids:
|
|
rules[line.code] += line.total
|
|
return rules
|
|
|
|
def assertPayrollEqual(self, first, second):
|
|
self.assertAlmostEqual(first, second, self.payroll_digits)
|
|
|
|
def assertPayrollAlmostEqual(self, first, second):
|
|
self.assertAlmostEqual(first, second, self.payroll_digits-1)
|