Release v6.0

This commit is contained in:
wilson gomez 2021-06-04 16:04:40 -05:00
parent 3364169673
commit 8b4648f6f3
16 changed files with 219 additions and 130 deletions

View File

@ -1,41 +1,40 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of #This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms. #this repository contains the full copyright notices and license terms.
from trytond.pool import Pool from trytond.pool import Pool
from .period import Period, OpenPeriod from . import period
from .wage_type import WageType, WageTypeSalary from . import wage_type
from .payroll import Payroll, PayrollLine, PayrollGroupStart, \ from . import payroll
PayrollGroup, PayrollReport, Move, PayrollRecompute, PayrollPreliquidation from . import category
from .category import CategoryWagesDefault, EmployeeCategory from . import employee
from .employee import Employee, MandatoryWage, CreateMandatoryWages from . import configuration
from .configuration import StaffConfigurationSequence, StaffConfiguration from . import position
from .position import Position, WorkdayDefinition
def register(): def register():
Pool.register( Pool.register(
Position, position.Position,
WorkdayDefinition, position.WorkdayDefinition,
Period, period.Period,
WageType, wage_type.WageType,
MandatoryWage, employee.MandatoryWage,
EmployeeCategory, category.EmployeeCategory,
Employee, employee.Employee,
Payroll, payroll.Payroll,
PayrollLine, payroll.PayrollLine,
CategoryWagesDefault, category.CategoryWagesDefault,
PayrollGroupStart, payroll.PayrollGroupStart,
StaffConfigurationSequence, configuration.StaffConfigurationSequence,
StaffConfiguration, configuration.StaffConfiguration,
WageTypeSalary, wage_type.WageTypeSalary,
Move, payroll.Move,
module='staff_payroll', type_='model') module='staff_payroll', type_='model')
Pool.register( Pool.register(
PayrollReport, payroll.PayrollReport,
module='staff_payroll', type_='report') module='staff_payroll', type_='report')
Pool.register( Pool.register(
OpenPeriod, period.OpenPeriod,
PayrollGroup, payroll.PayrollGroup,
CreateMandatoryWages, employee.CreateMandatoryWages,
PayrollPreliquidation, payroll.PayrollPreliquidation,
PayrollRecompute, payroll.PayrollRecompute,
module='staff_payroll', type_='wizard') module='staff_payroll', type_='wizard')

View File

@ -2,8 +2,6 @@
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields from trytond.model import ModelView, ModelSQL, fields
__all__ = ['EmployeeCategory', 'CategoryWagesDefault']
class EmployeeCategory(ModelSQL, ModelView): class EmployeeCategory(ModelSQL, ModelView):
'Employee Category' 'Employee Category'

View File

@ -3,12 +3,9 @@
from trytond import backend from trytond import backend
from trytond.model import fields from trytond.model import fields
from trytond.pool import PoolMeta, Pool from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval from trytond.pyson import Eval, Id
from trytond.tools.multivalue import migrate_property from trytond.tools.multivalue import migrate_property
__all__ = ['StaffConfiguration', 'StaffConfigurationSequence']
def default_func(field_name): def default_func(field_name):
@classmethod @classmethod
@ -19,12 +16,12 @@ def default_func(field_name):
return default return default
class StaffConfiguration: class StaffConfiguration(metaclass=PoolMeta):
__metaclass__ = PoolMeta
__name__ = 'staff.configuration' __name__ = 'staff.configuration'
staff_payroll_sequence = fields.MultiValue(fields.Many2One('ir.sequence', staff_payroll_sequence = fields.MultiValue(fields.Many2One('ir.sequence',
'Payroll Sequence', required=True, domain=[ 'Payroll Sequence', required=True, domain=[
('code', '=', 'staff.payroll')]) ('sequence_type', '=',
Id('staff_payroll', 'sequence_type_payroll'))])
) )
default_hour_workday = fields.Integer('Default Hour Workday', default_hour_workday = fields.Integer('Default Hour Workday',
required=True, help='In hours') required=True, help='In hours')
@ -48,22 +45,19 @@ class StaffConfiguration:
return super(StaffConfiguration, cls).multivalue_model(field) return super(StaffConfiguration, cls).multivalue_model(field)
class StaffConfigurationSequence: class StaffConfigurationSequence(metaclass=PoolMeta):
__metaclass__ = PoolMeta
__name__ = 'staff.configuration.sequence' __name__ = 'staff.configuration.sequence'
staff_payroll_sequence = fields.Many2One( staff_payroll_sequence = fields.Many2One(
'ir.sequence', "Staff Payroll Sequence", required=True, 'ir.sequence', "Staff Payroll Sequence", required=True,
domain=[ domain=[
('company', 'in', [Eval('company', -1), None]), ('company', 'in', [Eval('company', -1), None]),
('code', '=', 'staff.payroll'), ('sequence_type', '=', Id('staff_payroll', 'sequence_type_payroll')),
], ],
depends=['company']) depends=['company'])
@classmethod @classmethod
def __register__(cls, module_name): def __register__(cls, module_name):
TableHandler = backend.get('TableHandler') exist = backend.TableHandler.table_exist(cls._table)
exist = TableHandler.table_exist(cls._table)
super(StaffConfigurationSequence, cls).__register__(module_name) super(StaffConfigurationSequence, cls).__register__(module_name)
if not exist: if not exist:

View File

@ -10,9 +10,23 @@ this repository contains the full copyright notices and license terms. -->
<field name="name">configuration_form</field> <field name="name">configuration_form</field>
</record> </record>
<record model="ir.sequence.type" id="sequence_type_payroll">
<field name="name">Staff Payroll</field>
</record>
<record model="ir.sequence" id="sequence_staff_payroll"> <record model="ir.sequence" id="sequence_staff_payroll">
<field name="name">Payroll</field> <field name="name">Staff Payroll</field>
<field name="code">staff.payroll</field> <field name="sequence_type" ref="sequence_type_payroll"/>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_payroll_group_admin">
<field name="sequence_type" ref="sequence_type_payroll"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_payroll_group_staff_admin">
<field name="sequence_type" ref="sequence_type_payroll"/>
<field name="group" ref="staff.group_staff_admin"/>
</record> </record>
</data> </data>

View File

@ -6,8 +6,8 @@ from trytond.transaction import Transaction
from trytond.pyson import Not, Bool, Eval, If from trytond.pyson import Not, Bool, Eval, If
from trytond.wizard import Wizard, StateTransition from trytond.wizard import Wizard, StateTransition
from datetime import datetime, date from datetime import datetime, date
from trytond.i18n import gettext
__all__ = ['Employee', 'MandatoryWage', 'CreateMandatoryWages'] from .exceptions import (MissingPartyWageType)
class Employee(metaclass=PoolMeta): class Employee(metaclass=PoolMeta):
@ -19,9 +19,6 @@ class Employee(metaclass=PoolMeta):
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(Employee, cls).__setup__() super(Employee, cls).__setup__()
cls._error_messages.update({
'no_bank_accounts': ('The employee does not have banks!'),
})
def get_fix_amount_wage_type(self, wage_id): def get_fix_amount_wage_type(self, wage_id):
fix_amount = sum([w.fix_amount or 0 for w in self.mandatory_wages if w.wage_type.id == wage_id]) fix_amount = sum([w.fix_amount or 0 for w in self.mandatory_wages if w.wage_type.id == wage_id])
@ -51,9 +48,6 @@ class MandatoryWage(ModelSQL, ModelView):
def __setup__(cls): def __setup__(cls):
super(MandatoryWage, cls).__setup__() super(MandatoryWage, cls).__setup__()
cls._order.insert(0, ('id', 'ASC')) cls._order.insert(0, ('id', 'ASC'))
cls._error_messages.update({
'party_required': ('Error the wage type %s does not have party!'),
})
@classmethod @classmethod
def validate(cls, mandatoryWages): def validate(cls, mandatoryWages):
@ -70,7 +64,8 @@ class MandatoryWage(ModelSQL, ModelView):
if wages: if wages:
for wage in wages: for wage in wages:
if wage.party_required and not self.party: if wage.party_required and not self.party:
self.raise_user_error('party_required', wage.name) raise MissingPartyWageType(
gettext('staff_payroll.msg_party_required', wage=wage.name))
class CreateMandatoryWages(Wizard): class CreateMandatoryWages(Wizard):

74
exceptions.py Normal file
View File

@ -0,0 +1,74 @@
# 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 trytond.exceptions import UserError, UserWarning
from trytond.model.exceptions import ValidationError
class WageTypeValidationError(ValidationError):
pass
class MissingPartyWageType(WageTypeValidationError):
pass
class PayrollDeleteError(ValidationError):
pass
class PayrollExistPeriodError(UserError):
pass
class PayrollPeriodCloseError(ValidationError):
pass
class PayrollMissingSequence(ValidationError):
pass
class PayrollValidationError(UserError):
pass
class PeriodValidationError(UserError):
pass
class MissingConfigPosition(UserError):
pass
# class DontWriteAccountError(UserError):
# pass
#
#
# class MissingInvoiceTaxError(UserError):
# pass
#
#
# class InvoiceDuplicatedError(UserError):
# pass
#
#
# class NotificationAuthError(UserError):
# pass
#
#
# class NotificationAuthWarning(UserWarning):
# pass
#
#
# class AuthExpiredError(UserError):
# pass
#
#
# class InvalidTypeInvoiceError(UserError):
# pass
#
#
# class ImportMoveDataError(UserError):
# pass
# class AccountMoveCreatedError(UserWarning):
# pass

55
message.xml Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data grouped="1">
<record model="ir.message" id="msg_no_bank_accounts">
<field name="text"The employee does not have banks!</field>
</record>
<record model="ir.message" id="msg_party_required">
<field name="text">Error the wage type "%(wage)" does not have party!</field>
</record>
<record model="ir.message" id="msg_employee_without_salary">
<field name="text">The employee does not have salary!</field>
</record>
<record model="ir.message" id="msg_wrong_start_end">
<field name="text">The date end can not smaller than date start, for employee "%(employee)"</field>
</record>
<record model="ir.message" id="msg_sequence_missing">
<field name="text">Sequence Payroll is missing!</field>
</record>
<record model="ir.message" id="msg_period_closed">
<field name="text">Payroll period is closed!</field>
</record>
<record model="ir.message" id="msg_payroll_exist_period">
<field name="text">Already exist one payroll in this period with this contract!</field>
</record>
<record model="ir.message" id="msg_wrong_date_consistent">
<field name="text">The date start/end is repetead
or crossed with other date payroll</field>
</record>
<record model="ir.message" id="msg_delete_cancel">
<field name="text">Payroll "%(payroll)" must be cancelled before deletion.</field>
</record>
<record model="ir.message" id="msg_existing_move">
<field name="text">Payroll "%(payroll)" has a move, must be deleted before deletion.</field>
</record>
<record model="ir.message" id="msg_bad_configuration_wage_type">
<field name="text">Bad configuration of the wage type "%(wage)".</field>
</record>
<record model="ir.message" id="msg_wrong_start_end">
<field name="text">The date end can not smaller than date start.</field>
</record>
<record model="ir.message" id="msg_wrong_period_overlap">
<field name="text">The period overlap another period!.</field>
</record>
<record model="ir.message" id="msg_missing_config_default">
<field name="text">Missing default values for workday or restday on configuration!</field>
</record>
<record model="ir.message" id="msg_invalid_formula">
<field name="text">Invalid formula [ %formula ] for unit price!</field>
</record>
</data>
</tryton>

View File

@ -9,11 +9,10 @@ from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.modules.company import CompanyReport from trytond.modules.company import CompanyReport
from trytond.wizard import Wizard, StateView, StateTransition, Button from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.i18n import gettext
__all__ = [ from .exceptions import (PayrollDeleteError, PayrollPeriodCloseError,
'Payroll', 'PayrollLine', 'PayrollReport', 'Move', 'PayrollGroupStart', PayrollExistPeriodError, PayrollMissingSequence, WageTypeValidationError,
'PayrollGroup', 'PayrollPreliquidation', 'PayrollRecompute' PayrollValidationError)
]
STATES = {'readonly': (Eval('state') != 'draft')} STATES = {'readonly': (Eval('state') != 'draft')}
@ -102,20 +101,6 @@ class Payroll(Workflow, ModelSQL, ModelView):
('period', 'DESC'), ('period', 'DESC'),
('start', 'DESC'), ('start', 'DESC'),
] ]
cls._error_messages.update({
'employee_without_salary': ('The employee does not have salary!'),
'wrong_start_end': ('The date end can not smaller than date start, for employee %s'),
'sequence_missing': ('Sequence Payroll is missing!'),
'period_closed': ('Payroll period is closed!'),
'payroll_exist_period': ('Already exist one payroll in this period with this contract!'),
'wrong_date_consistent': ('The date start/end is repetead \
or crossed with other date payroll'),
'delete_cancel': ('Payroll "%s" must be cancelled before '
'deletion.'),
'existing_move': ('Payroll "%s" has a move, must be deleted '
'before deletion.'),
'bad_configuration_wage_type': ('Bad configuration of the wage type "%s".'),
})
cls._transitions |= set(( cls._transitions |= set((
('draft', 'cancel'), ('draft', 'cancel'),
('cancel', 'draft'), ('cancel', 'draft'),
@ -176,9 +161,11 @@ class Payroll(Workflow, ModelSQL, ModelView):
cls.cancel(records) cls.cancel(records)
for payroll in records: for payroll in records:
if payroll.state != 'cancel': if payroll.state != 'cancel':
cls.raise_user_error('delete_cancel', (payroll.rec_name,)) raise PayrollDeleteError(
gettext('staff_payroll.msg_delete_cancel', payroll=payroll.rec_name))
if payroll.move: if payroll.move:
cls.raise_user_error('existing_move', (payroll.rec_name,)) raise PayrollDeleteError(
gettext('staff_payroll.msg_existing_move', payroll=payroll.rec_name))
super(Payroll, cls).delete(records) super(Payroll, cls).delete(records)
@classmethod @classmethod
@ -223,11 +210,9 @@ class Payroll(Workflow, ModelSQL, ModelView):
('kind', '=', 'normal'), ('kind', '=', 'normal'),
]) ])
if len(payrolls) > 1: if len(payrolls) > 1:
cls.raise_user_error('payroll_exist_period',) raise PayrollExistPeriodError(gettext('staff_payroll.msg_payroll_exist_period'))
return
if payroll.period.state == 'closed': if payroll.period.state == 'closed':
cls.raise_user_error('period_closed',) raise PayrollPeriodCloseError(gettext('staff_payroll.msg_period_closed'))
return
payroll.set_number() payroll.set_number()
@classmethod @classmethod
@ -260,13 +245,12 @@ class Payroll(Workflow, ModelSQL, ModelView):
if self.number: if self.number:
return return
pool = Pool() pool = Pool()
Sequence = pool.get('ir.sequence')
Configuration = pool.get('staff.configuration') Configuration = pool.get('staff.configuration')
configuration = Configuration(1) configuration = Configuration(1)
if not configuration.staff_payroll_sequence: if not configuration.staff_payroll_sequence:
self.raise_user_error('sequence_missing',) raise PayrollMissingSequence(gettext('msg_sequence_missing'))
seq = configuration.staff_payroll_sequence.id seq = configuration.staff_payroll_sequence.get()
self.write([self], {'number': Sequence.get_id(seq)}) self.write([self], {'number': seq})
@fields.depends('start', 'end') @fields.depends('start', 'end')
def on_change_with_worked_days(self, name=None): def on_change_with_worked_days(self, name=None):
@ -393,7 +377,8 @@ class Payroll(Workflow, ModelSQL, ModelView):
if credit_acc and not line_credit_ready: if credit_acc and not line_credit_ready:
lines_moves[credit_acc.id][party.id]['credit'] += amount_credit lines_moves[credit_acc.id][party.id]['credit'] += amount_credit
except: except:
self.raise_user_error('bad_configuration_wage_type', line.wage_type.name) raise WageTypeValidationError(
gettext('staff_payroll.bad_configuration_wage_type', wage=line.wage_type.name))
result = [] result = []
for r in lines_moves.values(): for r in lines_moves.values():
@ -549,7 +534,8 @@ class Payroll(Workflow, ModelSQL, ModelView):
if self.start >= self.period.start and \ if self.start >= self.period.start and \
self.end is None: self.end is None:
return return
self.raise_user_error('wrong_start_end', self.employee.party.name) raise PayrollValidationError(
gettext('staff_payroll.msg_wrong_start_end', employee=self.employee.party.name))
@fields.depends('period', 'start', 'end', 'employee') @fields.depends('period', 'start', 'end', 'employee')
def on_change_period(self): def on_change_period(self):
@ -746,8 +732,8 @@ class PayrollReport(CompanyReport):
__name__ = 'staff.payroll' __name__ = 'staff.payroll'
@classmethod @classmethod
def get_context(cls, records, data): def get_context(cls, records, header, data):
report_context = super(PayrollReport, cls).get_context(records, data) report_context = super().get_context(records, header, data)
return report_context return report_context

View File

@ -4,22 +4,6 @@ this repository contains the full copyright notices and license terms. -->
<tryton> <tryton>
<data> <data>
<record model="ir.sequence.type" id="sequence_type_payroll">
<field name="name">Staff Payroll</field>
<field name="code">staff.payroll</field>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_payroll_group_admin">
<field name="sequence_type" ref="sequence_type_payroll"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_payroll_group_staff_admin">
<field name="sequence_type" ref="sequence_type_payroll"/>
<field name="group" ref="staff.group_staff_admin"/>
</record>
<record model="ir.action.report" id="report_staff_payroll"> <record model="ir.action.report" id="report_staff_payroll">
<field name="name">Payroll</field> <field name="name">Payroll</field>
<field name="model">staff.payroll</field> <field name="model">staff.payroll</field>

View File

@ -5,8 +5,8 @@ from trytond.pyson import Eval
from trytond.wizard import Wizard, StateTransition from trytond.wizard import Wizard, StateTransition
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.i18n import gettext
__all__ = ['Period', 'OpenPeriod'] from .exceptions import PeriodValidationError
STATES = {'readonly': Eval('state') != 'draft'} STATES = {'readonly': Eval('state') != 'draft'}
@ -36,10 +36,6 @@ class Period(Workflow, ModelSQL, ModelView):
def __setup__(cls): def __setup__(cls):
super(Period, cls).__setup__() super(Period, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC')) cls._order.insert(0, ('sequence', 'ASC'))
cls._error_messages.update({
'wrong_start_end': ('The date end can not smaller than date start'),
'wrong_period_overlap': ('The period overlap another period!')
})
cls._transitions |= set(( cls._transitions |= set((
('draft', 'open'), ('draft', 'open'),
('open', 'draft'), ('open', 'draft'),
@ -88,7 +84,7 @@ class Period(Workflow, ModelSQL, ModelView):
def check_start_end(self): def check_start_end(self):
if self.start > self.end: if self.start > self.end:
self.raise_user_error('wrong_start_end',) raise PeriodValidationError(gettext('staff_payroll.msg_wrong_start_end'))
def check_date_consistent(self): def check_date_consistent(self):
periods = self.search([ periods = self.search([
@ -105,7 +101,7 @@ class Period(Workflow, ModelSQL, ModelView):
] ]
]]) ]])
if periods: if periods:
self.raise_user_error('wrong_period_overlap',) raise PeriodValidationError(gettext('staff_payroll.msg_wrong_period_overlap'))
class OpenPeriod(Wizard): class OpenPeriod(Wizard):

View File

@ -3,12 +3,11 @@
from trytond.model import ModelView, ModelSQL, fields from trytond.model import ModelView, ModelSQL, fields
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, Bool from trytond.pyson import Eval, Bool
from trytond.i18n import gettext
__all__ = ['Position', 'WorkdayDefinition'] from .exceptions import MissingConfigPosition
class Position: class Position(metaclass=PoolMeta):
__metaclass__ = PoolMeta
__name__ = 'staff.position' __name__ = 'staff.position'
workday_definition = fields.One2Many('staff.workday_definition', workday_definition = fields.One2Many('staff.workday_definition',
'position', 'Workday Definition') 'position', 'Workday Definition')
@ -16,9 +15,6 @@ class Position:
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(Position, cls).__setup__() super(Position, cls).__setup__()
cls._error_messages.update({
'missing_config_default': ('Missing default values for '
'workday or restday on configuration!')})
cls._buttons.update({ cls._buttons.update({
'create_workdays': { 'create_workdays': {
'invisible': Bool(Eval('workday_definition')), 'invisible': Bool(Eval('workday_definition')),
@ -31,7 +27,7 @@ class Position:
Config = pool.get('staff.configuration') Config = pool.get('staff.configuration')
config = Config(1) config = Config(1)
if not config.default_hour_workday or not config.default_hour_workday: if not config.default_hour_workday or not config.default_hour_workday:
self.raise_user_error('missing_config_default') raise MissingConfigPosition(gettext('staff_payroll.msg_missing_config_default'))
for day in Workday.weekday.selection: for day in Workday.weekday.selection:
values = { values = {
'position': self.id, 'weekday': day[0], 'position': self.id, 'weekday': day[0],

View File

@ -104,10 +104,10 @@ setup(name=name,
'Natural Language :: Slovenian', 'Natural Language :: Slovenian',
'Natural Language :: Spanish', 'Natural Language :: Spanish',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy', 'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Office/Business', 'Topic :: Office/Business',

View File

@ -1,5 +1,5 @@
[tryton] [tryton]
version=5.0.3 version=6.0.0
depends: depends:
party party
currency currency

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of <!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. --> this repository contains the full copyright notices and license terms. -->
<tree editable="top"> <tree editable="1">
<field name="wage_type"/> <field name="wage_type"/>
<field name="party"/> <field name="party"/>
<field name="fix_amount"/> <field name="fix_amount"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of <!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. --> this repository contains the full copyright notices and license terms. -->
<tree editable="bottom"> <tree editable="1">
<field name="weekday"/> <field name="weekday"/>
<field name="workday"/> <field name="workday"/>
<field name="restday"/> <field name="restday"/>

View File

@ -4,8 +4,8 @@ from decimal import Decimal
from trytond.model import ModelView, ModelSQL, fields from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Not, Bool, Eval, If from trytond.pyson import Not, Bool, Eval, If
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.i18n import gettext
__all__ = ['WageType', 'WageTypeSalary'] from .exceptions import WageTypeValidationError
STATES = {'readonly': Not(Bool(Eval('active')))} STATES = {'readonly': Not(Bool(Eval('active')))}
@ -81,9 +81,6 @@ class WageType(ModelSQL, ModelView):
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(WageType, cls).__setup__() super(WageType, cls).__setup__()
cls._error_messages.update({
'invalid_formula': 'Invalid formula [ %s ] for unit price!',
})
cls._order.insert(0, ('sequence', 'ASC')) cls._order.insert(0, ('sequence', 'ASC'))
@staticmethod @staticmethod
@ -128,7 +125,8 @@ class WageType(ModelSQL, ModelView):
value = Decimal(str(round(eval(formula), 2))) value = Decimal(str(round(eval(formula), 2)))
return value return value
except Exception: except Exception:
self.raise_user_error('invalid_formula', formula) raise WageTypeValidationError(
gettext('staff_payroll.msg_invalid_formula', formula=formula))
class WageTypeSalary(ModelSQL): class WageTypeSalary(ModelSQL):