lims: sets and groups take the lab from the included analyzes

This commit is contained in:
Adrián Bernardi 2022-02-15 17:13:23 -03:00
parent 129aad37c4
commit c40814aa00
8 changed files with 165 additions and 310 deletions

View File

@ -862,10 +862,10 @@ class Analysis(Workflow, ModelSQL, ModelView):
'Laboratories', context={'type': Eval('type')}, 'Laboratories', context={'type': Eval('type')},
states={ states={
'invisible': Or( 'invisible': Or(
Eval('type').in_(['group']), Eval('type') != 'analysis',
Bool(Equal(Eval('behavior'), 'additional'))), Bool(Equal(Eval('behavior'), 'additional'))),
'required': Not(Or( 'required': Not(Or(
Eval('type').in_(['set', 'group']), Eval('type') != 'analysis',
Bool(Equal(Eval('behavior'), 'additional')))), Bool(Equal(Eval('behavior'), 'additional')))),
'readonly': Bool(Equal(Eval('state'), 'disabled')), 'readonly': Bool(Equal(Eval('state'), 'disabled')),
}, depends=['type', 'behavior', 'state']) }, depends=['type', 'behavior', 'state'])
@ -892,13 +892,12 @@ class Analysis(Workflow, ModelSQL, ModelView):
start_date = fields.Date('Entry date', readonly=True) start_date = fields.Date('Entry date', readonly=True)
end_date = fields.Date('Leaving date', readonly=True) end_date = fields.Date('Leaving date', readonly=True)
included_analysis = fields.One2Many('lims.analysis.included', 'analysis', included_analysis = fields.One2Many('lims.analysis.included', 'analysis',
'Included analysis', context={ 'Included analysis', depends=['type', 'state'],
'analysis': Eval('id'), 'type': Eval('type'), context={'analysis': Eval('id'), 'type': Eval('type')},
'laboratory_domain': Eval('laboratory_domain')},
states={ states={
'invisible': Bool(Equal(Eval('type'), 'analysis')), 'invisible': Bool(Equal(Eval('type'), 'analysis')),
'readonly': Bool(Equal(Eval('state'), 'disabled')), 'readonly': Bool(Equal(Eval('state'), 'disabled')),
}, depends=['type', 'laboratory_domain', 'state']) })
all_included_analysis = fields.Function(fields.One2Many('lims.analysis', all_included_analysis = fields.Function(fields.One2Many('lims.analysis',
None, 'All included analysis'), None, 'All included analysis'),
'on_change_with_all_included_analysis', 'on_change_with_all_included_analysis',
@ -1091,7 +1090,7 @@ class Analysis(Workflow, ModelSQL, ModelView):
('//page[@id="laboratories"]', ('//page[@id="laboratories"]',
'states', { 'states', {
'invisible': Or( 'invisible': Or(
Eval('type').in_(['group']), Eval('type') != 'analysis',
Bool(Equal(Eval('behavior'), 'additional'))), Bool(Equal(Eval('behavior'), 'additional'))),
}), }),
] ]
@ -1099,7 +1098,8 @@ class Analysis(Workflow, ModelSQL, ModelView):
@classmethod @classmethod
def get_included_analysis(cls, analysis_id): def get_included_analysis(cls, analysis_id):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
AnalysisIncluded = Pool().get('lims.analysis.included') pool = Pool()
AnalysisIncluded = pool.get('lims.analysis.included')
childs = [] childs = []
cursor.execute('SELECT included_analysis ' cursor.execute('SELECT included_analysis '
@ -1135,7 +1135,8 @@ class Analysis(Workflow, ModelSQL, ModelView):
@classmethod @classmethod
def get_included_analysis_method(cls, analysis_id): def get_included_analysis_method(cls, analysis_id):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
AnalysisIncluded = Pool().get('lims.analysis.included') pool = Pool()
AnalysisIncluded = pool.get('lims.analysis.included')
childs = [] childs = []
cursor.execute('SELECT included_analysis, method ' cursor.execute('SELECT included_analysis, method '
@ -1191,7 +1192,6 @@ class Analysis(Workflow, ModelSQL, ModelView):
super().validate(analysis) super().validate(analysis)
for a in analysis: for a in analysis:
cls.check_duplicate_description(a.type, a.description, a.id) cls.check_duplicate_description(a.type, a.description, a.id)
a.check_set()
a.check_end_date() a.check_end_date()
@classmethod @classmethod
@ -1204,23 +1204,6 @@ class Analysis(Workflow, ModelSQL, ModelView):
]) > 0: ]) > 0:
raise UserError(gettext('lims.msg_description_uniq')) raise UserError(gettext('lims.msg_description_uniq'))
def check_set(self):
if self.type == 'set':
if self.laboratories and len(self.laboratories) > 1:
raise UserError(gettext('lims.msg_set_laboratories'))
if self.included_analysis and not self.laboratories:
raise UserError(gettext('lims.msg_not_laboratory'))
if self.included_analysis:
set_laboratory = self.laboratories[0].laboratory
for ia in self.included_analysis:
included_analysis_laboratories = [lab.laboratory
for lab in ia.included_analysis.laboratories]
if (set_laboratory not in included_analysis_laboratories):
raise UserError(gettext('lims.msg_analysis_laboratory',
analysis=ia.included_analysis.rec_name,
laboratory=set_laboratory.rec_name,
))
def check_end_date(self): def check_end_date(self):
if self.end_date: if self.end_date:
if not self.start_date or self.end_date < self.start_date: if not self.start_date or self.end_date < self.start_date:
@ -1232,31 +1215,12 @@ class Analysis(Workflow, ModelSQL, ModelView):
def write(cls, *args): def write(cls, *args):
actions = iter(args) actions = iter(args)
for analysis, vals in zip(actions, actions): for analysis, vals in zip(actions, actions):
if vals.get('laboratories'):
cls.check_laboratory_change(analysis, vals['laboratories'])
if vals.get('description'): if vals.get('description'):
for a in analysis: for a in analysis:
cls.check_duplicate_description(vals.get('type', a.type), cls.check_duplicate_description(vals.get('type', a.type),
vals['description'], a.id) vals['description'], a.id)
super().write(*args) super().write(*args)
@classmethod
def check_laboratory_change(cls, analysis, laboratories):
AnalysisIncluded = Pool().get('lims.analysis.included')
for a in analysis:
if a.type == 'analysis':
for operation in laboratories:
if operation[0] == 'unlink':
for laboratory in operation[1]:
parent = AnalysisIncluded.search([
('included_analysis', '=', a.id),
('laboratory', '=', laboratory),
])
if parent:
raise UserError(
gettext('lims.msg_not_laboratory_change'))
@classmethod @classmethod
@ModelView.button_action('lims.wiz_lims_relate_analysis') @ModelView.button_action('lims.wiz_lims_relate_analysis')
def relate_analysis(cls, analysis): def relate_analysis(cls, analysis):
@ -1444,7 +1408,6 @@ class Analysis(Workflow, ModelSQL, ModelView):
backup.append({ backup.append({
'analysis': ia.analysis.id, 'analysis': ia.analysis.id,
'included_analysis': ia.included_analysis.id, 'included_analysis': ia.included_analysis.id,
'laboratory': ia.laboratory and ia.laboratory.id or None,
'method': ia.method and ia.method.id or None, 'method': ia.method and ia.method.id or None,
}) })
a.included_analysis_backup = json.dumps(backup) a.included_analysis_backup = json.dumps(backup)
@ -1705,22 +1668,6 @@ class AnalysisIncluded(ModelSQL, ModelView):
('group', 'Group'), ('group', 'Group'),
], 'Type', sort=False), ], 'Type', sort=False),
'on_change_with_analysis_type') 'on_change_with_analysis_type')
laboratory = fields.Many2One('lims.laboratory', 'Laboratory',
domain=[('id', 'in', Eval('laboratory_domain'))],
states={
'required': Or(
Bool(Equal(Eval('_parent_analysis', {}).get('type'), 'set')),
And(Bool(Equal(Eval('_parent_analysis', {}).get('type'),
'group')),
Bool(Equal(Eval('analysis_type'), 'analysis'))),
Bool(Eval('laboratory_domain'))),
'readonly': Bool(
Equal(Eval('_parent_analysis', {}).get('type'), 'set')),
'invisible': Eval('analysis_type').in_(['set', 'group']),
},
depends=['laboratory_domain', 'analysis_type'])
laboratory_domain = fields.Function(fields.Many2Many('lims.laboratory',
None, None, 'Laboratory domain'), 'on_change_with_laboratory_domain')
method = fields.Many2One('lims.lab.method', 'Method', method = fields.Many2One('lims.lab.method', 'Method',
domain=[('id', 'in', Eval('method_domain'))], domain=[('id', 'in', Eval('method_domain'))],
states={ states={
@ -1762,16 +1709,6 @@ class AnalysisIncluded(ModelSQL, ModelView):
raise UserError(gettext('lims.msg_duplicated_analysis', raise UserError(gettext('lims.msg_duplicated_analysis',
analysis=self.included_analysis.rec_name)) analysis=self.included_analysis.rec_name))
@fields.depends('included_analysis', 'analysis', 'laboratory',
'_parent_analysis.type', '_parent_analysis.laboratories')
def on_change_included_analysis(self):
laboratory = None
if self.included_analysis:
laboratories = self.on_change_with_laboratory_domain()
if len(laboratories) == 1:
laboratory = laboratories[0]
self.laboratory = laboratory
@fields.depends('included_analysis', '_parent_included_analysis.type') @fields.depends('included_analysis', '_parent_included_analysis.type')
def on_change_with_analysis_type(self, name=None): def on_change_with_analysis_type(self, name=None):
res = '' res = ''
@ -1784,93 +1721,32 @@ class AnalysisIncluded(ModelSQL, ModelView):
AnalysisIncluded = Pool().get('lims.analysis.included') AnalysisIncluded = Pool().get('lims.analysis.included')
context = Transaction().context context = Transaction().context
analysis_id = context.get('analysis', None) analysis_id = context.get('analysis', None)
analysis_type = context.get('type', None) return AnalysisIncluded.get_analysis_domain(analysis_id)
laboratories = context.get('laboratory_domain', [])
return AnalysisIncluded.get_analysis_domain(analysis_id,
analysis_type, laboratories)
@fields.depends('analysis', '_parent_analysis.type', @fields.depends('analysis')
'_parent_analysis.laboratories')
def on_change_with_analysis_domain(self, name=None): def on_change_with_analysis_domain(self, name=None):
analysis_id = self.analysis.id if self.analysis else None analysis_id = self.analysis.id if self.analysis else None
analysis_type = self.analysis.type if self.analysis else None return self.get_analysis_domain(analysis_id)
laboratories = []
if self.analysis and self.analysis.laboratories:
laboratories = [l.laboratory.id
for l in self.analysis.laboratories]
return self.get_analysis_domain(analysis_id,
analysis_type, laboratories)
@staticmethod @staticmethod
def get_analysis_domain(analysis_id=None, analysis_type=None, def get_analysis_domain(analysis_id=None):
laboratories=[]):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
Analysis = pool.get('lims.analysis') Analysis = pool.get('lims.analysis')
AnalysisLaboratory = pool.get('lims.analysis-laboratory')
if not analysis_type: not_parent_clause = ''
if analysis_id:
not_parent_clause = 'AND id != ' + str(analysis_id)
cursor.execute('SELECT id '
'FROM "' + Analysis._table + '" '
'WHERE state = \'active\' '
'AND type != \'group\' '
'AND end_date IS NULL ' +
not_parent_clause)
res = cursor.fetchall()
if not res:
return [] return []
return [x[0] for x in res]
if analysis_type == 'set':
if len(laboratories) != 1:
raise UserError(gettext('lims.msg_not_set_laboratory'))
set_laboratory_id = laboratories[0]
not_parent_clause = ''
if analysis_id:
not_parent_clause = 'AND al.analysis != ' + str(analysis_id)
cursor.execute('SELECT DISTINCT(al.analysis) '
'FROM "' + AnalysisLaboratory._table + '" al '
'INNER JOIN "' + Analysis._table + '" a '
'ON a.id = al.analysis '
'WHERE al.laboratory = %s '
'AND a.state = \'active\' '
'AND a.type = \'analysis\' '
'AND a.end_date IS NULL ' +
not_parent_clause,
(set_laboratory_id,))
res = cursor.fetchall()
if not res:
return []
return [x[0] for x in res]
else:
not_parent_clause = ''
if analysis_id:
not_parent_clause = 'AND id != ' + str(analysis_id)
cursor.execute('SELECT id '
'FROM "' + Analysis._table + '" '
'WHERE state = \'active\' '
'AND type != \'group\' '
'AND end_date IS NULL ' +
not_parent_clause)
res = cursor.fetchall()
if not res:
return []
return [x[0] for x in res]
@staticmethod
def default_laboratory_domain():
return Transaction().context.get('laboratory_domain', [])
@fields.depends('included_analysis', 'analysis', '_parent_analysis.type',
'_parent_analysis.laboratories', 'laboratory')
def on_change_with_laboratory_domain(self, name=None):
laboratories = []
analysis_laboratories = []
if self.included_analysis and self.included_analysis.laboratories:
analysis_laboratories = [l.laboratory.id
for l in self.included_analysis.laboratories]
if self.analysis and self.analysis.type == 'set':
if self.analysis.laboratories:
set_laboratory = self.analysis.laboratories[0].laboratory.id
if set_laboratory in analysis_laboratories:
laboratories = [set_laboratory]
else:
laboratories = analysis_laboratories
if not laboratories and self.laboratory:
laboratories = [self.laboratory.id]
return laboratories
@fields.depends('included_analysis', '_parent_included_analysis.methods') @fields.depends('included_analysis', '_parent_included_analysis.methods')
def on_change_with_method_domain(self, name=None): def on_change_with_method_domain(self, name=None):
@ -2812,38 +2688,28 @@ class RelateAnalysis(Wizard):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
Analysis = pool.get('lims.analysis') Analysis = pool.get('lims.analysis')
AnalysisLaboratory = pool.get('lims.analysis-laboratory')
analysis = Analysis(Transaction().context['active_id'])
default = { default = {
'analysis_domain': [], 'analysis_domain': [],
} }
if len(analysis.laboratories) != 1: cursor.execute('SELECT id '
raise UserError(gettext('lims.msg_not_set_laboratory')) 'FROM "' + Analysis._table + '" '
'WHERE state = \'active\' '
cursor.execute('SELECT DISTINCT(al.analysis) ' 'AND type = \'analysis\' '
'FROM "' + AnalysisLaboratory._table + '" al ' 'AND end_date IS NULL')
'INNER JOIN "' + Analysis._table + '" a '
'ON a.id = al.analysis '
'WHERE al.laboratory = %s '
'AND a.state = \'active\' '
'AND a.type = \'analysis\' '
'AND a.end_date IS NULL '
'AND al.analysis != %s',
(analysis.laboratories[0].laboratory.id, analysis.id,))
res = cursor.fetchall() res = cursor.fetchall()
if res: if res:
default['analysis_domain'] = [x[0] for x in res] default['analysis_domain'] = [x[0] for x in res]
return default return default
def transition_relate(self): def transition_relate(self):
Analysis = Pool().get('lims.analysis') pool = Pool()
Analysis = pool.get('lims.analysis')
analysis = Analysis(Transaction().context['active_id']) analysis = Analysis(Transaction().context['active_id'])
to_create = [{ to_create = [{
'analysis': analysis.id, 'analysis': analysis.id,
'included_analysis': al.id, 'included_analysis': al.id,
'laboratory': analysis.laboratories[0].laboratory.id,
} for al in self.start.analysis] } for al in self.start.analysis]
Analysis.write([analysis], { Analysis.write([analysis], {
'included_analysis': [('create', to_create)], 'included_analysis': [('create', to_create)],

View File

@ -426,18 +426,6 @@
<field name="name">analysis_included_list</field> <field name="name">analysis_included_list</field>
</record> </record>
<record model="ir.rule.group" id="rule_group_analysis_included">
<field name="name">User in laboratory</field>
<field name="model" search="[('model', '=', 'lims.analysis.included')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_analysis_included">
<field name="domain"
eval="[If(Bool(Eval('user', {}).get('laboratory', False)), ('laboratory', '=', Eval('user', {}).get('laboratory', None)), If(Bool(Eval('user', {}).get('laboratories', False)), ('laboratory', 'in', Eval('user', {}).get('laboratories', [])), ('id', '!=', 0)))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_analysis_included"/>
</record>
<!-- Analysis Device --> <!-- Analysis Device -->
<record model="ir.ui.view" id="lims_analysis_device_view_form"> <record model="ir.ui.view" id="lims_analysis_device_view_form">

View File

@ -238,14 +238,6 @@ msgctxt "field:lims.analysis.included,included_analysis:"
msgid "Included analysis" msgid "Included analysis"
msgstr "Análisis incluido" msgstr "Análisis incluido"
msgctxt "field:lims.analysis.included,laboratory:"
msgid "Laboratory"
msgstr "Laboratorio"
msgctxt "field:lims.analysis.included,laboratory_domain:"
msgid "Laboratory domain"
msgstr "Dominio para Laboratorio"
msgctxt "field:lims.analysis.included,method:" msgctxt "field:lims.analysis.included,method:"
msgid "Method" msgid "Method"
msgstr "Método" msgstr "Método"
@ -7634,12 +7626,6 @@ msgctxt "model:ir.message,text:msg_analysis_family_code_unique_id"
msgid "Analysis family code must be unique" msgid "Analysis family code must be unique"
msgstr "El código de la familia de análisis debe ser único" msgstr "El código de la familia de análisis debe ser único"
msgctxt "model:ir.message,text:msg_analysis_laboratory"
msgid "The \"%(analysis)s\" analysis is not defined in laboratory \"%(laboratory)s\""
msgstr ""
"El análisis \"%(analysis)s\" no está definido para el laboratorio "
"\"%(laboratory)s\""
msgctxt "model:ir.message,text:msg_annul_analysis" msgctxt "model:ir.message,text:msg_annul_analysis"
msgid "The analysis \"%(analysis)s\" is already reported" msgid "The analysis \"%(analysis)s\" is already reported"
msgstr "El análisis \"%(analysis)s\" ya fue informado" msgstr "El análisis \"%(analysis)s\" ya fue informado"
@ -8121,27 +8107,11 @@ msgctxt "model:ir.message,text:msg_not_fraction"
msgid "You can not confirm entry \"%(entry)s\" because has not fractions" msgid "You can not confirm entry \"%(entry)s\" because has not fractions"
msgstr "No puede confirmar el ingreso «%(entry)s» porque no posee fracciones" msgstr "No puede confirmar el ingreso «%(entry)s» porque no posee fracciones"
msgctxt "model:ir.message,text:msg_not_laboratory"
msgid "Must define a Laboratory"
msgstr "Debe definir un laboratorio"
msgctxt "model:ir.message,text:msg_not_laboratory_change"
msgid ""
"You can not change the laboratory because the analysis is included in a "
"set/group with this laboratory"
msgstr ""
"No puede cambiar el laboratorio porque el análisis está incluido en un "
"set/grupo con este laboratorio"
msgctxt "model:ir.message,text:msg_not_services" msgctxt "model:ir.message,text:msg_not_services"
msgid "You can not confirm fraction \"%(fraction)s\" because has not services" msgid "You can not confirm fraction \"%(fraction)s\" because has not services"
msgstr "" msgstr ""
"No puede confirmar la fracción «%(fraction)s» porque no posee servicios" "No puede confirmar la fracción «%(fraction)s» porque no posee servicios"
msgctxt "model:ir.message,text:msg_not_set_laboratory"
msgid "No Laboratory loaded for the Set"
msgstr "Ningún laboratorio definido para el Set"
msgctxt "model:ir.message,text:msg_not_start_date" msgctxt "model:ir.message,text:msg_not_start_date"
msgid "The planification must have a start date" msgid "The planification must have a start date"
msgstr "La planificación debe tener una fecha de inicio" msgstr "La planificación debe tener una fecha de inicio"
@ -8294,10 +8264,6 @@ msgstr ""
"No puede copiar el servicio \"%(analysis)s\" porque el laboratorio asignado " "No puede copiar el servicio \"%(analysis)s\" porque el laboratorio asignado "
"(%(laboratory)s) no es el predeterminado." "(%(laboratory)s) no es el predeterminado."
msgctxt "model:ir.message,text:msg_set_laboratories"
msgid "A Set can be assigned to a single laboratory"
msgstr "Un Set puede ser asignado a un único laboratorio"
msgctxt "model:ir.message,text:msg_suspension_reason_unique_id" msgctxt "model:ir.message,text:msg_suspension_reason_unique_id"
msgid "Suspension reason code must be unique" msgid "Suspension reason code must be unique"
msgstr "El código del motivo de suspensión debe ser único" msgstr "El código del motivo de suspensión debe ser único"
@ -8434,10 +8400,6 @@ msgctxt "model:ir.rule.group,name:rule_group_analysis_device"
msgid "User in laboratory" msgid "User in laboratory"
msgstr "" msgstr ""
msgctxt "model:ir.rule.group,name:rule_group_analysis_included"
msgid "User in laboratory"
msgstr ""
msgctxt "model:ir.rule.group,name:rule_group_analysis_laboratory" msgctxt "model:ir.rule.group,name:rule_group_analysis_laboratory"
msgid "User in laboratory" msgid "User in laboratory"
msgstr "" msgstr ""

View File

@ -19,18 +19,6 @@
<record model="ir.message" id="msg_description_uniq"> <record model="ir.message" id="msg_description_uniq">
<field name="text">Analysis description must be unique</field> <field name="text">Analysis description must be unique</field>
</record> </record>
<record model="ir.message" id="msg_not_laboratory">
<field name="text">Must define a Laboratory</field>
</record>
<record model="ir.message" id="msg_set_laboratories">
<field name="text">A Set can be assigned to a single laboratory</field>
</record>
<record model="ir.message" id="msg_analysis_laboratory">
<field name="text">The "%(analysis)s" analysis is not defined in laboratory "%(laboratory)s"</field>
</record>
<record model="ir.message" id="msg_not_laboratory_change">
<field name="text">You can not change the laboratory because the analysis is included in a set/group with this laboratory</field>
</record>
<record model="ir.message" id="msg_end_date"> <record model="ir.message" id="msg_end_date">
<field name="text">The leaving date cannot be lower than entry date</field> <field name="text">The leaving date cannot be lower than entry date</field>
</record> </record>
@ -40,9 +28,6 @@
<record model="ir.message" id="msg_duplicated_analysis"> <record model="ir.message" id="msg_duplicated_analysis">
<field name="text">The analysis "%(analysis)s" is already included</field> <field name="text">The analysis "%(analysis)s" is already included</field>
</record> </record>
<record model="ir.message" id="msg_not_set_laboratory">
<field name="text">No Laboratory loaded for the Set</field>
</record>
<record model="ir.message" id="msg_typificated_method"> <record model="ir.message" id="msg_typificated_method">
<field name="text">You can not delete method "%(method)s" because is typificated</field> <field name="text">You can not delete method "%(method)s" because is typificated</field>
</record> </record>

View File

@ -178,24 +178,25 @@ class Planification(Workflow, ModelSQL, ModelView):
'INNER JOIN "' + Analysis._table + '" a ' 'INNER JOIN "' + Analysis._table + '" a '
'ON a.id = al.analysis ' 'ON a.id = al.analysis '
'WHERE al.laboratory = %s ' 'WHERE al.laboratory = %s '
'AND a.type = \'analysis\' '
'AND a.behavior != \'internal_relation\'', 'AND a.behavior != \'internal_relation\'',
(laboratory.id,)) (laboratory.id,))
analysis_sets_list = [a[0] for a in cursor.fetchall()] analyzes_list = [a[0] for a in cursor.fetchall()]
groups_list = [] others_list = []
cursor.execute('SELECT id ' cursor.execute('SELECT id '
'FROM "' + Analysis._table + '" ' 'FROM "' + Analysis._table + '" '
'WHERE type = \'group\'') 'WHERE type != \'analysis\'')
groups_list_ids = [g[0] for g in cursor.fetchall()] others_list_ids = [x[0] for x in cursor.fetchall()]
for group_id in groups_list_ids: for set_group_id in others_list_ids:
if Planification._get_group_available(group_id, if Planification._get_set_group_available(set_group_id,
analysis_sets_list): analyzes_list):
groups_list.append(group_id) others_list.append(set_group_id)
return analysis_sets_list + groups_list return analyzes_list + others_list
@staticmethod @staticmethod
def _get_group_available(group_id, analysis_sets_list): def _get_set_group_available(set_group_id, analyzes_list):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
AnalysisIncluded = pool.get('lims.analysis.included') AnalysisIncluded = pool.get('lims.analysis.included')
@ -207,17 +208,17 @@ class Planification(Workflow, ModelSQL, ModelView):
'ON a.id = ia.included_analysis ' 'ON a.id = ia.included_analysis '
'WHERE ia.analysis = %s ' 'WHERE ia.analysis = %s '
'AND a.behavior != \'internal_relation\'', 'AND a.behavior != \'internal_relation\'',
(group_id,)) (set_group_id,))
included_analysis = cursor.fetchall() included_analysis = cursor.fetchall()
if not included_analysis: if not included_analysis:
return False return False
for analysis in included_analysis: for analysis in included_analysis:
if (analysis[1] != 'group' and analysis[0] not in if (analysis[1] == 'analysis' and analysis[0] not in
analysis_sets_list): analyzes_list):
return False return False
if (analysis[1] == 'group' and not if (analysis[1] != 'analysis' and not
Planification._get_group_available(analysis[0], Planification._get_set_group_available(analysis[0],
analysis_sets_list)): analyzes_list)):
return False return False
return True return True
@ -4508,41 +4509,41 @@ class CreateFractionControlStart(ModelView):
if not self.laboratory or not self.product_type or not self.matrix: if not self.laboratory or not self.product_type or not self.matrix:
return [] return []
cursor.execute('SELECT DISTINCT(analysis) ' cursor.execute('SELECT DISTINCT(al.analysis) '
'FROM "' + AnalysisLaboratory._table + '" ' 'FROM "' + AnalysisLaboratory._table + '" al '
'WHERE laboratory = %s', (self.laboratory.id,)) 'INNER JOIN "' + Analysis._table + '" a '
analysis_sets_list = [a[0] for a in cursor.fetchall()] 'ON a.id = al.analysis '
if not analysis_sets_list: 'WHERE al.laboratory = %s '
'AND a.type = \'analysis\'',
(self.laboratory.id,))
analyzes_list = [a[0] for a in cursor.fetchall()]
if not analyzes_list:
return [] return []
lab_analysis_ids = ', '.join(str(a) for a in lab_analysis_ids = ', '.join(str(a) for a in analyzes_list)
analysis_sets_list)
groups_list = [] others_list = []
groups = Analysis.search([ others = Analysis.search([
('type', '=', 'group'), ('type', '!=', 'analysis'),
]) ])
if groups: for set_group in others:
for group in groups: available = True
available = True
ia = Analysis.get_included_analysis_analysis( ia = Analysis.get_included_analysis_analysis(set_group.id)
group.id) if not ia:
if not ia: continue
continue included_ids = ', '.join(str(a) for a in ia)
included_ids = ', '.join(str(a) for a in ia)
cursor.execute('SELECT id ' cursor.execute('SELECT id '
'FROM "' + Analysis._table + '" ' 'FROM "' + Analysis._table + '" '
'WHERE id IN (' + included_ids + ') ' 'WHERE id IN (' + included_ids + ') '
'AND id NOT IN (' + lab_analysis_ids + 'AND id NOT IN (' + lab_analysis_ids + ')')
')') if cursor.fetchone():
if cursor.fetchone(): available = False
available = False
if available: if available:
groups_list.append(group.id) others_list.append(set_group.id)
analysis_domain = analysis_sets_list + groups_list analysis_domain = analyzes_list + others_list
analysis_domain_ids = ', '.join(str(a) for a in analysis_domain) analysis_domain_ids = ', '.join(str(a) for a in analysis_domain)
cursor.execute('SELECT DISTINCT(typ.analysis) ' cursor.execute('SELECT DISTINCT(typ.analysis) '

View File

@ -640,7 +640,9 @@ class Service(ModelSQL, ModelView):
@staticmethod @staticmethod
def _get_included_analysis(analysis, analysis_origin='', def _get_included_analysis(analysis, analysis_origin='',
service_context=None): service_context=None):
Typification = Pool().get('lims.typification') cursor = Transaction().connection.cursor()
pool = Pool()
Typification = pool.get('lims.typification')
childs = [] childs = []
if analysis.included_analysis: if analysis.included_analysis:
@ -651,24 +653,45 @@ class Service(ModelSQL, ModelView):
else: else:
origin = (analysis_origin + ' > ' + origin = (analysis_origin + ' > ' +
included.included_analysis.code) included.included_analysis.code)
if included.included_analysis.type == 'analysis': if included.included_analysis.type == 'analysis':
laboratory_id = included.laboratory.id laboratory_id = None
cursor.execute('SELECT laboratory '
'FROM "' + Typification._table + '" '
'WHERE product_type = %s '
'AND matrix = %s '
'AND analysis = %s '
'AND valid IS TRUE '
'AND by_default IS TRUE '
'AND laboratory IS NOT NULL',
(service_context['product_type'],
service_context['matrix'],
included.included_analysis.id))
res = cursor.fetchone()
if res:
laboratory_id = res[0]
if not laboratory_id:
for l in included.included_analysis.laboratories:
if l.by_default is True:
laboratory_id = l.laboratory.id
method_id = (included.method.id method_id = (included.method.id
if included.method else None) if included.method else None)
if not method_id: if not method_id:
typifications = Typification.search([ cursor.execute('SELECT method '
('product_type', '=', 'FROM "' + Typification._table + '" '
service_context['product_type']), 'WHERE product_type = %s '
('matrix', '=', service_context['matrix']), 'AND matrix = %s '
('analysis', '=', included.included_analysis), 'AND analysis = %s '
('by_default', '=', True), 'AND valid IS TRUE '
('valid', '=', True), 'AND by_default IS TRUE',
]) (service_context['product_type'],
method_id = (typifications[0].method.id service_context['matrix'],
if typifications else None) included.included_analysis.id))
res = cursor.fetchone()
if res:
method_id = res[0]
device_id = None device_id = None
if included.included_analysis.devices: if included.included_analysis.devices:
@ -827,12 +850,13 @@ class Service(ModelSQL, ModelView):
@classmethod @classmethod
def _get_analysis_included_labs(cls, analysis): def _get_analysis_included_labs(cls, analysis):
childs = [] childs = []
if analysis.included_analysis: for included in analysis.included_analysis:
for included in analysis.included_analysis: if included.included_analysis.type == 'analysis':
if included.included_analysis.type == 'analysis': for l in included.included_analysis.laboratories:
childs.append(included.laboratory.id) if l.by_default is True:
childs.extend(cls._get_analysis_included_labs( childs.append(l.laboratory.id)
included.included_analysis)) childs.extend(cls._get_analysis_included_labs(
included.included_analysis))
return childs return childs
@classmethod @classmethod
@ -1085,7 +1109,7 @@ class Service(ModelSQL, ModelView):
AnalysisLaboratory = pool.get('lims.analysis-laboratory') AnalysisLaboratory = pool.get('lims.analysis-laboratory')
Typification = pool.get('lims.typification') Typification = pool.get('lims.typification')
if not self.analysis: if not self.analysis or self.analysis.type != 'analysis':
return None return None
cursor.execute('SELECT laboratory ' cursor.execute('SELECT laboratory '
@ -1120,7 +1144,7 @@ class Service(ModelSQL, ModelView):
pool = Pool() pool = Pool()
AnalysisLaboratory = pool.get('lims.analysis-laboratory') AnalysisLaboratory = pool.get('lims.analysis-laboratory')
if not self.analysis: if not self.analysis or self.analysis.type != 'analysis':
return [] return []
cursor.execute('SELECT DISTINCT(laboratory) ' cursor.execute('SELECT DISTINCT(laboratory) '
@ -5967,9 +5991,13 @@ class CreateSampleService(ModelView):
def _get_default_laboratory(analysis_id, product_type_id, matrix_id): def _get_default_laboratory(analysis_id, product_type_id, matrix_id):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
Analysis = pool.get('lims.analysis')
AnalysisLaboratory = pool.get('lims.analysis-laboratory') AnalysisLaboratory = pool.get('lims.analysis-laboratory')
Typification = pool.get('lims.typification') Typification = pool.get('lims.typification')
if Analysis(analysis_id).type != 'analysis':
return None
cursor.execute('SELECT laboratory ' cursor.execute('SELECT laboratory '
'FROM "' + Typification._table + '" ' 'FROM "' + Typification._table + '" '
'WHERE product_type = %s ' 'WHERE product_type = %s '
@ -5998,8 +6026,12 @@ class CreateSampleService(ModelView):
def _get_laboratory_domain(analysis_id): def _get_laboratory_domain(analysis_id):
cursor = Transaction().connection.cursor() cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
Analysis = pool.get('lims.analysis')
AnalysisLaboratory = pool.get('lims.analysis-laboratory') AnalysisLaboratory = pool.get('lims.analysis-laboratory')
if Analysis(analysis_id).type != 'analysis':
return []
cursor.execute('SELECT DISTINCT(laboratory) ' cursor.execute('SELECT DISTINCT(laboratory) '
'FROM "' + AnalysisLaboratory._table + '" ' 'FROM "' + AnalysisLaboratory._table + '" '
'WHERE analysis = %s', 'WHERE analysis = %s',
@ -6307,6 +6339,7 @@ class CreateSample(Wizard):
return samples_defaults return samples_defaults
def _get_included_analysis(self, analysis): def _get_included_analysis(self, analysis):
cursor = Transaction().connection.cursor()
pool = Pool() pool = Pool()
Typification = pool.get('lims.typification') Typification = pool.get('lims.typification')
@ -6314,20 +6347,43 @@ class CreateSample(Wizard):
if analysis.included_analysis: if analysis.included_analysis:
for included in analysis.included_analysis: for included in analysis.included_analysis:
if included.included_analysis.type == 'analysis': if included.included_analysis.type == 'analysis':
laboratory_id = included.laboratory.id
laboratory_id = None
cursor.execute('SELECT laboratory '
'FROM "' + Typification._table + '" '
'WHERE product_type = %s '
'AND matrix = %s '
'AND analysis = %s '
'AND valid IS TRUE '
'AND by_default IS TRUE '
'AND laboratory IS NOT NULL',
(self.start.product_type.id,
self.start.matrix.id,
included.included_analysis.id))
res = cursor.fetchone()
if res:
laboratory_id = res[0]
if not laboratory_id:
for l in included.included_analysis.laboratories:
if l.by_default is True:
laboratory_id = l.laboratory.id
method_id = (included.method.id method_id = (included.method.id
if included.method else None) if included.method else None)
if not method_id: if not method_id:
typifications = Typification.search([ cursor.execute('SELECT method '
('product_type', '=', self.start.product_type.id), 'FROM "' + Typification._table + '" '
('matrix', '=', self.start.matrix.id), 'WHERE product_type = %s '
('analysis', '=', included.included_analysis), 'AND matrix = %s '
('by_default', '=', True), 'AND analysis = %s '
('valid', '=', True), 'AND valid IS TRUE '
]) 'AND by_default IS TRUE',
method_id = (typifications[0].method.id (self.start.product_type.id,
if typifications else None) self.start.matrix.id,
included.included_analysis.id))
res = cursor.fetchone()
if res:
method_id = res[0]
device_id = None device_id = None
if included.included_analysis.devices: if included.included_analysis.devices:

View File

@ -4,8 +4,6 @@
<field name="included_analysis"/> <field name="included_analysis"/>
<label name="analysis_type"/> <label name="analysis_type"/>
<field name="analysis_type"/> <field name="analysis_type"/>
<label name="laboratory"/>
<field name="laboratory"/>
<label name="method"/> <label name="method"/>
<field name="method"/> <field name="method"/>
<field name="method_domain" invisible="1"/> <field name="method_domain" invisible="1"/>

View File

@ -2,6 +2,5 @@
<tree> <tree>
<field name="included_analysis"/> <field name="included_analysis"/>
<field name="analysis_type"/> <field name="analysis_type"/>
<field name="laboratory"/>
<field name="method"/> <field name="method"/>
</tree> </tree>