trytonpsk-staff_payroll/wage_type.py

143 lines
5.5 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Not, Bool, Eval, If
from trytond.transaction import Transaction
__all__ = ['WageType', 'WageTypeSalary']
STATES = {'readonly': Not(Bool(Eval('active'))),}
class WageType(ModelSQL, ModelView):
"Wage Type"
__name__ = "staff.wage_type"
name = fields.Char('Name', select=True, required=True)
sequence = fields.Integer('Sequence', select=True)
code = fields.Char('Code', select=True)
active = fields.Boolean('Active')
company = fields.Many2One('company.company', 'Company', required=True,
domain=[
('id', If(Eval('context', {}).contains('company'), '=', '!='),
Eval('context', {}).get('company', 0)),
])
definition = fields.Selection([
('payment', 'Payment'),
('discount', 'Discount'),
('deduction', 'Deduction'),
], 'Definition', required=True)
unit_price_formula = fields.Char('Unit Price Formula',
help='Python expression for eval(expr)')
expense_formula = fields.Char('Expense Formula',
help='Python expression for eval(expr)')
uom = fields.Many2One('product.uom', 'UOM', required=True)
default_quantity = fields.Numeric('Default Quantity', digits=(16, 2))
type_concept = fields.Selection([
('salary', 'Salary'),
('extras', 'Extras'),
('other', 'Other'),
('special', 'Special'),
('', ''),
], 'Type Concept')
salary_constitute = fields.Boolean('Salary Constitute',
select=True,
states={
'invisible': Eval('definition') != 'payment',
})
debit_account = fields.Many2One('account.account',
'Debit Account', domain=[
('kind', 'in', ['expense', 'payable', 'receivable']),
('company', '=', Eval('context', {}).get('company', 0))],
states={
'invisible': ~Eval('context', {}).get('company'),
})
credit_account = fields.Many2One('account.account',
'Credit Account', domain=[
('kind', 'in', ['expense', 'payable', 'receivable']),
('company', '=', Eval('context', {}).get('company', 0))],
states={
'invisible': ~Eval('context', {}).get('company'),
})
deduction_account = fields.Many2One('account.account',
'Deduction Account', domain=[
('kind', '!=', 'view'),
('company', '=', Eval('context', {}).get('company', 0))],
states={
'invisible': Eval('definition') == 'payment',
'required': Eval('definition') != 'payment',
}, depends=['definition'])
receipt = fields.Boolean('Receipt', select=True)
parent = fields.Many2One('staff.wage_type', 'Parent', select=True)
concepts_salary = fields.Many2Many('staff.wage_type-staff.wage_type',
'parent', 'child', 'Concepts Salary')
contract_finish = fields.Boolean('Contract Finish', select=True)
party_required = fields.Boolean('Party Required', select=True)
amount_required = fields.Boolean('Amount Required', select=True)
limit_days = fields.Numeric('Limit Days', digits=(4, 0), states={
'invisible': Eval('type_concept') != 'special',
'required': Eval('type_concept') == 'special',
})
@classmethod
def __setup__(cls):
super(WageType, cls).__setup__()
cls._error_messages.update({
'invalid_formula': 'Invalid formula [ %s ] for unit price!',
})
cls._order.insert(0, ('sequence', 'ASC'))
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def validate(cls, wage_types):
super(WageType, cls).validate(wage_types)
for wage in wage_types:
test_salary = {'salary': 1000}
if wage.unit_price_formula:
wage.compute_unit_price(test_salary)
if wage.expense_formula:
wage.compute_expense(test_salary)
@staticmethod
def default_unit_price_formula():
return 'salary'
@staticmethod
def default_active():
return True
def compute_unit_price(self, args):
return self.compute_formula('unit_price_formula', args)
def compute_expense(self, args):
return self.compute_formula('expense_formula', args)
def compute_formula(self, formula, args=None):
'''
Compute a formula field with a salary value as float
:return: A decimal
'''
formula = getattr(self, formula)
if not formula:
return Decimal('0.0')
if args.get('salary') != None:
salary = float(args['salary'])
try:
value = Decimal(str(round(eval(formula), 2)))
return value
except Exception:
self.raise_user_error('invalid_formula', formula)
class WageTypeSalary(ModelSQL):
"Wage Type Salary"
__name__ = "staff.wage_type-staff.wage_type"
_table = 'staff_wage_type_salary_rel'
parent = fields.Many2One('staff.wage_type', 'Parent', ondelete='CASCADE',
select=True, required=True)
child = fields.Many2One('staff.wage_type', 'Child', ondelete='RESTRICT',
select=True, required=True)