mirror of
https://github.com/Kalenis/kalenislims.git
synced 2023-12-14 07:13:04 +01:00
1233 lines
47 KiB
Python
1233 lines
47 KiB
Python
# This file is part of lims_analysis_sheet module for Tryton.
|
|
# The COPYRIGHT file at the top level of this repository contains
|
|
# the full copyright notices and license terms.
|
|
import operator
|
|
from datetime import datetime, time
|
|
from collections import defaultdict
|
|
from sql import Column, Literal, Cast
|
|
|
|
from trytond.model import ModelView, ModelSQL, fields
|
|
from trytond.wizard import Wizard, StateTransition, StateView, StateAction, \
|
|
Button
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.pyson import Eval, Equal, Bool, If, PYSONEncoder
|
|
from trytond.transaction import Transaction
|
|
|
|
|
|
class Planification(metaclass=PoolMeta):
|
|
__name__ = 'lims.planification'
|
|
|
|
planification_update_draft_sheet = fields.Boolean(
|
|
'Update draft sheets')
|
|
analysis_sheets = fields.One2Many('lims.planification.analysis_sheet',
|
|
'planification', 'Analysis sheets to update', depends=['state'],
|
|
states={'readonly': Eval('state') != 'preplanned'})
|
|
|
|
@staticmethod
|
|
def default_planification_update_draft_sheet():
|
|
Config = Pool().get('lims.configuration')
|
|
return Config(1).planification_update_draft_sheet
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._buttons.update({
|
|
'search_analysis_sheet': {
|
|
'readonly': (Eval('state') != 'draft'),
|
|
},
|
|
})
|
|
|
|
@classmethod
|
|
@ModelView.button_action('lims_analysis_sheet.wiz_search_analysis_sheet')
|
|
def search_analysis_sheet(cls, planifications):
|
|
pass
|
|
|
|
@classmethod
|
|
@ModelView.button_action('lims.wiz_lims_technicians_qualification')
|
|
def confirm(cls, planifications):
|
|
super().confirm(planifications)
|
|
for planification in planifications:
|
|
planification.load_analysis_sheets()
|
|
|
|
def load_analysis_sheets(self):
|
|
pool = Pool()
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
AnalysisSheet = pool.get('lims.analysis_sheet')
|
|
PlanificationAnalysisSheet = pool.get(
|
|
'lims.planification.analysis_sheet')
|
|
|
|
if not self.planification_update_draft_sheet:
|
|
return
|
|
|
|
analysis_sheets = {}
|
|
service_details = PlanificationServiceDetail.search([
|
|
('detail.planification', '=', self.id),
|
|
('notebook_line', '!=', None),
|
|
])
|
|
for service_detail in service_details:
|
|
nl = service_detail.notebook_line
|
|
template_id = nl.get_analysis_sheet_template()
|
|
if not template_id:
|
|
continue
|
|
key = (template_id, service_detail.staff_responsible[0])
|
|
if key not in analysis_sheets:
|
|
analysis_sheets[key] = []
|
|
analysis_sheets[key].append(nl)
|
|
|
|
for key, values in analysis_sheets.items():
|
|
if PlanificationAnalysisSheet.search([
|
|
('planification', '=', self.id),
|
|
('professional', '=', key[1]),
|
|
('analysis_sheet.template', '=', key[0]),
|
|
]):
|
|
continue
|
|
draft_sheet = AnalysisSheet.search([
|
|
('template', '=', key[0]),
|
|
('professional', '=', key[1]),
|
|
('state', '=', 'draft'),
|
|
])
|
|
if not draft_sheet:
|
|
continue
|
|
PlanificationAnalysisSheet.create([{
|
|
'planification': self.id,
|
|
'professional': key[1],
|
|
'analysis_sheet': draft_sheet[0].id,
|
|
}])
|
|
|
|
@classmethod
|
|
def do_confirm(cls, planifications):
|
|
super().do_confirm(planifications)
|
|
for planification in planifications:
|
|
planification.create_analysis_sheets()
|
|
|
|
def create_analysis_sheets(self):
|
|
pool = Pool()
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
AnalysisSheet = pool.get('lims.analysis_sheet')
|
|
PlanificationAnalysisSheet = pool.get(
|
|
'lims.planification.analysis_sheet')
|
|
|
|
analysis_sheets = {}
|
|
service_details = PlanificationServiceDetail.search([
|
|
('detail.planification', '=', self.id),
|
|
('notebook_line', '!=', None),
|
|
])
|
|
for service_detail in service_details:
|
|
nl = service_detail.notebook_line
|
|
template_id = nl.get_analysis_sheet_template()
|
|
if not template_id:
|
|
continue
|
|
key = (template_id, service_detail.staff_responsible[0])
|
|
if key not in analysis_sheets:
|
|
analysis_sheets[key] = []
|
|
analysis_sheets[key].append(nl)
|
|
|
|
date_time = datetime.combine(self.start_date, self.create_date.time())
|
|
|
|
for key, values in analysis_sheets.items():
|
|
planification_sheet = PlanificationAnalysisSheet.search([
|
|
('planification', '=', self.id),
|
|
('professional', '=', key[1]),
|
|
('analysis_sheet.template', '=', key[0]),
|
|
('analysis_sheet.state', 'in', ['draft', 'active']),
|
|
])
|
|
if planification_sheet:
|
|
sheet = AnalysisSheet(planification_sheet[0].analysis_sheet.id)
|
|
else:
|
|
sheet = AnalysisSheet()
|
|
sheet.template = key[0]
|
|
sheet.compilation = sheet.get_new_compilation(
|
|
{'date_time': date_time})
|
|
sheet.professional = key[1]
|
|
sheet.laboratory = self.laboratory.id
|
|
sheet.planification = self.id
|
|
sheet.save()
|
|
sheet.create_lines(values)
|
|
|
|
|
|
class PlanificationAnalysisSheet(ModelSQL, ModelView):
|
|
'Planification - Analysis Sheet'
|
|
__name__ = 'lims.planification.analysis_sheet'
|
|
|
|
planification = fields.Many2One('lims.planification', 'Planification',
|
|
ondelete='CASCADE', select=True, required=True)
|
|
professional = fields.Many2One('lims.laboratory.professional',
|
|
'Laboratory professional', required=True)
|
|
analysis_sheet = fields.Many2One('lims.analysis_sheet',
|
|
'Analysis Sheet', required=True,
|
|
domain=['OR', ('id', '=', Eval('analysis_sheet')),
|
|
[('state', 'in', ['draft', 'active']),
|
|
('professional', '=', Eval('professional'))]],
|
|
depends=['professional'])
|
|
template = fields.Function(fields.Many2One('lims.template.analysis_sheet',
|
|
'Template'), 'on_change_with_template')
|
|
|
|
@fields.depends('analysis_sheet')
|
|
def on_change_with_template(self, name=None):
|
|
if self.analysis_sheet:
|
|
return self.analysis_sheet.template.id
|
|
return None
|
|
|
|
|
|
class SearchAnalysisSheetStart(ModelView):
|
|
'Search Analysis Sheets'
|
|
__name__ = 'lims.planification.search_analysis_sheet.start'
|
|
|
|
date_from = fields.Date('Date from', readonly=True)
|
|
date_to = fields.Date('Date to', readonly=True)
|
|
templates = fields.Many2Many('lims.template.analysis_sheet',
|
|
None, None, 'Templates', required=True,
|
|
domain=[('id', 'in', Eval('templates_domain'))],
|
|
context={'date_from': Eval('date_from'), 'date_to': Eval('date_to')},
|
|
depends=['templates_domain', 'date_from', 'date_to'])
|
|
templates_domain = fields.One2Many('lims.template.analysis_sheet',
|
|
None, 'Templates domain')
|
|
|
|
|
|
class SearchAnalysisSheetNext(ModelView):
|
|
'Search Analysis Sheets'
|
|
__name__ = 'lims.planification.search_analysis_sheet.next'
|
|
|
|
details = fields.Many2Many(
|
|
'lims.planification.search_fractions.detail',
|
|
None, None, 'Fractions to plan', depends=['details_domain'],
|
|
domain=[('id', 'in', Eval('details_domain'))], required=True)
|
|
details_domain = fields.One2Many(
|
|
'lims.planification.search_fractions.detail',
|
|
None, 'Fractions domain')
|
|
|
|
|
|
class SearchAnalysisSheet(Wizard):
|
|
'Search Analysis Sheets'
|
|
__name__ = 'lims.planification.search_analysis_sheet'
|
|
|
|
start = StateView('lims.planification.search_analysis_sheet.start',
|
|
'lims_analysis_sheet.planification_search_analysis_sheet_start'
|
|
'_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Search', 'search', 'tryton-forward', default=True),
|
|
])
|
|
search = StateTransition()
|
|
next = StateView('lims.planification.search_analysis_sheet.next',
|
|
'lims_analysis_sheet.planification_search_analysis_sheet_next'
|
|
'_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Add', 'add', 'tryton-ok', default=True),
|
|
])
|
|
add = StateTransition()
|
|
|
|
def default_start(self, fields):
|
|
Planification = Pool().get('lims.planification')
|
|
planification = Planification(Transaction().context['active_id'])
|
|
templates_domain = self._get_templates(planification)
|
|
return {
|
|
'templates': [],
|
|
'templates_domain': templates_domain,
|
|
'date_from': planification.date_from,
|
|
'date_to': planification.date_to,
|
|
}
|
|
|
|
def _get_templates(self, planification):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
PlanificationDetail = pool.get('lims.planification.detail')
|
|
Planification = pool.get('lims.planification')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
Notebook = pool.get('lims.notebook')
|
|
Fraction = pool.get('lims.fraction')
|
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
|
Analysis = pool.get('lims.analysis')
|
|
Template = pool.get('lims.template.analysis_sheet')
|
|
TemplateAnalysis = pool.get('lims.template.analysis_sheet.analysis')
|
|
|
|
cursor.execute('SELECT nl.id '
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table +
|
|
'" psd ON psd.notebook_line = nl.id '
|
|
'INNER JOIN "' + PlanificationDetail._table + '" pd '
|
|
'ON psd.detail = pd.id '
|
|
'INNER JOIN "' + Planification._table + '" p '
|
|
'ON pd.planification = p.id '
|
|
'WHERE p.state = \'preplanned\' '
|
|
'OR p.id = %s',
|
|
(str(planification.id),))
|
|
planned_lines = [x[0] for x in cursor.fetchall()]
|
|
planned_lines_ids = ', '.join(str(x) for x in [0] + planned_lines)
|
|
preplanned_where = 'AND nl.id NOT IN (%s) ' % planned_lines_ids
|
|
|
|
dates_where = ''
|
|
if planification.date_from:
|
|
dates_where += ('AND ad.confirmation_date::date >= \'%s\'::date ' %
|
|
planification.date_from)
|
|
if planification.date_to:
|
|
dates_where += ('AND ad.confirmation_date::date <= \'%s\'::date ' %
|
|
planification.date_to)
|
|
|
|
sql_select = 'SELECT nl.analysis, nl.method '
|
|
sql_from = (
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + Analysis._table + '" nla '
|
|
'ON nla.id = nl.analysis '
|
|
'INNER JOIN "' + Notebook._table + '" nb '
|
|
'ON nb.id = nl.notebook '
|
|
'INNER JOIN "' + Fraction._table + '" frc '
|
|
'ON frc.id = nb.fraction '
|
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
|
|
'ON ad.id = nl.analysis_detail ')
|
|
sql_where = (
|
|
'WHERE ad.plannable = TRUE '
|
|
'AND nl.start_date IS NULL '
|
|
'AND nl.annulled = FALSE '
|
|
'AND nl.laboratory = %s '
|
|
'AND nla.behavior != \'internal_relation\' ' +
|
|
preplanned_where + dates_where)
|
|
|
|
with Transaction().set_user(0):
|
|
cursor.execute(sql_select + sql_from + sql_where,
|
|
(planification.laboratory.id,))
|
|
notebook_lines = cursor.fetchall()
|
|
if not notebook_lines:
|
|
return []
|
|
|
|
result = []
|
|
for nl in notebook_lines:
|
|
cursor.execute('SELECT t.id '
|
|
'FROM "' + Template._table + '" t '
|
|
'INNER JOIN "' + TemplateAnalysis._table + '" ta '
|
|
'ON t.id = ta.template '
|
|
'WHERE t.active IS TRUE '
|
|
'AND ta.analysis = %s '
|
|
'AND (ta.method = %s OR ta.method IS NULL)',
|
|
(nl[0], nl[1]))
|
|
template = cursor.fetchone()
|
|
if template:
|
|
result.append(template[0])
|
|
return list(set(result))
|
|
|
|
def transition_search(self):
|
|
pool = Pool()
|
|
Planification = pool.get('lims.planification')
|
|
SearchFractionsDetail = pool.get(
|
|
'lims.planification.search_fractions.detail')
|
|
|
|
planification = Planification(Transaction().context['active_id'])
|
|
data = self._get_service_details(planification)
|
|
|
|
to_create = []
|
|
for k, v in data.items():
|
|
to_create.append({
|
|
'session_id': self._session_id,
|
|
'fraction': k[0],
|
|
'service_analysis': k[1],
|
|
'repetition': v['repetition'],
|
|
})
|
|
fractions_added = SearchFractionsDetail.create(to_create)
|
|
|
|
self.next.details = fractions_added
|
|
return 'next'
|
|
|
|
def default_next(self, fields):
|
|
details = [d.id for d in self.next.details]
|
|
self.next.details = None
|
|
return {
|
|
'details': [],
|
|
'details_domain': details,
|
|
}
|
|
|
|
def transition_add(self):
|
|
pool = Pool()
|
|
Planification = pool.get('lims.planification')
|
|
PlanificationDetail = pool.get('lims.planification.detail')
|
|
PlanificationAnalysis = pool.get('lims.planification-analysis')
|
|
|
|
planification = Planification(Transaction().context['active_id'])
|
|
|
|
records_added = ['(%s,%s)' % (d.fraction.id, d.service_analysis.id)
|
|
for d in self.next.details]
|
|
records_ids_added = ', '.join(str(x)
|
|
for x in ['(0,0)'] + records_added)
|
|
extra_where = (
|
|
'AND (nb.fraction, srv.analysis) IN (' + records_ids_added + ') ')
|
|
|
|
data = self._get_service_details(planification, extra_where)
|
|
|
|
details_to_create = []
|
|
for k, v in data.items():
|
|
details = PlanificationDetail.search([
|
|
('planification', '=', planification.id),
|
|
('fraction', '=', k[0]),
|
|
('service_analysis', '=', k[1]),
|
|
])
|
|
if details:
|
|
PlanificationDetail.write([details[0]], {
|
|
'details': [('create', v)],
|
|
})
|
|
else:
|
|
details_to_create.append({
|
|
'planification': planification.id,
|
|
'fraction': k[0],
|
|
'service_analysis': k[1],
|
|
'details': [('create', v)],
|
|
})
|
|
if details_to_create:
|
|
PlanificationDetail.create(details_to_create)
|
|
|
|
analysis_to_create = []
|
|
for a_id in list(set(k[1] for k in list(data.keys()))):
|
|
if not PlanificationAnalysis.search([
|
|
('planification', '=', planification.id),
|
|
('analysis', '=', a_id),
|
|
]):
|
|
analysis_to_create.append({
|
|
'planification': planification.id,
|
|
'analysis': a_id,
|
|
})
|
|
if analysis_to_create:
|
|
PlanificationAnalysis.create(analysis_to_create)
|
|
|
|
return 'end'
|
|
|
|
def _get_service_details(self, planification, extra_where=''):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
Notebook = pool.get('lims.notebook')
|
|
Fraction = pool.get('lims.fraction')
|
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
|
Service = pool.get('lims.service')
|
|
Analysis = pool.get('lims.analysis')
|
|
TemplateAnalysis = pool.get('lims.template.analysis_sheet.analysis')
|
|
|
|
template_analysis = {}
|
|
for template in self.start.templates:
|
|
cursor.execute('SELECT analysis, method '
|
|
'FROM "' + TemplateAnalysis._table + '" '
|
|
'WHERE template = %s',
|
|
(template.id,))
|
|
for res in cursor.fetchall():
|
|
if res[0] not in template_analysis:
|
|
template_analysis[res[0]] = []
|
|
if res[1]:
|
|
template_analysis[res[0]].append(res[1])
|
|
if not template_analysis:
|
|
return {}
|
|
all_included_analysis_ids = ', '.join(str(x)
|
|
for x in list(template_analysis.keys()))
|
|
service_where = 'AND ad.analysis IN (%s) ' % all_included_analysis_ids
|
|
|
|
planification_details = PlanificationServiceDetail.search([['OR',
|
|
('planification.state', '=', 'preplanned'),
|
|
('planification', '=', planification.id)],
|
|
('notebook_line', '!=', None),
|
|
])
|
|
planned_lines = [pd.notebook_line.id for pd in planification_details]
|
|
planned_lines_ids = ', '.join(str(x) for x in [0] + planned_lines)
|
|
preplanned_where = 'AND nl.id NOT IN (%s) ' % planned_lines_ids
|
|
|
|
dates_where = ''
|
|
if planification.date_from:
|
|
dates_where += ('AND ad.confirmation_date::date >= \'%s\'::date ' %
|
|
planification.date_from)
|
|
if planification.date_to:
|
|
dates_where += ('AND ad.confirmation_date::date <= \'%s\'::date ' %
|
|
planification.date_to)
|
|
|
|
sql_select = ('SELECT nl.id, nb.fraction, srv.analysis' +
|
|
', nl.analysis, nl.method, nl.repetition != 0 ')
|
|
|
|
sql_from = (
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + Analysis._table + '" nla '
|
|
'ON nla.id = nl.analysis '
|
|
'INNER JOIN "' + Notebook._table + '" nb '
|
|
'ON nb.id = nl.notebook '
|
|
'INNER JOIN "' + Fraction._table + '" frc '
|
|
'ON frc.id = nb.fraction '
|
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
|
|
'ON ad.id = nl.analysis_detail '
|
|
'INNER JOIN "' + Service._table + '" srv '
|
|
'ON srv.id = nl.service ')
|
|
|
|
sql_where = (
|
|
'WHERE ad.plannable = TRUE '
|
|
'AND nl.start_date IS NULL '
|
|
'AND nl.annulled = FALSE '
|
|
'AND nl.laboratory = %s '
|
|
'AND nla.behavior != \'internal_relation\' ' +
|
|
preplanned_where + dates_where + service_where + extra_where)
|
|
|
|
sql_order = (
|
|
'ORDER BY nb.fraction ASC, srv.analysis ASC')
|
|
|
|
with Transaction().set_user(0):
|
|
cursor.execute(sql_select + sql_from + sql_where + sql_order,
|
|
(planification.laboratory.id,))
|
|
notebook_lines = cursor.fetchall()
|
|
if not notebook_lines:
|
|
return {}
|
|
|
|
result = {}
|
|
nlines_added = []
|
|
if extra_where:
|
|
for nl in notebook_lines:
|
|
if (template_analysis[nl[3]] and
|
|
nl[4] not in template_analysis[nl[3]]):
|
|
continue
|
|
f_ = nl[1]
|
|
s_ = nl[2]
|
|
if (f_, s_) not in result:
|
|
result[(f_, s_)] = []
|
|
if nl[0] not in nlines_added:
|
|
nlines_added.append(nl[0])
|
|
result[(f_, s_)].append({
|
|
'notebook_line': nl[0],
|
|
'planned_service': nl[2],
|
|
})
|
|
else:
|
|
for nl in notebook_lines:
|
|
if (template_analysis[nl[3]] and
|
|
nl[4] not in template_analysis[nl[3]]):
|
|
continue
|
|
f_ = nl[1]
|
|
s_ = nl[2]
|
|
result[(f_, s_)] = {
|
|
'repetition': nl[5],
|
|
}
|
|
|
|
return result
|
|
|
|
|
|
class RelateTechniciansStart(metaclass=PoolMeta):
|
|
__name__ = 'lims.planification.relate_technicians.start'
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
grouping = ('analysis_sheet', 'Analysis sheet')
|
|
if grouping not in cls.grouping.selection:
|
|
cls.grouping.selection.append(grouping)
|
|
|
|
|
|
class RelateTechniciansResult(metaclass=PoolMeta):
|
|
__name__ = 'lims.planification.relate_technicians.result'
|
|
|
|
details4 = fields.Many2Many(
|
|
'lims.planification.relate_technicians.detail4', None, None,
|
|
'Fractions to plan', domain=[('id', 'in', Eval('details4_domain'))],
|
|
states={'invisible': ~Bool(Equal(Eval('grouping'), 'analysis_sheet'))},
|
|
depends=['details4_domain', 'grouping'])
|
|
details4_domain = fields.One2Many(
|
|
'lims.planification.relate_technicians.detail4', None,
|
|
'Fractions domain')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
grouping = ('analysis_sheet', 'Analysis sheet')
|
|
if grouping not in cls.grouping.selection:
|
|
cls.grouping.selection.append(grouping)
|
|
|
|
@fields.depends('grouping')
|
|
def on_change_grouping(self):
|
|
super().on_change_grouping()
|
|
self.details4 = []
|
|
|
|
|
|
class RelateTechniciansDetail4(ModelSQL, ModelView):
|
|
'Fraction Detail'
|
|
__name__ = 'lims.planification.relate_technicians.detail4'
|
|
_table = 'lims_planification_relate_technicians_d4'
|
|
|
|
fraction = fields.Many2One('lims.fraction', 'Fraction')
|
|
template = fields.Many2One('lims.template.analysis_sheet',
|
|
'Analysis sheet')
|
|
services_list = fields.Char('Services')
|
|
session_id = fields.Integer('Session ID')
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
super().__register__(module_name)
|
|
cursor = Transaction().connection.cursor()
|
|
cursor.execute('DELETE FROM "' + cls._table + '"')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._order.insert(0, ('fraction', 'ASC'))
|
|
cls._order.insert(1, ('template', 'ASC'))
|
|
|
|
|
|
class RelateTechnicians(metaclass=PoolMeta):
|
|
__name__ = 'lims.planification.relate_technicians'
|
|
|
|
def transition_search(self):
|
|
planification_id = Transaction().context['active_id']
|
|
|
|
self.result.details4_domain = []
|
|
|
|
if self.start.grouping == 'analysis_sheet':
|
|
self.result.details4_domain = self._view_details4(planification_id,
|
|
self.start.exclude_relateds)
|
|
return super().transition_search()
|
|
|
|
def default_result(self, fields):
|
|
res = super().default_result(fields)
|
|
details4_domain = []
|
|
if self.result.details4_domain:
|
|
details4_domain = [d.id for d in self.result.details4_domain]
|
|
res['details4_domain'] = details4_domain
|
|
return res
|
|
|
|
def _view_details4(self, planification_id, exclude_relateds):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
PlanificationDetail = pool.get('lims.planification.detail')
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
ServiceDetailProfessional = pool.get(
|
|
'lims.planification.service_detail-laboratory.professional')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
RelateTechniciansDetail4 = pool.get(
|
|
'lims.planification.relate_technicians.detail4')
|
|
Template = pool.get('lims.template.analysis_sheet')
|
|
TemplateAnalysis = pool.get('lims.template.analysis_sheet.analysis')
|
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
|
Service = pool.get('lims.service')
|
|
|
|
exclude_relateds_clause = ''
|
|
if exclude_relateds:
|
|
exclude_relateds_clause = (' AND sd.id NOT IN ('
|
|
'SELECT sdp.detail '
|
|
'FROM "' + ServiceDetailProfessional._table + '" sdp '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table + '" sd'
|
|
' ON sdp.detail = sd.id '
|
|
'INNER JOIN "' + PlanificationDetail._table + '" d'
|
|
' ON sd.detail = d.id '
|
|
'WHERE d.planification = %s'
|
|
')' % planification_id)
|
|
|
|
details4 = {}
|
|
cursor.execute('SELECT d.fraction, nl.analysis, nl.method, '
|
|
'ad.service '
|
|
'FROM "' + PlanificationDetail._table + '" d '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table + '" sd '
|
|
'ON sd.detail = d.id '
|
|
'INNER JOIN "' + NotebookLine._table + '" nl '
|
|
'ON sd.notebook_line = nl.id '
|
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
|
|
'ON nl.analysis_detail = ad.id '
|
|
'WHERE d.planification = %s' +
|
|
exclude_relateds_clause,
|
|
(planification_id,))
|
|
for x in cursor.fetchall():
|
|
cursor.execute('SELECT t.id '
|
|
'FROM "' + Template._table + '" t '
|
|
'INNER JOIN "' + TemplateAnalysis._table + '" ta '
|
|
'ON t.id = ta.template '
|
|
'WHERE t.active IS TRUE '
|
|
'AND ta.analysis = %s '
|
|
'AND (ta.method = %s OR ta.method IS NULL)',
|
|
(x[1], x[2]))
|
|
template = cursor.fetchone()
|
|
t = template and template[0] or None
|
|
f = x[0]
|
|
if (f, t) not in details4:
|
|
details4[(f, t)] = {
|
|
'fraction': f,
|
|
'template': t,
|
|
'service_ids': [],
|
|
}
|
|
details4[(f, t)]['service_ids'].append(x[3])
|
|
|
|
to_create = []
|
|
for d in details4.values():
|
|
services = Service.browse(list(set(d['service_ids'])))
|
|
to_create.append({
|
|
'session_id': self._session_id,
|
|
'fraction': d['fraction'],
|
|
'template': d['template'],
|
|
'services_list': ' // '.join(
|
|
s.analysis.rec_name for s in services),
|
|
})
|
|
return RelateTechniciansDetail4.create(to_create)
|
|
|
|
def _get_details(self, planification_id):
|
|
details = super()._get_details(planification_id)
|
|
if self.start.grouping == 'analysis_sheet':
|
|
details = self._get_details4(planification_id,
|
|
self.start.exclude_relateds)
|
|
return details
|
|
|
|
def _get_details4(self, planification_id, exclude_relateds):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
PlanificationDetail = pool.get(
|
|
'lims.planification.detail')
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
ServiceDetailProfessional = pool.get(
|
|
'lims.planification.service_detail-laboratory.professional')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
TemplateAnalysis = pool.get('lims.template.analysis_sheet.analysis')
|
|
|
|
exclude_relateds_clause = ''
|
|
if exclude_relateds:
|
|
exclude_relateds_clause = (' AND sd.id NOT IN ('
|
|
'SELECT sdp.detail '
|
|
'FROM "' + ServiceDetailProfessional._table + '" sdp '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table + '" sd'
|
|
' ON sdp.detail = sd.id '
|
|
'INNER JOIN "' + PlanificationDetail._table + '" d'
|
|
' ON sd.detail = d.id '
|
|
'WHERE d.planification = %s'
|
|
')' % planification_id)
|
|
|
|
details = []
|
|
for detail in self.result.details4:
|
|
|
|
template_analysis = {}
|
|
cursor.execute('SELECT analysis, method '
|
|
'FROM "' + TemplateAnalysis._table + '" '
|
|
'WHERE template = %s',
|
|
(detail.template and detail.template.id or None,))
|
|
for res in cursor.fetchall():
|
|
if res[0] not in template_analysis:
|
|
template_analysis[res[0]] = []
|
|
if res[1]:
|
|
template_analysis[res[0]].append(res[1])
|
|
if not template_analysis:
|
|
continue
|
|
all_included_analysis_ids = ', '.join(str(x)
|
|
for x in list(template_analysis.keys()))
|
|
analysis_where = ('AND nl.analysis IN (' +
|
|
all_included_analysis_ids + ') ')
|
|
|
|
cursor.execute('SELECT sd.id, nl.analysis, nl.method '
|
|
'FROM "' + PlanificationDetail._table + '" d '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table + '" sd'
|
|
' ON sd.detail = d.id '
|
|
'INNER JOIN "' + NotebookLine._table + '" nl '
|
|
'ON sd.notebook_line = nl.id '
|
|
'WHERE d.planification = %s '
|
|
'AND d.fraction = %s ' +
|
|
analysis_where + exclude_relateds_clause,
|
|
(planification_id, detail.fraction.id))
|
|
for x in cursor.fetchall():
|
|
if (template_analysis[x[1]] and
|
|
x[2] not in template_analysis[x[1]]):
|
|
continue
|
|
details.append(x[0])
|
|
|
|
return PlanificationServiceDetail.browse(details)
|
|
|
|
|
|
class LaboratoryProfessional(metaclass=PoolMeta):
|
|
__name__ = 'lims.laboratory.professional'
|
|
|
|
sheets_queue = fields.Function(fields.Integer('# Sheets in queue'),
|
|
'get_professional')
|
|
sheets_process = fields.Function(fields.Integer('# Sheets in process'),
|
|
'get_professional')
|
|
samples_qty = fields.Function(fields.Integer('# Samples'),
|
|
'get_professional')
|
|
|
|
@classmethod
|
|
def get_professional(cls, records, name):
|
|
pool = Pool()
|
|
Sheet = pool.get('lims.analysis_sheet')
|
|
|
|
res = defaultdict(int)
|
|
clause = [('state', 'in', ['draft', 'active'])]
|
|
|
|
context = Transaction().context
|
|
if context.get('laboratory'):
|
|
clause.append(('laboratory', '=', context.get('laboratory')))
|
|
if context.get('from_date'):
|
|
clause.append(('date', '>=', datetime.combine(
|
|
context.get('from_date'), time(0, 0))))
|
|
if context.get('to_date'):
|
|
clause.append(('date', '<=', datetime.combine(
|
|
context.get('to_date'), time(23, 59))))
|
|
|
|
sheets = Sheet.search(clause)
|
|
for sheet in sheets:
|
|
if name == 'sheets_queue' and sheet.state == 'draft':
|
|
res[sheet.professional.id] += 1
|
|
if name == 'sheets_process' and sheet.state == 'active':
|
|
res[sheet.professional.id] += 1
|
|
if name == 'samples_qty':
|
|
res[sheet.professional.id] += sheet.samples_qty
|
|
return res
|
|
|
|
|
|
class PlanificationProfessional(ModelSQL, ModelView):
|
|
'Planification Professional'
|
|
__name__ = 'lims.planification.professional'
|
|
|
|
name = fields.Char('Name')
|
|
sheets_queue = fields.Function(fields.Integer('# Sheets in queue'),
|
|
'get_professional', searcher='search_professional')
|
|
sheets_process = fields.Function(fields.Integer('# Sheets in process'),
|
|
'get_professional', searcher='search_professional')
|
|
samples_qty = fields.Function(fields.Integer('# Samples'),
|
|
'get_professional', searcher='search_professional')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._order.insert(0, ('name', 'ASC'))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
pool = Pool()
|
|
Professional = pool.get('lims.laboratory.professional')
|
|
Party = pool.get('party.party')
|
|
professional = Professional.__table__()
|
|
party = Party.__table__()
|
|
columns = []
|
|
for fname, field in cls._fields.items():
|
|
if hasattr(field, 'set'):
|
|
continue
|
|
if fname == 'name':
|
|
column = Column(party, 'name').as_(fname)
|
|
else:
|
|
column = Column(professional, fname).as_(fname)
|
|
columns.append(column)
|
|
return professional.join(
|
|
party, condition=professional.party == party.id).select(*columns)
|
|
|
|
@classmethod
|
|
def get_professional(cls, records, name):
|
|
pool = Pool()
|
|
Professional = pool.get('lims.laboratory.professional')
|
|
|
|
professionals = Professional.browse(records)
|
|
return {p.id: getattr(p, name) for p in professionals}
|
|
|
|
@classmethod
|
|
def search_professional(cls, name, domain):
|
|
pool = Pool()
|
|
Professional = pool.get('lims.laboratory.professional')
|
|
|
|
professionals = Professional.search([], order=[])
|
|
|
|
_, operator_, operand = domain
|
|
operator_ = {
|
|
'=': operator.eq,
|
|
'>=': operator.ge,
|
|
'>': operator.gt,
|
|
'<=': operator.le,
|
|
'<': operator.lt,
|
|
'!=': operator.ne,
|
|
'in': lambda v, l: v in l,
|
|
'not in': lambda v, l: v not in l,
|
|
}.get(operator_, lambda v, l: False)
|
|
|
|
ids = [p.id for p in professionals
|
|
if operator_(getattr(p, name), operand)]
|
|
return [('id', 'in', ids)]
|
|
|
|
def get_rec_name(self, name):
|
|
return self.name
|
|
|
|
|
|
class PlanificationProfessionalContext(ModelView):
|
|
'Planification Professional Context'
|
|
__name__ = 'lims.planification.professional.context'
|
|
laboratory = fields.Many2One('lims.laboratory', 'Laboratory')
|
|
from_date = fields.Date("From Date",
|
|
domain=[
|
|
If(Eval('to_date') & Eval('from_date'),
|
|
('from_date', '<=', Eval('to_date')),
|
|
()),
|
|
],
|
|
depends=['to_date'])
|
|
to_date = fields.Date("To Date",
|
|
domain=[
|
|
If(Eval('from_date') & Eval('to_date'),
|
|
('to_date', '>=', Eval('from_date')),
|
|
()),
|
|
],
|
|
depends=['from_date'])
|
|
|
|
@classmethod
|
|
def default_laboratory(cls):
|
|
return Transaction().context.get('laboratory')
|
|
|
|
@classmethod
|
|
def default_from_date(cls):
|
|
return Transaction().context.get('from_date')
|
|
|
|
@classmethod
|
|
def default_to_date(cls):
|
|
return Transaction().context.get('to_date')
|
|
|
|
|
|
class PlanificationProfessionalLine(ModelSQL, ModelView):
|
|
'Planification Professional Line'
|
|
__name__ = 'lims.planification.professional.line'
|
|
|
|
template = fields.Many2One('lims.template.analysis_sheet', 'Template')
|
|
laboratory = fields.Many2One('lims.laboratory', 'Laboratory')
|
|
professional = fields.Many2One('lims.laboratory.professional',
|
|
'Professional')
|
|
date = fields.Date('Date')
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('active', 'Active'),
|
|
('validated', 'Validated'),
|
|
('done', 'Done'),
|
|
], 'State')
|
|
samples_qty = fields.Function(fields.Integer('# Samples'),
|
|
'get_fields')
|
|
completion_percentage = fields.Function(fields.Numeric('Complete',
|
|
digits=(1, 4), domain=[
|
|
('completion_percentage', '>=', 0),
|
|
('completion_percentage', '<=', 1),
|
|
]),
|
|
'get_fields')
|
|
color = fields.Function(fields.Char('Color'), 'get_color')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._order.insert(0, ('date', 'ASC'))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
pool = Pool()
|
|
Sheet = pool.get('lims.analysis_sheet')
|
|
Compilation = pool.get('lims.interface.compilation')
|
|
sheet = Sheet.__table__()
|
|
compilation = Compilation.__table__()
|
|
|
|
context = Transaction().context
|
|
where = Literal(True)
|
|
if context.get('laboratory'):
|
|
where &= sheet.laboratory == context.get('laboratory')
|
|
if context.get('from_date'):
|
|
where &= compilation.date_time >= datetime.combine(
|
|
context.get('from_date'), time(0, 0))
|
|
if context.get('to_date'):
|
|
where &= compilation.date_time <= datetime.combine(
|
|
context.get('to_date'), time(23, 59))
|
|
|
|
columns = []
|
|
for fname, field in cls._fields.items():
|
|
if hasattr(field, 'set'):
|
|
continue
|
|
if fname == 'date':
|
|
column = Cast(compilation.date_time, 'date').as_(fname)
|
|
else:
|
|
column = Column(sheet, fname).as_(fname)
|
|
columns.append(column)
|
|
return sheet.join(compilation,
|
|
condition=sheet.compilation == compilation.id).select(*columns,
|
|
where=where)
|
|
|
|
@classmethod
|
|
def get_fields(cls, records, name):
|
|
pool = Pool()
|
|
Sheet = pool.get('lims.analysis_sheet')
|
|
|
|
sheets = Sheet.browse(records)
|
|
return {s.id: getattr(s, name) for s in sheets}
|
|
|
|
def get_color(self, name):
|
|
return 'lightblue'
|
|
|
|
|
|
class OpenSheetSample(Wizard):
|
|
'Open Sheet Sample'
|
|
__name__ = 'lims.planification.professional.open_sheet_sample'
|
|
start_state = 'open_'
|
|
open_ = StateAction('lims.act_lims_sample_list')
|
|
|
|
def do_open_(self, action):
|
|
pool = Pool()
|
|
Sheet = pool.get('lims.analysis_sheet')
|
|
Data = pool.get('lims.interface.data')
|
|
|
|
sheet = Sheet(Transaction().context['active_id'])
|
|
|
|
with Transaction().set_context(
|
|
lims_interface_table=sheet.compilation.table.id):
|
|
lines = Data.search([('compilation', '=', sheet.compilation.id)])
|
|
samples = []
|
|
for line in lines:
|
|
nl = line.notebook_line
|
|
if not nl:
|
|
continue
|
|
if nl.sample.id not in samples:
|
|
samples.append(nl.sample.id)
|
|
|
|
action['pyson_domain'] = [
|
|
('id', 'in', samples),
|
|
]
|
|
action['pyson_domain'] = PYSONEncoder().encode(action['pyson_domain'])
|
|
return action, {}
|
|
|
|
|
|
class SamplesPendingPlanning(ModelSQL, ModelView):
|
|
'Samples Pending Planning'
|
|
__name__ = 'lims.sample_pending_planning'
|
|
|
|
name = fields.Char('Name')
|
|
samples_qty = fields.Function(fields.Integer('# Samples'),
|
|
'get_samples_qty')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._order.insert(0, ('name', 'ASC'))
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
PlanificationDetail = pool.get('lims.planification.detail')
|
|
Planification = pool.get('lims.planification')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
Notebook = pool.get('lims.notebook')
|
|
Fraction = pool.get('lims.fraction')
|
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
|
Analysis = pool.get('lims.analysis')
|
|
TemplateAnalysis = pool.get('lims.template.analysis_sheet.analysis')
|
|
Template = pool.get('lims.template.analysis_sheet')
|
|
template = Template.__table__()
|
|
|
|
context = Transaction().context
|
|
|
|
cursor.execute('SELECT nl.id '
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table +
|
|
'" psd ON psd.notebook_line = nl.id '
|
|
'INNER JOIN "' + PlanificationDetail._table + '" pd '
|
|
'ON psd.detail = pd.id '
|
|
'INNER JOIN "' + Planification._table + '" p '
|
|
'ON pd.planification = p.id '
|
|
'WHERE p.state = \'preplanned\' ')
|
|
planned_lines = [x[0] for x in cursor.fetchall()]
|
|
planned_lines_ids = ', '.join(str(x)
|
|
for x in [0] + planned_lines)
|
|
preplanned_where = 'AND nl.id NOT IN (%s) ' % planned_lines_ids
|
|
|
|
sql_select = 'SELECT nl.analysis, nl.method '
|
|
sql_from = (
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + Analysis._table + '" nla '
|
|
'ON nla.id = nl.analysis '
|
|
'INNER JOIN "' + Notebook._table + '" nb '
|
|
'ON nb.id = nl.notebook '
|
|
'INNER JOIN "' + Fraction._table + '" frc '
|
|
'ON frc.id = nb.fraction '
|
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
|
|
'ON ad.id = nl.analysis_detail ')
|
|
sql_where = (
|
|
'WHERE ad.plannable = TRUE '
|
|
'AND nl.start_date IS NULL '
|
|
'AND nl.annulled = FALSE '
|
|
'AND nla.behavior != \'internal_relation\' ' +
|
|
preplanned_where)
|
|
params = []
|
|
|
|
if context.get('laboratory'):
|
|
sql_where += 'AND nl.laboratory = %s '
|
|
params.append(context.get('laboratory'))
|
|
if context.get('department'):
|
|
sql_where += 'AND nl.department = %s '
|
|
params.append(context.get('department'))
|
|
if context.get('date_from'):
|
|
sql_where += 'AND ad.confirmation_date::date >= %s::date '
|
|
params.append(context.get('date_from'))
|
|
if context.get('date_to'):
|
|
sql_where += 'AND ad.confirmation_date::date <= %s::date '
|
|
params.append(context.get('date_to'))
|
|
|
|
with Transaction().set_user(0):
|
|
cursor.execute(sql_select + sql_from + sql_where, tuple(params))
|
|
notebook_lines = cursor.fetchall()
|
|
|
|
result = []
|
|
for nl in notebook_lines:
|
|
cursor.execute('SELECT t.id '
|
|
'FROM "' + Template._table + '" t '
|
|
'INNER JOIN "' + TemplateAnalysis._table + '" ta '
|
|
'ON t.id = ta.template '
|
|
'WHERE t.active IS TRUE '
|
|
'AND ta.analysis = %s '
|
|
'AND (ta.method = %s OR ta.method IS NULL)',
|
|
(nl[0], nl[1]))
|
|
template_id = cursor.fetchone()
|
|
if template_id:
|
|
result.append(template_id[0])
|
|
template_ids = list(set(result))
|
|
|
|
where = (template.id.in_(template_ids))
|
|
if not template_ids:
|
|
where = (template.id == -1)
|
|
columns = []
|
|
for fname, field in cls._fields.items():
|
|
if hasattr(field, 'set'):
|
|
continue
|
|
columns.append(Column(template, fname).as_(fname))
|
|
return template.select(*columns, where=where)
|
|
|
|
@classmethod
|
|
def get_samples_qty(cls, records, name):
|
|
pool = Pool()
|
|
Template = pool.get('lims.template.analysis_sheet')
|
|
|
|
context = Transaction().context
|
|
with Transaction().set_context(
|
|
date_from=context.get('date_from') or datetime.min,
|
|
date_to=context.get('date_to') or datetime.max,
|
|
laboratory=context.get('laboratory'),
|
|
department=context.get('department')):
|
|
templates = Template.browse(records)
|
|
return {t.id: getattr(t, 'pending_fractions') for t in templates}
|
|
|
|
def get_rec_name(self, name):
|
|
return self.name
|
|
|
|
|
|
class SamplesPendingPlanningContext(ModelView):
|
|
'Samples Pending Planning Context'
|
|
__name__ = 'lims.sample_pending_planning.context'
|
|
|
|
laboratory = fields.Many2One('lims.laboratory', 'Laboratory')
|
|
department = fields.Many2One('company.department', 'Department')
|
|
date_from = fields.Date("From Date",
|
|
domain=[
|
|
If(Eval('date_to') & Eval('date_from'),
|
|
('date_from', '<=', Eval('date_to')),
|
|
()),
|
|
],
|
|
depends=['date_to'])
|
|
date_to = fields.Date("To Date",
|
|
domain=[
|
|
If(Eval('date_from') & Eval('date_to'),
|
|
('date_to', '>=', Eval('date_from')),
|
|
()),
|
|
],
|
|
depends=['date_from'])
|
|
|
|
@classmethod
|
|
def default_laboratory(cls):
|
|
return Transaction().context.get('laboratory')
|
|
|
|
@classmethod
|
|
def default_date_from(cls):
|
|
return Transaction().context.get('date_from')
|
|
|
|
@classmethod
|
|
def default_date_to(cls):
|
|
return Transaction().context.get('date_to')
|
|
|
|
|
|
class OpenPendingPlanningSample(Wizard):
|
|
'Open Pending Planning Sample'
|
|
__name__ = 'lims.sample_pending_planning.open_sample'
|
|
|
|
start_state = 'open_'
|
|
open_ = StateAction('lims.act_lims_sample_list')
|
|
|
|
def do_open_(self, action):
|
|
cursor = Transaction().connection.cursor()
|
|
pool = Pool()
|
|
Template = pool.get('lims.template.analysis_sheet')
|
|
PlanificationServiceDetail = pool.get(
|
|
'lims.planification.service_detail')
|
|
PlanificationDetail = pool.get('lims.planification.detail')
|
|
Planification = pool.get('lims.planification')
|
|
NotebookLine = pool.get('lims.notebook.line')
|
|
Notebook = pool.get('lims.notebook')
|
|
Fraction = pool.get('lims.fraction')
|
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
|
Analysis = pool.get('lims.analysis')
|
|
|
|
context = Transaction().context
|
|
template = Template(context['active_id'])
|
|
template_analysis = {}
|
|
for analysis in template.analysis:
|
|
if analysis.analysis.id not in template_analysis:
|
|
template_analysis[analysis.analysis.id] = []
|
|
if analysis.method:
|
|
template_analysis[analysis.analysis.id].append(
|
|
analysis.method.id)
|
|
|
|
cursor.execute('SELECT nl.id '
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + PlanificationServiceDetail._table +
|
|
'" psd ON psd.notebook_line = nl.id '
|
|
'INNER JOIN "' + PlanificationDetail._table + '" pd '
|
|
'ON psd.detail = pd.id '
|
|
'INNER JOIN "' + Planification._table + '" p '
|
|
'ON pd.planification = p.id '
|
|
'WHERE p.state = \'preplanned\' ')
|
|
planned_lines = [x[0] for x in cursor.fetchall()]
|
|
planned_lines_ids = ', '.join(str(x)
|
|
for x in [0] + planned_lines)
|
|
preplanned_where = 'AND nl.id NOT IN (%s) ' % planned_lines_ids
|
|
|
|
analysis_ids = ', '.join(str(x) for x in template_analysis.keys())
|
|
sql_select = 'SELECT nl.analysis, nl.method, frc.sample '
|
|
sql_from = (
|
|
'FROM "' + NotebookLine._table + '" nl '
|
|
'INNER JOIN "' + Analysis._table + '" nla '
|
|
'ON nla.id = nl.analysis '
|
|
'INNER JOIN "' + Notebook._table + '" nb '
|
|
'ON nb.id = nl.notebook '
|
|
'INNER JOIN "' + Fraction._table + '" frc '
|
|
'ON frc.id = nb.fraction '
|
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
|
|
'ON ad.id = nl.analysis_detail ')
|
|
sql_where = (
|
|
'WHERE ad.plannable = TRUE '
|
|
'AND nl.start_date IS NULL '
|
|
'AND nl.analysis IN (' + analysis_ids + ') '
|
|
'AND nl.annulled = FALSE '
|
|
'AND nla.behavior != \'internal_relation\' ' +
|
|
preplanned_where)
|
|
params = []
|
|
|
|
if context.get('laboratory'):
|
|
sql_where += 'AND nl.laboratory = %s '
|
|
params.append(context.get('laboratory'))
|
|
if context.get('department'):
|
|
sql_where += 'AND nl.department = %s '
|
|
params.append(context.get('department'))
|
|
if context.get('date_from'):
|
|
sql_where += 'AND ad.confirmation_date::date >= %s::date '
|
|
params.append(context.get('date_from'))
|
|
if context.get('date_to'):
|
|
sql_where += 'AND ad.confirmation_date::date <= %s::date '
|
|
params.append(context.get('date_to'))
|
|
|
|
with Transaction().set_user(0):
|
|
cursor.execute(sql_select + sql_from + sql_where, tuple(params))
|
|
notebook_lines = cursor.fetchall()
|
|
|
|
result = []
|
|
for nl in notebook_lines:
|
|
if (template_analysis[nl[0]] and
|
|
nl[1] not in template_analysis[nl[0]]):
|
|
continue
|
|
result.append(nl[2])
|
|
samples = list(set(result))
|
|
|
|
action['pyson_domain'] = [
|
|
('id', 'in', samples),
|
|
]
|
|
action['pyson_domain'] = PYSONEncoder().encode(action['pyson_domain'])
|
|
action['name'] += ' (%s)' % template.rec_name
|
|
return action, {}
|