# 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.model import ModelView, Workflow, ModelSQL, fields from trytond.pyson import Eval from trytond.pool import Pool from trytond.i18n import gettext from trytond.model.exceptions import AccessError from trytond.transaction import Transaction from .exceptions import (StaffContractError) from trytond import backend from trytond.tools.multivalue import migrate_property STATES = {'readonly': (Eval('state') != 'draft')} PAYMENT_TERM = [ ('', ''), ('1', 'Cash') ] class StaffContract(Workflow, ModelSQL, ModelView): "Staff Contract" __name__ = "staff.contract" _rec_name = 'number' number = fields.Char('Number', select=True, states=STATES) employee = fields.Many2One('company.employee', 'Employee', select=True, required=True, states=STATES) company = fields.Many2One('company.company', 'Company', required=True, select=True, states=STATES) contract_date = fields.Date('Contract Date', required=True, states=STATES) start_date = fields.Date('Start Contract', required=True, states=STATES) end_date = fields.Date('End Contract', states={ 'required': Eval('state') == 'finished', 'readonly': Eval('state') == 'finished', }, depends=['state']) canceled_date = fields.Date('Canceled Date', states={ 'required': Eval('state') == 'canceled', }, depends=['state']) salary = fields.Numeric('Salary', digits=(16, 2), states=STATES, help='Salary monthly of person', required=True) kind = fields.Selection([ ('steady', 'Steady'), ('indefinite', 'Indefinite'), ('job', 'Job'), ('learning', 'learning'), ('internships', 'internships') ], 'Kind', select=True, states=STATES) kind_string = kind.translated('kind') state = fields.Selection([ ('draft', 'Draft'), ('active', 'Active'), ('finished', 'Finished'), ('canceled', 'Canceled'), ], 'State', readonly=True, select=True) payment_term = fields.Selection( PAYMENT_TERM, 'Payment Term', states=STATES) comment = fields.Text("Comment", states=STATES) position = fields.Many2One('staff.position', 'Position', select=True) @classmethod def __setup__(cls): super(StaffContract, cls).__setup__() cls._order.insert(0, ('number', 'DESC')) cls._transitions |= set(( ('draft', 'active'), ('active', 'draft'), ('active', 'canceled'), ('active', 'finished'), )) cls._buttons.update({ 'draft': { 'invisible': Eval('state') != 'active', }, 'active': { 'invisible': Eval('state') != 'draft', }, 'finished': { 'invisible': Eval('state') != 'active', }, 'canceled': { 'invisible': Eval('state') != 'active', }, }) @classmethod def __register__(cls, module_name): exist = backend.TableHandler.table_exist(cls._table) super(StaffContract, cls).__register__(module_name) if not exist: cls._migrate_property([], [], []) @classmethod def _migrate_property(cls, field_names, value_names, fields): field_names.append('payment_term') migrate_property( 'staff.contract', field_names, cls, value_names, fields=fields) @staticmethod def default_company(): return Transaction().context.get('company') @staticmethod def default_state(): return 'draft' @staticmethod def default_kind(): return 'job' @staticmethod def default_payment_term(): return '1' @classmethod def search_rec_name(cls, name, clause): if clause[1].startswith('!') or clause[1].startswith('not '): bool_op = 'AND' else: bool_op = 'OR' return [bool_op, ('number',) + tuple(clause[1:]), ('employee',) + tuple(clause[1:]), ] @classmethod @ModelView.button @Workflow.transition('draft') def draft(cls, records): pass @classmethod @ModelView.button @Workflow.transition('active') def active(cls, records): for contract in records: contract.set_number() @classmethod @ModelView.button @Workflow.transition('finished') def finished(cls, records): for contract in records: contract._check_finish_date() @classmethod @ModelView.button @Workflow.transition('canceled') def canceled(cls, records): for contract in records: if not contract.canceled_date: raise StaffContractError(gettext('staff.msg_missing_canceled_date')) def _check_finish_date(self): pass def set_number(self): ''' Fill the reference field with the request sequence ''' pool = Pool() Config = pool.get('staff.configuration') config = Config(1) if self.number: return if not config.staff_contract_sequence: raise StaffContractError(gettext('staff.msg_missing_contract_sequence')) number = config.staff_contract_sequence.get() self.write([self], {'number': number}) @classmethod def create(cls, vlist): vlist = [v.copy() for v in vlist] for values in vlist: contracts_current = cls.search([ ('employee', '=', values['employee']), ('state', 'in', ('active', 'draft')), ]) if contracts_current: raise AccessError(gettext('staff.msg_employee_with_contract_current', contract=contracts_current[0].employee.rec_name)) return super(StaffContract, cls).create(vlist) @classmethod def delete(cls, records): for contract in records: if contract.number: raise AccessError(gettext('staff.msg_dont_delete_contract', contract=contracts_current[0].employee.rec_name)) return super(StaffContract, cls).delete(records)