2017-10-08 02:23:22 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This file is part of lims_project_tas module for Tryton.
|
|
|
|
# The COPYRIGHT file at the top level of this repository contains
|
|
|
|
# the full copyright notices and license terms.
|
|
|
|
|
|
|
|
from trytond.model import ModelView, ModelSQL, fields, Unique
|
|
|
|
from trytond.pool import Pool, PoolMeta
|
|
|
|
from trytond.pyson import Eval, Equal, Bool, Not
|
2019-07-23 23:27:33 +02:00
|
|
|
from trytond.exceptions import UserError
|
|
|
|
from trytond.i18n import gettext
|
2017-10-08 02:23:22 +02:00
|
|
|
|
2018-05-24 01:47:26 +02:00
|
|
|
__all__ = ['TasType', 'Project', 'Entry']
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
PROJECT_TYPE = ('tas', 'TAS')
|
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class Project(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.project'
|
|
|
|
|
2020-08-05 22:23:20 +02:00
|
|
|
_states = {'required': Bool(Equal(Eval('type'), 'tas'))}
|
|
|
|
_depends = ['type']
|
|
|
|
|
2017-10-08 02:23:22 +02:00
|
|
|
tas_invoice_party = fields.Many2One('party.party', 'Invoice party',
|
|
|
|
domain=[('id', 'in', Eval('tas_invoice_party_domain'))],
|
2020-08-05 22:23:20 +02:00
|
|
|
states=_states, depends=['type', 'tas_invoice_party_domain'])
|
2017-10-08 02:23:22 +02:00
|
|
|
tas_invoice_party_domain = fields.Function(fields.Many2Many('party.party',
|
|
|
|
None, None, 'TAS Invoice party domain'),
|
|
|
|
'on_change_with_tas_invoice_party_domain')
|
|
|
|
tas_laboratory = fields.Many2One('lims.laboratory', 'Laboratory',
|
2020-08-05 22:23:20 +02:00
|
|
|
states=_states, depends=_depends)
|
2017-10-08 02:23:22 +02:00
|
|
|
tas_type = fields.Many2One('lims.tas.type', 'TAS type')
|
|
|
|
tas_responsible = fields.Many2One('lims.laboratory.professional',
|
|
|
|
'Responsible', domain=[('id', 'in', Eval('tas_responsible_domain'))],
|
|
|
|
depends=['tas_responsible_domain'])
|
|
|
|
tas_responsible_domain = fields.Function(fields.Many2Many(
|
|
|
|
'lims.laboratory.professional', None, None, 'TAS responsible domain'),
|
|
|
|
'on_change_with_tas_responsible_domain')
|
|
|
|
tas_comments = fields.Text('Comments')
|
|
|
|
|
2020-08-05 22:23:20 +02:00
|
|
|
del _states, _depends
|
|
|
|
|
2017-10-08 02:23:22 +02:00
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
2018-05-24 01:47:26 +02:00
|
|
|
super(Project, cls).__setup__()
|
2017-10-08 02:23:22 +02:00
|
|
|
project_type = PROJECT_TYPE
|
|
|
|
if project_type not in cls.type.selection:
|
|
|
|
cls.type.selection.append(project_type)
|
2020-08-05 22:23:20 +02:00
|
|
|
cls.client.states = {'required': Bool(Equal(Eval('type'), 'tas'))}
|
|
|
|
cls.client.depends = ['type']
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def view_attributes(cls):
|
2018-05-24 01:47:26 +02:00
|
|
|
return super(Project, cls).view_attributes() + [
|
2017-10-08 02:23:22 +02:00
|
|
|
('//group[@id="tas"]', 'states', {
|
|
|
|
'invisible': Not(Bool(Equal(Eval('type'), 'tas'))),
|
|
|
|
})]
|
|
|
|
|
|
|
|
@fields.depends('client', 'tas_invoice_party')
|
|
|
|
def on_change_client(self):
|
|
|
|
parties = []
|
|
|
|
if self.client:
|
|
|
|
parties.append(self.client.id)
|
|
|
|
if self.tas_invoice_party:
|
|
|
|
parties.append(self.tas_invoice_party.id)
|
|
|
|
|
|
|
|
if self.client and not self.tas_invoice_party:
|
|
|
|
tas_invoice_party_domain = \
|
|
|
|
self.on_change_with_tas_invoice_party_domain()
|
|
|
|
if len(tas_invoice_party_domain) == 1:
|
|
|
|
self.tas_invoice_party = tas_invoice_party_domain[0]
|
|
|
|
|
|
|
|
@fields.depends('client')
|
|
|
|
def on_change_with_tas_invoice_party_domain(self, name=None):
|
|
|
|
Config = Pool().get('lims.configuration')
|
|
|
|
|
|
|
|
config_ = Config(1)
|
|
|
|
parties = []
|
|
|
|
if self.client:
|
|
|
|
parties.append(self.client.id)
|
|
|
|
if config_.invoice_party_relation_type:
|
|
|
|
parties.extend([r.to.id for r in self.client.relations
|
|
|
|
if r.type == config_.invoice_party_relation_type])
|
|
|
|
return parties
|
|
|
|
|
|
|
|
@fields.depends('tas_laboratory')
|
|
|
|
def on_change_with_tas_responsible_domain(self, name=None):
|
|
|
|
pool = Pool()
|
2018-05-24 01:47:26 +02:00
|
|
|
UserLaboratory = pool.get('lims.user-laboratory')
|
|
|
|
LaboratoryProfessional = pool.get('lims.laboratory.professional')
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
if not self.tas_laboratory:
|
|
|
|
return []
|
|
|
|
|
2018-05-24 01:47:26 +02:00
|
|
|
users = UserLaboratory.search([
|
2017-10-08 02:23:22 +02:00
|
|
|
('laboratory', '=', self.tas_laboratory.id),
|
|
|
|
])
|
|
|
|
if not users:
|
|
|
|
return []
|
2018-05-24 01:47:26 +02:00
|
|
|
professionals = LaboratoryProfessional.search([
|
2017-10-08 02:23:22 +02:00
|
|
|
('party.lims_user', 'in', [u.user.id for u in users]),
|
|
|
|
('role', '!=', ''),
|
|
|
|
])
|
|
|
|
if not professionals:
|
|
|
|
return []
|
|
|
|
return [p.id for p in professionals]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create(cls, vlist):
|
|
|
|
pool = Pool()
|
2018-05-24 01:47:26 +02:00
|
|
|
LabWorkYear = pool.get('lims.lab.workyear')
|
2017-10-08 02:23:22 +02:00
|
|
|
Sequence = pool.get('ir.sequence.strict')
|
|
|
|
|
2018-05-24 01:47:26 +02:00
|
|
|
workyear_id = LabWorkYear.find()
|
|
|
|
workyear = LabWorkYear(workyear_id)
|
2017-10-08 02:23:22 +02:00
|
|
|
sequence = workyear.get_sequence('project_tas')
|
|
|
|
if not sequence:
|
2019-07-23 23:27:33 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'lims_project_tas.msg_no_project_tas_sequence',
|
|
|
|
work_year=workyear.rec_name))
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
vlist = [x.copy() for x in vlist]
|
|
|
|
for values in vlist:
|
|
|
|
if values['type'] == 'tas':
|
|
|
|
values['code'] = Sequence.get_id(sequence.id)
|
2018-05-24 01:47:26 +02:00
|
|
|
return super(Project, cls).create(vlist)
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class Entry(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.entry'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
2018-05-24 01:47:26 +02:00
|
|
|
super(Entry, cls).__setup__()
|
2017-10-08 02:23:22 +02:00
|
|
|
project_type = PROJECT_TYPE
|
|
|
|
if project_type not in cls.project_type.selection:
|
|
|
|
cls.project_type.selection.append(project_type)
|
|
|
|
|
|
|
|
|
2018-05-24 01:47:26 +02:00
|
|
|
class TasType(ModelSQL, ModelView):
|
2017-10-08 02:23:22 +02:00
|
|
|
'TAS Type'
|
|
|
|
__name__ = 'lims.tas.type'
|
|
|
|
|
|
|
|
code = fields.Char('Code', required=True)
|
|
|
|
description = fields.Char('Description', required=True)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
2018-05-24 01:47:26 +02:00
|
|
|
super(TasType, cls).__setup__()
|
2017-10-08 02:23:22 +02:00
|
|
|
t = cls.__table__()
|
|
|
|
cls._sql_constraints += [
|
|
|
|
('code_uniq', Unique(t, t.code),
|
2019-08-01 05:33:07 +02:00
|
|
|
'lims_project_tas.msg_tas_type_code_unique_id'),
|
2017-10-08 02:23:22 +02:00
|
|
|
]
|
|
|
|
|
|
|
|
def get_rec_name(self, name):
|
|
|
|
if self.code:
|
|
|
|
return self.code + ' - ' + self.description
|
|
|
|
else:
|
|
|
|
return self.description
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def search_rec_name(cls, name, clause):
|
|
|
|
field = None
|
|
|
|
for field in ('code', 'description'):
|
|
|
|
records = cls.search([(field,) + tuple(clause[1:])], limit=1)
|
|
|
|
if records:
|
|
|
|
break
|
|
|
|
if records:
|
|
|
|
return [(field,) + tuple(clause[1:])]
|
|
|
|
return [(cls._rec_name,) + tuple(clause[1:])]
|