Compare commits

...

2 Commits

Author SHA1 Message Date
Adrián Bernardi 4aeb6ffeae lims, lims_planning_automatic: adds Simplified Automatic Planning 2023-12-05 17:36:49 -03:00
Adrián Bernardi fc725256b2 lims, lims_planning_automatic: adds Simplified Automatic Planning 2023-12-05 17:13:55 -03:00
6 changed files with 155 additions and 4 deletions

View File

@ -16,5 +16,9 @@
<field name="headquarters"/>
<group col="-1" colspan="2" id="checkboxes">
</group>
<field name="cv_corrections" colspan="4"/>
<notebook>
<page name="cv_corrections">
<field name="cv_corrections" colspan="4"/>
</page>
</notebook>
</form>

View File

@ -19,6 +19,7 @@ def register():
sample.Sample,
module='lims_planning_automatic', type_='model')
Pool.register(
planification.Planification2,
sheet.AnalysisSheet,
module='lims_planning_automatic', type_='model',
depends=['lims_analysis_sheet'])

View File

@ -10,3 +10,5 @@ class Laboratory(metaclass=PoolMeta):
__name__ = 'lims.laboratory'
automatic_planning = fields.Boolean('Automatic Planning')
automatic_planning_simplified = fields.Boolean(
'Simplified Automatic Planning')

View File

@ -6,6 +6,10 @@ msgctxt "field:lims.laboratory,automatic_planning:"
msgid "Automatic Planning"
msgstr "Planificación Automática"
msgctxt "field:lims.laboratory,automatic_planning_simplified:"
msgid "Simplified Automatic Planning"
msgstr "Planificación Automática Simplificada"
msgctxt "field:lims.planification,automatic:"
msgid "Automatic"
msgstr "Automática"

View File

@ -1,6 +1,7 @@
# This file is part of lims_planning_automatic module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from datetime import datetime
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
@ -29,16 +30,21 @@ class Planification(metaclass=PoolMeta):
laboratories = Laboratory.search([('automatic_planning', '=', True)])
for laboratory in laboratories:
if laboratory.automatic_planning_simplified:
cls.automatic_plan_simplified(laboratory, entries, tests)
continue
clause = [
('laboratory', '=', laboratory),
('plannable', '=', True),
('state', '=', 'unplanned'),
]
if entries:
clause.append(('entry', 'in', [e.id for e in entries]),)
clause.append(
('entry', 'in', [e.id for e in entries]))
if tests:
clause.append(('sample', 'in', [t.sample.id for t in tests]),)
clause.append(
('sample', 'in', [t.sample.id for t in tests]))
detail_analyses = EntryDetailAnalysis.search(clause)
if not detail_analyses:
@ -59,6 +65,7 @@ class Planification(metaclass=PoolMeta):
laboratory.default_laboratory_professional
planification.technicians = [technician]
planification.save()
session_id, _, _ = SearchFractions.create()
search_fractions = SearchFractions(session_id)
with Transaction().set_context(active_id=planification.id):
@ -66,13 +73,16 @@ class Planification(metaclass=PoolMeta):
details = SearchFractionsDetail.search([])
search_fractions.next.details = details
search_fractions.transition_add()
cls.preplan([planification])
for f in planification.details:
for s in f.details:
s.staff_responsible = [
laboratory.default_laboratory_professional.id]
s.save()
planification.save()
session_id, _, _ = TechniciansQualification.create()
technicians_qualification = TechniciansQualification(session_id)
with Transaction().set_context(active_id=planification.id):
@ -80,3 +90,127 @@ class Planification(metaclass=PoolMeta):
while res == 'next_':
res = technicians_qualification.transition_next_()
technicians_qualification.transition_confirm()
@classmethod
def automatic_plan_simplified(cls, laboratory, entries=None, tests=None):
cursor = Transaction().connection.cursor()
pool = Pool()
NotebookLine = pool.get('lims.notebook.line')
Notebook = pool.get('lims.notebook')
Fraction = pool.get('lims.fraction')
Sample = pool.get('lims.sample')
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
Analysis = pool.get('lims.analysis')
Date = pool.get('ir.date')
NotebookLineProfessional = pool.get(
'lims.notebook.line-laboratory.professional')
sql_select = 'SELECT nl.id, ad.id '
sql_from = (
'FROM "' + NotebookLine._table + '" nl '
'INNER JOIN "' + Analysis._table + '" an '
'ON an.id = nl.analysis '
'INNER JOIN "' + EntryDetailAnalysis._table + '" ad '
'ON ad.id = nl.analysis_detail '
'INNER JOIN "' + Notebook._table + '" nb '
'ON nb.id = nl.notebook '
'INNER JOIN "' + Fraction._table + '" fr '
'ON fr.id = nb.fraction '
'INNER JOIN "' + Sample._table + '" sa '
'ON sa.id = fr.sample ')
sql_where = (
'WHERE ad.plannable = TRUE '
'AND nl.start_date IS NULL '
'AND nl.annulled = FALSE '
'AND nl.laboratory = %s '
'AND an.behavior != \'internal_relation\' ')
if entries:
sql_where += 'AND sa.entry IN (%s) ' % ', '.join(
str(e.id) for e in entries)
if tests:
sql_where += 'AND fr.sample IN (%s) ' % ', '.join(
str(t.sample.id) for t in tests)
sql_order = 'ORDER BY nb.fraction ASC'
with Transaction().set_user(0):
cursor.execute(sql_select + sql_from + sql_where + sql_order,
(laboratory.id,))
res = cursor.fetchall()
if not res:
return
notebook_lines, detail_analyses = set(), set()
for x in res:
notebook_lines.add(x[0])
detail_analyses.add(x[1])
lines = NotebookLine.browse(list(notebook_lines))
details = EntryDetailAnalysis.browse(list(detail_analyses))
start_date = Date.today()
professional_id = laboratory.default_laboratory_professional.id
NotebookLine.write(lines, {'start_date': start_date})
EntryDetailAnalysis.write(details, {'state': 'planned'})
notebook_lines_ids = ', '.join(str(nl_id) for nl_id in notebook_lines)
cursor.execute('DELETE FROM "' +
NotebookLineProfessional._table + '" '
'WHERE notebook_line IN (' + notebook_lines_ids + ')')
NotebookLineProfessional.create([{
'notebook_line': nl_id,
'professional': professional_id,
} for nl_id in notebook_lines])
return res
class Planification2(metaclass=PoolMeta):
__name__ = 'lims.planification'
@classmethod
def automatic_plan_simplified(cls, laboratory, entries=None, tests=None):
pool = Pool()
NotebookLine = pool.get('lims.notebook.line')
Date = pool.get('ir.date')
AnalysisSheet = pool.get('lims.analysis_sheet')
res = super().automatic_plan_simplified(laboratory, entries, tests)
if not res:
return
notebook_lines, detail_analyses = set(), set()
for x in res:
notebook_lines.add(x[0])
detail_analyses.add(x[1])
lines = NotebookLine.browse(list(notebook_lines))
start_date = Date.today()
date_time = datetime.combine(start_date, datetime.now().time())
professional_id = laboratory.default_laboratory_professional.id
analysis_sheets = {}
for nl in lines:
template_id = nl.get_analysis_sheet_template()
if not template_id:
continue
key = (template_id, professional_id)
if key not in analysis_sheets:
analysis_sheets[key] = []
analysis_sheets[key].append(nl)
for key, values in analysis_sheets.items():
sheet = AnalysisSheet()
sheet.template = key[0]
sheet.compilation = sheet.get_new_compilation(
{'date_time': date_time})
sheet.professional = key[1]
sheet.laboratory = laboratory.id
sheet.save()
sheet.create_lines(values)
return res

View File

@ -4,4 +4,10 @@
<label name="automatic_planning"/>
<field name="automatic_planning"/>
</xpath>
<xpath expr="/form/notebook" position="inside">
<page name="automatic_planning">
<label name="automatic_planning_simplified"/>
<field name="automatic_planning_simplified"/>
</page>
</xpath>
</data>