lims, lims_interface, lims_analysis_sheet, lims_instrument,

lims_project_study_plan, lims_quality_control: add result modifiers
This commit is contained in:
Adrián Bernardi 2022-09-08 19:04:22 -03:00
parent daaf876def
commit 471a0c7415
29 changed files with 441 additions and 596 deletions

View File

@ -84,6 +84,7 @@ def register():
uom.ConcentrationLevel,
entry.EntryDetailAnalysis,
notebook.Notebook,
laboratory.ResultModifier,
results_report.ResultsReport,
notebook.NotebookLine,
notebook.NotebookLineAllFields,

View File

@ -583,6 +583,18 @@ class LabDeviceRelateAnalysis(Wizard):
return 'end'
class ResultModifier(ModelSQL, ModelView):
'Result Modifier'
__name__ = 'lims.result_modifier'
code = fields.Char('Code', required=True)
name = fields.Char('Name', required=True, translate=True)
@classmethod
def check_xml_record(cls, records, values):
return True
class NotebookRule(ModelSQL, ModelView):
'Notebook Rule'
__name__ = 'lims.rule'

View File

@ -311,6 +311,37 @@
<field name="action" ref="wizard_device_relate_analysis"/>
</record>
<!-- Result Modifier -->
<record model="ir.ui.view" id="result_modifier_view_form">
<field name="model">lims.result_modifier</field>
<field name="type">form</field>
<field name="name">result_modifier_form</field>
</record>
<record model="ir.ui.view" id="result_modifier_view_list">
<field name="model">lims.result_modifier</field>
<field name="type">tree</field>
<field name="name">result_modifier_list</field>
</record>
<record model="ir.action.act_window" id="act_result_modifier_list">
<field name="name">Result Modifiers</field>
<field name="res_model">lims.result_modifier</field>
</record>
<record model="ir.action.act_window.view" id="act_result_modifier_view_list">
<field name="sequence" eval="10"/>
<field name="view" ref="result_modifier_view_list"/>
<field name="act_window" ref="act_result_modifier_list"/>
</record>
<record model="ir.action.act_window.view" id="act_result_modifier_view_form">
<field name="sequence" eval="20"/>
<field name="view" ref="result_modifier_view_form"/>
<field name="act_window" ref="act_result_modifier_list"/>
</record>
<menuitem action="act_result_modifier_list" id="menu_result_modifier_list"
parent="lims_config_laboratory" sequence="55"/>
<!-- Notebook Rule -->
<record model="ir.ui.view" id="notebook_rule_view_form">
@ -356,4 +387,44 @@
</record>
</data>
<data noupdate="1">
<record model="lims.result_modifier" id="result_modifier_low">
<field name="code">low</field>
<field name="name">&lt;</field>
</record>
<record model="lims.result_modifier" id="result_modifier_d">
<field name="code">d</field>
<field name="name">Detected</field>
</record>
<record model="lims.result_modifier" id="result_modifier_nd">
<field name="code">nd</field>
<field name="name">nd</field>
</record>
<record model="lims.result_modifier" id="result_modifier_na">
<field name="code">na</field>
<field name="name">na</field>
</record>
<record model="lims.result_modifier" id="result_modifier_pos">
<field name="code">pos</field>
<field name="name">Positive</field>
</record>
<record model="lims.result_modifier" id="result_modifier_neg">
<field name="code">neg</field>
<field name="name">Negative</field>
</record>
<record model="lims.result_modifier" id="result_modifier_ni">
<field name="code">ni</field>
<field name="name">ni</field>
</record>
<record model="lims.result_modifier" id="result_modifier_abs">
<field name="code">abs</field>
<field name="name">Absence</field>
</record>
<record model="lims.result_modifier" id="result_modifier_pre">
<field name="code">pre</field>
<field name="name">Presence</field>
</record>
</data>
</tryton>

View File

@ -5033,6 +5033,14 @@ msgctxt "field:lims.relate_method.start,method:"
msgid "Method"
msgstr "Método"
msgctxt "field:lims.result_modifier,code:"
msgid "Code"
msgstr "Código"
msgctxt "field:lims.result_modifier,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:lims.results_report,attachments:"
msgid "Attachments"
msgstr "Adjuntos"
@ -7276,6 +7284,10 @@ msgctxt "model:ir.action,name:act_remove_typifications"
msgid "Remove Typifications"
msgstr "Quitar tipificaciones"
msgctxt "model:ir.action,name:act_result_modifier_list"
msgid "Result Modifiers"
msgstr "Modificadores de resultado"
msgctxt "model:ir.action,name:act_sample_attribute"
msgid "Sample Attributes"
msgstr "Atributos de Muestra"
@ -9184,6 +9196,10 @@ msgctxt "model:ir.ui.menu,name:menu_referral_list"
msgid "Referrals"
msgstr "Derivaciones"
msgctxt "model:ir.ui.menu,name:menu_result_modifier_list"
msgid "Result Modifiers"
msgstr "Modificadores de resultado"
msgctxt "model:ir.ui.menu,name:menu_sample_attribute"
msgid "Sample Attributes"
msgstr "Atributos de Muestra"
@ -10053,6 +10069,46 @@ msgctxt "model:lims.relate_method.start,name:"
msgid "Relate Method"
msgstr "Relacionar método"
msgctxt "model:lims.result_modifier,name:"
msgid "Result Modifier"
msgstr "Modificador de resultado"
msgctxt "model:lims.result_modifier,name:result_modifier_abs"
msgid "Absence"
msgstr "Ausencia"
msgctxt "model:lims.result_modifier,name:result_modifier_d"
msgid "Detected"
msgstr "Detectado"
msgctxt "model:lims.result_modifier,name:result_modifier_low"
msgid "<"
msgstr "<"
msgctxt "model:lims.result_modifier,name:result_modifier_na"
msgid "na"
msgstr "na"
msgctxt "model:lims.result_modifier,name:result_modifier_nd"
msgid "nd"
msgstr "nd"
msgctxt "model:lims.result_modifier,name:result_modifier_neg"
msgid "Negative"
msgstr "Negativo"
msgctxt "model:lims.result_modifier,name:result_modifier_ni"
msgid "ni"
msgstr "ni"
msgctxt "model:lims.result_modifier,name:result_modifier_pos"
msgid "Positive"
msgstr "Positivo"
msgctxt "model:lims.result_modifier,name:result_modifier_pre"
msgid "Presence"
msgstr "Presencia"
msgctxt "model:lims.results_report,name:"
msgid "Results Report"
msgstr "Informe de resultados"
@ -10718,7 +10774,8 @@ msgid "line.converted_result"
msgstr ""
msgctxt "report:lims.analysis_checked_pending_inform:"
msgid "line.converted_result_modifier_string"
msgid ""
"line.converted_result_modifier and line.converted_result_modifier.name or ''"
msgstr ""
msgctxt "report:lims.analysis_checked_pending_inform:"
@ -10774,7 +10831,7 @@ msgid "line.result"
msgstr ""
msgctxt "report:lims.analysis_checked_pending_inform:"
msgid "line.result_modifier_string"
msgid "line.result_modifier and line.result_modifier.name or ''"
msgstr ""
msgctxt "report:lims.analysis_checked_pending_inform:"
@ -11102,7 +11159,8 @@ msgid "line.converted_result"
msgstr ""
msgctxt "report:lims.analysis_pending_inform:"
msgid "line.converted_result_modifier_string"
msgid ""
"line.converted_result_modifier and line.converted_result_modifier.name or ''"
msgstr ""
msgctxt "report:lims.analysis_pending_inform:"
@ -11162,7 +11220,7 @@ msgid "line.result"
msgstr ""
msgctxt "report:lims.analysis_pending_inform:"
msgid "line.result_modifier_string"
msgid "line.result_modifier and line.result_modifier.name or ''"
msgstr ""
msgctxt "report:lims.analysis_pending_inform:"
@ -13093,219 +13151,6 @@ msgctxt "selection:lims.notebook.generate_results_report.start,type:"
msgid "Preliminary"
msgstr "Preliminar"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "<"
msgstr "<"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "="
msgstr "="
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "na"
msgstr "na"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "<"
msgstr "<"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "="
msgstr "="
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "na"
msgstr "na"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt ""
"selection:lims.notebook.internal_relations_calc_2.variable,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.line,converted_result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "na"
msgstr "na"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.line,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.line.all_fields,converted_result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "na"
msgstr "na"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.line.all_fields,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.line.repeat_analysis.start,analysis_type:"
msgid "Analysis"
msgstr "Análisis"
@ -13318,136 +13163,6 @@ msgctxt "selection:lims.notebook.line.repeat_analysis.start,analysis_type:"
msgid "Set"
msgstr "Set"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "na"
msgstr "na"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.load_results_formula.action,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "<"
msgstr "<"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "="
msgstr "="
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "na"
msgstr "na"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt ""
"selection:lims.notebook.load_results_formula.process,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "<"
msgstr "<"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "="
msgstr "="
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "Absence"
msgstr "Ausencia"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "Detected"
msgstr "Detectado"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "Negative"
msgstr "Negativo"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "Positive"
msgstr "Positivo"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "Presence"
msgstr "Presencia"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "na"
msgstr "na"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "nd"
msgstr "nd"
msgctxt "selection:lims.notebook.load_results_manual.line,result_modifier:"
msgid "ni"
msgstr "ni"
msgctxt "selection:lims.planification,state:"
msgid "Confirmed"
msgstr "Confirmado"

View File

@ -309,6 +309,7 @@ class Notebook(ModelSQL, ModelView):
Fraction = pool.get('lims.fraction')
FractionType = pool.get('lims.fraction.type')
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
ResultModifier = pool.get('lims.result_modifier')
draft_lines_ids = ResultsLine.get_draft_lines_ids(
laboratory_id, notebook_id)
@ -322,6 +323,8 @@ class Notebook(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE nl.notebook = %s '
'AND nl.laboratory = %s '
'AND ft.report = TRUE '
@ -357,6 +360,8 @@ class Notebook(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE nl.notebook = %s '
'AND nl.laboratory = %s '
'AND ft.report = TRUE '
@ -505,6 +510,7 @@ class Notebook(ModelSQL, ModelView):
Notebook = pool.get('lims.notebook')
Fraction = pool.get('lims.fraction')
FractionType = pool.get('lims.fraction.type')
ResultModifier = pool.get('lims.result_modifier')
laboratory_id = Transaction().context.get(
'samples_pending_reporting_laboratory', None)
@ -522,6 +528,8 @@ class Notebook(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE nl.laboratory = %s '
'AND ft.report = TRUE '
'AND nl.report = TRUE '
@ -549,7 +557,7 @@ class Notebook(ModelSQL, ModelView):
clause = [['OR',
('result', 'not in', [None, '']),
('literal_result', 'not in', [None, '']),
('result_modifier', 'in', [
('result_modifier.code', 'in', [
'd', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre', 'na']),
]]
return clause
@ -566,7 +574,7 @@ class Notebook(ModelSQL, ModelView):
'AND nl.result != \'\') '
'OR (nl.literal_result IS NOT NULL '
'AND nl.literal_result != \'\') '
'OR nl.result_modifier IN '
'OR rm.code IN '
'(\'d\', \'nd\', \'pos\', \'neg\', '
'\'ni\', \'abs\', \'pre\', \'na\')) ')
return sql_clause
@ -675,6 +683,7 @@ class Notebook(ModelSQL, ModelView):
NotebookLine = pool.get('lims.notebook.line')
Fraction = pool.get('lims.fraction')
FractionType = pool.get('lims.fraction.type')
ResultModifier = pool.get('lims.result_modifier')
result = {}
for n in notebooks:
@ -687,13 +696,15 @@ class Notebook(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE ft.report = TRUE '
'AND nl.report = TRUE '
'AND nl.annulled = FALSE '
'AND nl.accepted = FALSE '
'AND (nl.result IS NOT NULL '
'OR nl.literal_result IS NOT NULL '
'OR nl.result_modifier IN '
'OR rm.code IN '
'(\'d\', \'nd\', \'pos\', \'neg\', '
'\'ni\', \'abs\', \'pre\', \'na\')) '
'AND nl.notebook = %s',
@ -709,6 +720,7 @@ class Notebook(ModelSQL, ModelView):
NotebookLine = pool.get('lims.notebook.line')
Fraction = pool.get('lims.fraction')
FractionType = pool.get('lims.fraction.type')
ResultModifier = pool.get('lims.result_modifier')
cursor.execute('SELECT nl.notebook '
'FROM "' + NotebookLine._table + '" nl '
@ -718,13 +730,15 @@ class Notebook(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE ft.report = TRUE '
'AND nl.report = TRUE '
'AND nl.annulled = FALSE '
'AND nl.accepted = FALSE '
'AND (nl.result IS NOT NULL '
'OR nl.literal_result IS NOT NULL '
'OR nl.result_modifier IN '
'OR rm.code IN '
'(\'d\', \'nd\', \'pos\', \'neg\', '
'\'ni\', \'abs\', \'pre\', \'na\'))')
notebooks_ids = [x[0] for x in cursor.fetchall()]
@ -856,31 +870,12 @@ class NotebookLine(ModelSQL, ModelView):
final_unit = fields.Many2One('product.uom', 'Final unit',
domain=[('category.lims_only_available', '=', True)],
states=_states, depends=_depends)
result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier', sort=False,
result_modifier = fields.Many2One('lims.result_modifier',
'Result modifier', select=True,
states=_states, depends=_depends)
result_modifier_string = result_modifier.translated('result_modifier')
converted_result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('nd', 'nd'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
], 'Converted result modifier', sort=False,
converted_result_modifier = fields.Many2One('lims.result_modifier',
'Converted result modifier', select=True,
states=_states, depends=_depends)
converted_result_modifier_string = converted_result_modifier.translated(
'converted_result_modifier')
result = fields.Char('Result',
states=_states, depends=_depends)
converted_result = fields.Char('Converted result',
@ -1015,16 +1010,51 @@ class NotebookLine(ModelSQL, ModelView):
@classmethod
def __register__(cls, module_name):
cursor = Transaction().connection.cursor()
Service = Pool().get('lims.service')
table_h = cls.__table_handler__(module_name)
urgent_exist = table_h.column_exist('urgent')
migrate_result_modifier = (
table_h.column_exist('result_modifier') and
table_h.column_is_type('result_modifier', 'VARCHAR'))
if migrate_result_modifier:
table_h.column_rename('result_modifier',
'temp_result_modifier')
table_h.column_rename('converted_result_modifier',
'temp_converted_result_modifier')
super().__register__(module_name)
if not urgent_exist:
cursor = Transaction().connection.cursor()
Service = Pool().get('lims.service')
cursor.execute('UPDATE "' + cls._table + '" nl '
'SET urgent = srv.urgent FROM '
'"' + Service._table + '" srv '
'WHERE srv.id = nl.service')
if migrate_result_modifier:
cls._migrate_result_modifier()
table_h.drop_column('temp_result_modifier')
table_h.drop_column('temp_converted_result_modifier')
@classmethod
def _migrate_result_modifier(cls):
cursor = Transaction().connection.cursor()
ResultModifier = Pool().get('lims.result_modifier')
cursor.execute('UPDATE "' + cls._table + '" '
'SET result_modifier = NULL '
'WHERE temp_result_modifier = \'eq\'')
cursor.execute('UPDATE "' + cls._table + '" nl '
'SET result_modifier = rm.id FROM '
'"' + ResultModifier._table + '" rm '
'WHERE rm.code = nl.temp_result_modifier')
cursor.execute('UPDATE "' + cls._table + '" '
'SET converted_result_modifier = NULL '
'WHERE temp_converted_result_modifier = \'eq\'')
cursor.execute('UPDATE "' + cls._table + '" nl '
'SET converted_result_modifier = rm.id FROM '
'"' + ResultModifier._table + '" rm '
'WHERE rm.code = nl.temp_converted_result_modifier')
@classmethod
def __setup__(cls):
@ -1036,14 +1066,6 @@ class NotebookLine(ModelSQL, ModelView):
def default_repetition():
return 0
@staticmethod
def default_result_modifier():
return 'eq'
@staticmethod
def default_converted_result_modifier():
return 'eq'
@staticmethod
def default_decimals():
return 2
@ -1175,8 +1197,9 @@ class NotebookLine(ModelSQL, ModelView):
('annulled', '=', False),
('result', 'in', [None, '']),
('literal_result', 'in', [None, '']),
('result_modifier', 'not in', [
'd', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre', 'na']),
['OR', ('result_modifier', '=', None),
('result_modifier.code', 'not in',
['d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre', 'na'])],
]) == 0:
Referral.write([referral], {'state': 'done'})
@ -1397,7 +1420,7 @@ class NotebookLine(ModelSQL, ModelView):
'analysis')
def on_change_result(self):
self.converted_result = None
self.converted_result_modifier = 'eq'
self.converted_result_modifier = None
self.backup = None
self.verification = None
self.uncertainty = None
@ -1422,29 +1445,37 @@ class NotebookLine(ModelSQL, ModelView):
self.not_accepted_message = gettext('lims.msg_not_accepted_3')
elif not (self.result or self.converted_result or
self.literal_result or
self.result_modifier in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre') or
self.converted_result_modifier in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')):
(self.result_modifier and
self.result_modifier.code in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')) or
(self.converted_result_modifier and
self.converted_result_modifier.code in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre'))):
self.accepted = False
self.not_accepted_message = gettext('lims.msg_not_accepted_4')
else:
if (self.converted_result and self.converted_result_modifier
not in ('ni', 'eq', 'low')):
if (self.converted_result and (
self.converted_result_modifier and
self.converted_result_modifier.code not in
('ni', 'low'))):
self.accepted = False
self.not_accepted_message = gettext(
'lims.msg_not_accepted_5')
elif (self.result and self.result_modifier
not in ('ni', 'eq', 'low')):
elif (self.result and (
self.result_modifier and
self.result_modifier.code not in
('ni', 'low'))):
self.accepted = False
self.not_accepted_message = gettext(
'lims.msg_not_accepted_6')
elif (self.result_modifier == 'ni' and
elif (self.result_modifier and
self.result_modifier.code == 'ni' and
not self.literal_result and
(not self.converted_result_modifier or
not self.converted_result) and
self.converted_result_modifier not in (
'nd', 'pos', 'neg')):
(self.converted_result_modifier and
self.converted_result_modifier.code not in
('nd', 'pos', 'neg'))):
self.accepted = False
self.not_accepted_message = gettext(
'lims.msg_not_accepted_7')
@ -1466,11 +1497,13 @@ class NotebookLine(ModelSQL, ModelView):
@fields.depends('result_modifier', 'annulled', 'annulment_date', 'report')
def on_change_result_modifier(self):
if self.result_modifier == 'na' and not self.annulled:
if (self.result_modifier and self.result_modifier.code == 'na'
and not self.annulled):
self.annulled = True
self.annulment_date = datetime.now()
self.report = False
elif self.result_modifier != 'na' and self.annulled:
elif ((not self.result_modifier or self.result_modifier.code != 'na')
and self.annulled):
self.annulled = False
self.annulment_date = None
self.report = True
@ -1619,14 +1652,14 @@ class NotebookLine(ModelSQL, ModelView):
def get_formated_result(self, name=None):
res = ''
result_modifier = self.result_modifier
result_modifier = self.result_modifier and self.result_modifier.code
if self.literal_result:
res = self.literal_result
else:
res = self._format_result(self.result,
self.decimals, self.significant_digits,
self.scientific_notation)
if result_modifier == 'eq':
if not result_modifier:
res = res
elif result_modifier == 'low':
res = gettext('lims.msg_quantification_limit', loq=res)
@ -1645,17 +1678,18 @@ class NotebookLine(ModelSQL, ModelView):
elif result_modifier == 'abs':
res = gettext('lims.msg_abs')
else:
res = result_modifier
res = self.result_modifier.name
return res
def get_formated_converted_result(self, name=None):
res = ''
result_modifier = self.converted_result_modifier
result_modifier = (self.converted_result_modifier and
self.converted_result_modifier.code)
if not self.literal_result:
res = self._format_result(self.converted_result,
self.decimals, self.significant_digits,
self.scientific_notation)
if result_modifier == 'eq':
if not result_modifier:
res = res
elif result_modifier == 'low':
res = gettext('lims.msg_quantification_limit', loq=res)
@ -1674,7 +1708,7 @@ class NotebookLine(ModelSQL, ModelView):
elif result_modifier == 'abs':
res = gettext('lims.msg_abs')
else:
res = result_modifier
res = self.converted_result_modifier.name
return res
def _format_result(self, result, decimals, significant_digits=None,
@ -1736,29 +1770,10 @@ class NotebookLineAllFields(ModelSQL, ModelView):
initial_unit = fields.Many2One('product.uom', 'Initial unit',
readonly=True)
final_unit = fields.Many2One('product.uom', 'Final unit', readonly=True)
result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier', readonly=True)
converted_result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('nd', 'nd'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
], 'Converted result modifier', readonly=True)
result_modifier_string = result_modifier.translated('result_modifier')
converted_result_modifier_string = converted_result_modifier.translated(
'converted_result_modifier')
result_modifier = fields.Many2One('lims.result_modifier',
'Result modifier', readonly=True)
converted_result_modifier = fields.Many2One('lims.result_modifier',
'Converted result modifier', readonly=True)
result = fields.Char('Result', readonly=True)
converted_result = fields.Char('Converted result', readonly=True)
formated_result = fields.Function(fields.Char('Result to report'),
@ -2215,7 +2230,7 @@ class NotebookResultsConversion(Wizard):
if notebook_line.accepted:
continue
if (notebook_line.converted_result or not notebook_line.result or
notebook_line.result_modifier != 'eq'):
notebook_line.result_modifier):
continue
iu = notebook_line.initial_unit
if not iu:
@ -2239,7 +2254,7 @@ class NotebookResultsConversion(Wizard):
if (iu == fu and ic == fc):
converted_result = result
notebook_line.converted_result = str(converted_result)
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
lines_to_save.append(notebook_line)
elif (iu != fu and ic == fc):
formula = UomConversion.get_conversion_formula(iu, fu)
@ -2251,12 +2266,12 @@ class NotebookResultsConversion(Wizard):
converted_result = result * formula_result
notebook_line.converted_result = str(converted_result)
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
lines_to_save.append(notebook_line)
elif (iu == fu and ic != fc):
converted_result = result * (fc / ic)
notebook_line.converted_result = str(converted_result)
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
lines_to_save.append(notebook_line)
else:
formula = None
@ -2282,12 +2297,12 @@ class NotebookResultsConversion(Wizard):
converted_result = (result * (fc / ic) * (d_fc / d_ic) *
formula_result)
notebook_line.converted_result = str(converted_result)
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
lines_to_save.append(notebook_line)
else:
converted_result = result * (fc / ic) * formula_result
notebook_line.converted_result = str(converted_result)
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
lines_to_save.append(notebook_line)
if lines_to_save:
NotebookLine.save(lines_to_save)
@ -2370,7 +2385,13 @@ class NotebookLimitsValidation(Wizard):
return 'end'
def lines_limits_validation(self, notebook_lines):
NotebookLine = Pool().get('lims.notebook.line')
pool = Pool()
ModelData = pool.get('ir.model.data')
NotebookLine = pool.get('lims.notebook.line')
result_modifier_low = ModelData.get_id('lims', 'result_modifier_low')
result_modifier_nd = ModelData.get_id('lims', 'result_modifier_nd')
result_modifier_ni = ModelData.get_id('lims', 'result_modifier_ni')
lines_to_save = []
for notebook_line in notebook_lines:
@ -2390,7 +2411,7 @@ class NotebookLimitsValidation(Wizard):
if (notebook_line.result and (
notebook_line.check_result_limits or
not notebook_line.converted_result)):
if notebook_line.result_modifier != 'eq':
if notebook_line.result_modifier:
continue
try:
value = float(notebook_line.result)
@ -2401,27 +2422,27 @@ class NotebookLimitsValidation(Wizard):
line=notebook_line.rec_name))
if dl < value and value < ql:
notebook_line.result = str(ql)
notebook_line.result_modifier = 'low'
notebook_line.result_modifier = result_modifier_low
notebook_line.converted_result = None
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
notebook_line.rm_correction_formula = None
elif value < dl:
notebook_line.result = None
notebook_line.result_modifier = 'nd'
notebook_line.result_modifier = result_modifier_nd
notebook_line.converted_result = None
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
notebook_line.rm_correction_formula = None
elif value == dl:
notebook_line.result = str(ql)
notebook_line.result_modifier = 'low'
notebook_line.result_modifier = result_modifier_low
notebook_line.converted_result = None
notebook_line.converted_result_modifier = 'eq'
notebook_line.converted_result_modifier = None
notebook_line.rm_correction_formula = None
notebook_line.backup = str(value)
lines_to_save.append(notebook_line)
elif notebook_line.converted_result:
if notebook_line.converted_result_modifier != 'eq':
if notebook_line.converted_result_modifier:
continue
try:
value = float(notebook_line.converted_result)
@ -2432,18 +2453,21 @@ class NotebookLimitsValidation(Wizard):
line=notebook_line.rec_name))
if dl < value and value < ql:
notebook_line.converted_result = str(ql)
notebook_line.converted_result_modifier = 'low'
notebook_line.result_modifier = 'ni'
notebook_line.converted_result_modifier = (
result_modifier_low)
notebook_line.result_modifier = result_modifier_ni
notebook_line.rm_correction_formula = None
elif value < dl:
notebook_line.converted_result = None
notebook_line.converted_result_modifier = 'nd'
notebook_line.result_modifier = 'ni'
notebook_line.converted_result_modifier = (
result_modifier_nd)
notebook_line.result_modifier = result_modifier_ni
notebook_line.rm_correction_formula = None
elif value == dl:
notebook_line.converted_result = str(ql)
notebook_line.converted_result_modifier = 'low'
notebook_line.result_modifier = 'ni'
notebook_line.converted_result_modifier = (
result_modifier_low)
notebook_line.result_modifier = result_modifier_ni
notebook_line.rm_correction_formula = None
notebook_line.backup = str(value)
lines_to_save.append(notebook_line)
@ -2899,32 +2923,15 @@ class NotebookInternalRelationsCalc2Variable(ModelSQL, ModelView):
line = fields.Many2One('lims.notebook.line', 'Line')
analysis = fields.Many2One('lims.analysis', 'Analysis', readonly=True)
repetition = fields.Integer('Repetition', readonly=True)
result_modifier = fields.Function(fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier'), 'get_line_field')
result_modifier = fields.Function(fields.Many2One('lims.result_modifier',
'Result modifier'), 'get_line_field')
result = fields.Function(fields.Char('Result'), 'get_line_field')
initial_unit = fields.Function(fields.Many2One('product.uom',
'Initial unit'), 'get_line_field')
initial_concentration = fields.Function(fields.Char(
'Initial concentration'), 'get_line_field')
converted_result_modifier = fields.Function(fields.Selection([
('eq', '='),
('low', '<'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
], 'Converted result modifier'), 'get_line_field')
converted_result_modifier = fields.Function(fields.Many2One(
'lims.result_modifier', 'Converted result modifier'), 'get_line_field')
converted_result = fields.Function(fields.Char('Converted result'),
'get_line_field')
final_unit = fields.Function(fields.Many2One('product.uom', 'Final unit'),
@ -2945,7 +2952,7 @@ class NotebookInternalRelationsCalc2Variable(ModelSQL, ModelView):
result = {}
for name in names:
result[name] = {}
if name in ('initial_unit', 'final_unit'):
if cls._fields[name]._type == 'many2one':
for v in variables:
field = getattr(v.line, name, None)
result[name][v.id] = field.id if field else None
@ -3401,18 +3408,8 @@ class NotebookLoadResultsFormulaAction(ModelSQL):
line = fields.Many2One('lims.notebook.line', 'Line')
result = fields.Char('Result')
result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier', sort=False)
result_modifier = fields.Many2One('lims.result_modifier',
'Result modifier')
end_date = fields.Date('End date')
professional = fields.Many2One('lims.laboratory.professional',
'Laboratory professional')
@ -3426,8 +3423,17 @@ class NotebookLoadResultsFormulaAction(ModelSQL):
@classmethod
def __register__(cls, module_name):
super().__register__(module_name)
cursor = Transaction().connection.cursor()
table_h = cls.__table_handler__(module_name)
migrate_result_modifier = (
table_h.column_exist('result_modifier') and
table_h.column_is_type('result_modifier', 'VARCHAR'))
if migrate_result_modifier:
table_h.column_rename('result_modifier',
'temp_result_modifier')
super().__register__(module_name)
if migrate_result_modifier:
table_h.drop_column('temp_result_modifier')
cursor.execute('DELETE FROM "' + cls._table + '"')
@ -3447,18 +3453,8 @@ class NotebookLoadResultsFormulaProcess(ModelView):
variables = fields.One2Many('lims.notebook.load_results_formula.variable',
None, 'Variables')
result = fields.Char('Result', required=True)
result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier', sort=False, required=True)
result_modifier = fields.Many2One('lims.result_modifier',
'Result modifier')
end_date = fields.Date('End date')
end_date_copy = fields.Boolean('Field copy')
professional = fields.Many2One('lims.laboratory.professional',
@ -3687,7 +3683,8 @@ class NotebookLoadResultsFormula(Wizard):
'session_id': self._session_id,
'line': self.process.line.id,
'result': self.process.result,
'result_modifier': self.process.result_modifier,
'result_modifier': (self.process.result_modifier.id if
self.process.result_modifier else None),
'end_date': self.process.end_date,
'professional': self.process.professional.id,
'chromatogram': self.process.chromatogram,
@ -3732,7 +3729,8 @@ class NotebookLoadResultsFormula(Wizard):
])
if action:
self.process.result = action[0].result
self.process.result_modifier = action[0].result_modifier
self.process.result_modifier = (action[0].result_modifier.id if
action[0].result_modifier else None)
self.process.end_date = action[0].end_date
self.process.professional = action[0].professional.id
self.process.chromatogram = action[0].chromatogram
@ -3743,7 +3741,7 @@ class NotebookLoadResultsFormula(Wizard):
self.process.variables = [v.id for v in action[0].variables]
elif has_prev:
self.process.result = None
self.process.result_modifier = 'eq'
self.process.result_modifier = None
if not self.process.end_date_copy:
self.process.end_date = None
if not self.process.chromatogram_copy:
@ -3783,7 +3781,8 @@ class NotebookLoadResultsFormula(Wizard):
])
if action:
self.process.result = action[0].result
self.process.result_modifier = action[0].result_modifier
self.process.result_modifier = (action[0].result_modifier.id if
action[0].result_modifier else None)
self.process.end_date = action[0].end_date
self.process.professional = action[0].professional.id
self.process.chromatogram = action[0].chromatogram
@ -3794,7 +3793,7 @@ class NotebookLoadResultsFormula(Wizard):
self.process.variables = [v.id for v in action[0].variables]
else:
self.process.result = None
self.process.result_modifier = 'eq'
self.process.result_modifier = None
self.process.end_date = None
self.process.professional = None
self.process.chromatogram = None
@ -3840,7 +3839,8 @@ class NotebookLoadResultsFormula(Wizard):
default['formula_formula'] = formula_formula
default['result'] = self.process.result
default['result_modifier'] = self.process.result_modifier
default['result_modifier'] = (self.process.result_modifier.id if
self.process.result_modifier else None)
default['initial_concentration'] = (
self.process.initial_concentration)
@ -3867,7 +3867,7 @@ class NotebookLoadResultsFormula(Wizard):
for k, v in variables_desc.items():
formula_formula = formula_formula.replace(k, v)
default['formula_formula'] = formula_formula
default['result_modifier'] = 'eq'
default['result_modifier'] = None
for field in ('initial_concentration', 'comments'):
if (hasattr(self.process, field + '_copy') and
@ -3994,18 +3994,19 @@ class NotebookLoadResultsFormula(Wizard):
continue
notebook_line_write = {
'result': data.result,
'result_modifier': data.result_modifier,
'result_modifier': (data.result_modifier.id if
data.result_modifier else None),
'end_date': data.end_date,
'chromatogram': data.chromatogram,
'initial_concentration': data.initial_concentration,
'comments': data.comments,
'converted_result': None,
'converted_result_modifier': 'eq',
'converted_result_modifier': None,
'backup': None,
'verification': None,
'uncertainty': None,
}
if data.result_modifier == 'na':
if data.result_modifier and data.result_modifier.code == 'na':
notebook_line_write['annulled'] = True
notebook_line_write['annulment_date'] = datetime.now()
notebook_line_write['report'] = False
@ -4154,18 +4155,8 @@ class NotebookLoadResultsManualLine(ModelSQL, ModelView):
repetition = fields.Integer('Repetition', readonly=True)
fraction = fields.Many2One('lims.fraction', 'Fraction', readonly=True)
result = fields.Char('Result')
result_modifier = fields.Selection([
('eq', '='),
('low', '<'),
('d', 'Detected'),
('nd', 'nd'),
('na', 'na'),
('pos', 'Positive'),
('neg', 'Negative'),
('ni', 'ni'),
('abs', 'Absence'),
('pre', 'Presence'),
], 'Result modifier', sort=False)
result_modifier = fields.Many2One('lims.result_modifier',
'Result modifier')
end_date = fields.Date('End date')
chromatogram = fields.Char('Chromatogram')
initial_unit = fields.Many2One('product.uom', 'Initial unit',
@ -4195,7 +4186,7 @@ class NotebookLoadResultsManualLine(ModelSQL, ModelView):
if self.end_date:
return self.end_date
if (self.result or self.literal_result or
self.result_modifier not in ('eq', 'low')):
(self.result_modifier and self.result_modifier.code != 'low')):
return Date.today()
return None
@ -4291,7 +4282,8 @@ class NotebookLoadResultsManual(Wizard):
'line': line.id,
'repetition': line.repetition,
'result': line.result,
'result_modifier': line.result_modifier,
'result_modifier': (line.result_modifier.id if
line.result_modifier else None),
'end_date': line.end_date,
'chromatogram': line.chromatogram,
'initial_unit': (line.initial_unit.id if
@ -4401,24 +4393,25 @@ class NotebookLoadResultsManual(Wizard):
continue
notebook_line_write = {
'result': data.result,
'result_modifier': data.result_modifier,
'result_modifier': (data.result_modifier.id if
data.result_modifier else None),
'chromatogram': data.chromatogram,
'initial_unit': (data.initial_unit.id if
data.initial_unit else None),
'comments': data.comments,
'literal_result': data.literal_result,
'converted_result': None,
'converted_result_modifier': 'eq',
'converted_result_modifier': None,
'backup': None,
'verification': None,
'uncertainty': data.uncertainty,
'device': (data.device.id if
data.device else None),
}
if (not (data.result_modifier == 'eq' and not data.result) or
if (not (not data.result_modifier and not data.result) or
data.literal_result):
notebook_line_write['end_date'] = data.end_date
if data.result_modifier == 'na':
if data.result_modifier and data.result_modifier.code == 'na':
notebook_line_write['annulled'] = True
notebook_line_write['annulment_date'] = datetime.now()
notebook_line_write['report'] = False
@ -5282,17 +5275,22 @@ class NotebookAcceptLines(Wizard):
continue
if not (notebook_line.result or notebook_line.converted_result or
notebook_line.literal_result or
notebook_line.result_modifier in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre') or
notebook_line.converted_result_modifier in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')):
(notebook_line.result_modifier and
notebook_line.result_modifier.code in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')) or
(notebook_line.converted_result_modifier and
notebook_line.converted_result_modifier.code in
('d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre'))):
continue
if (notebook_line.converted_result and
notebook_line.converted_result_modifier
not in ('ni', 'eq', 'low')):
if (notebook_line.converted_result and (
notebook_line.converted_result_modifier and
notebook_line.converted_result_modifier.code not in
('ni', 'low'))):
continue
if (notebook_line.result and notebook_line.result_modifier
not in ('ni', 'eq', 'low')):
if (notebook_line.result and (
notebook_line.result_modifier and
notebook_line.result_modifier.code not in
('ni', 'low'))):
continue
notebook_id = notebook_line.notebook.id
@ -5422,10 +5420,14 @@ class NotebookAnnulLines(Wizard):
return 'end'
def lines_annul(self, notebook_lines):
NotebookLine = Pool().get('lims.notebook.line')
pool = Pool()
ModelData = pool.get('ir.model.data')
NotebookLine = pool.get('lims.notebook.line')
result_modifier_na = ModelData.get_id('lims', 'result_modifier_na')
NotebookLine.write(notebook_lines, {
'result_modifier': 'na',
'result_modifier': result_modifier_na,
'annulled': True,
'annulment_date': datetime.now(),
'annulment_reason': self.start.annulment_reason,
@ -5477,7 +5479,7 @@ class NotebookUnannulLines(Wizard):
NotebookLine = Pool().get('lims.notebook.line')
NotebookLine.write(notebook_lines, {
'result_modifier': 'eq',
'result_modifier': None,
'annulled': False,
'annulment_date': None,
'annulment_reason': None,

View File

@ -527,13 +527,13 @@
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://if%20test=%22line.report_date%22" xlink:type="simple">if test=&quot;line.report_date&quot;</text:a><text:a xlink:href="relatorio://format_date(line.report_date,%20user.language)" xlink:type="simple">format_date(line.report_date, user.language)</text:a><text:a xlink:href="relatorio:///if" xlink:type="simple">/if</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result_modifier_string" xlink:type="simple">line.result_modifier_string</text:a></text:p>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result_modifier%20and%20line.result_modifier.name%20or%20&apos;&apos;" xlink:type="simple">line.result_modifier and line.result_modifier.name or &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result" xlink:type="simple">line.result</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.initial_unit.rec_name%20if%20line.initial_unit%20else%20&apos;&apos;" xlink:type="simple">line.initial_unit.rec_name if line.initial_unit else &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result_modifier_string" xlink:type="simple">line.converted_result_modifier_string</text:a></text:p>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result_modifier%20and%20line.converted_result_modifier.name%20or%20&apos;&apos;" xlink:type="simple">line.converted_result_modifier and line.converted_result_modifier.name or &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result" xlink:type="simple">line.converted_result</text:a></text:p>
</table:table-cell>

View File

@ -538,13 +538,13 @@
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://if%20test=%22line.report_date%22" xlink:type="simple">if test=&quot;line.report_date&quot;</text:a><text:a xlink:href="relatorio://format_date(line.report_date,%20user.language)" xlink:type="simple">format_date(line.report_date, user.language)</text:a><text:a xlink:href="relatorio:///if" xlink:type="simple">/if</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result_modifier_string" xlink:type="simple">line.result_modifier_string</text:a></text:p>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result_modifier%20and%20line.result_modifier.name%20or%20&apos;&apos;" xlink:type="simple">line.result_modifier and line.result_modifier.name or &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.result" xlink:type="simple">line.result</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.initial_unit.rec_name%20if%20line.initial_unit%20else%20&apos;&apos;" xlink:type="simple">line.initial_unit.rec_name if line.initial_unit else &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result_modifier_string" xlink:type="simple">line.converted_result_modifier_string</text:a></text:p>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result_modifier%20and%20line.converted_result_modifier.name%20or%20&apos;&apos;" xlink:type="simple">line.converted_result_modifier and line.converted_result_modifier.name or &apos;&apos;</text:a></text:p>
</table:table-cell>
<table:table-cell office:value-type="string" calcext:value-type="string"><text:p><text:a xlink:href="relatorio://line.converted_result" xlink:type="simple">line.converted_result</text:a></text:p>
</table:table-cell>

View File

@ -1800,7 +1800,6 @@ class ResultsReportVersionDetailSigner(sequence_ordered(),
if signer_exist and not signer_table_exist:
cls._migrate_signer()
@classmethod
def _migrate_signer(cls):
cursor = Transaction().connection.cursor()
@ -4027,7 +4026,8 @@ class ResultReport(Report):
def get_result(cls, report_section, notebook_line, obs_ql, language):
res = notebook_line.formated_result
if (report_section in ('amb', 'for', 'rp', 'sq') and
notebook_line.result_modifier == 'low'):
notebook_line.result_modifier and
notebook_line.result_modifier.code == 'low'):
obs_ql = True
return res, obs_ql
@ -4036,8 +4036,9 @@ class ResultReport(Report):
notebook_line, obs_ql, language):
res = notebook_line.formated_converted_result
if (notebook_line.analysis.code != '0001' and
not notebook_line.literal_result
and notebook_line.converted_result_modifier == 'low'):
not notebook_line.literal_result and
notebook_line.converted_result_modifier and
notebook_line.converted_result_modifier.code == 'low'):
obs_ql = True
return res, obs_ql
@ -4049,7 +4050,8 @@ class ResultReport(Report):
initial_unit = notebook_line.initial_unit.rec_name
literal_result = notebook_line.literal_result
result_modifier = notebook_line.result_modifier
result_modifier = (notebook_line.result_modifier and
notebook_line.result_modifier.code)
detection_limit = notebook_line.detection_limit
converted_result = notebook_line.converted_result
uncertainty = notebook_line.uncertainty
@ -4058,7 +4060,7 @@ class ResultReport(Report):
with Transaction().set_context(language=language):
if report_section == 'rp':
res = ''
if (not literal_result and result_modifier == 'eq' and
if (not literal_result and not result_modifier and
uncertainty and float(uncertainty) != 0):
res = round(float(uncertainty), decimals)
res = format(res, '.{}f'.format(decimals))
@ -4105,7 +4107,8 @@ class ResultReport(Report):
final_unit = notebook_line.final_unit.rec_name
analysis = notebook_line.analysis.code
literal_result = notebook_line.literal_result
converted_result_modifier = notebook_line.converted_result_modifier
converted_result_modifier = (notebook_line.converted_result_modifier
and notebook_line.converted_result_modifier.code)
detection_limit = notebook_line.detection_limit
converted_result = notebook_line.converted_result
uncertainty = notebook_line.uncertainty
@ -4143,7 +4146,8 @@ class ResultReport(Report):
report_type, notebook_line, language):
detection_limit = notebook_line.detection_limit
literal_result = notebook_line.literal_result
result_modifier = notebook_line.result_modifier
result_modifier = (notebook_line.result_modifier and
notebook_line.result_modifier.code)
if report_section in ('amb', 'sq'):
res = ''

View File

@ -3287,6 +3287,7 @@ class Sample(ModelSQL, ModelView):
Notebook = pool.get('lims.notebook')
Fraction = pool.get('lims.fraction')
FractionType = pool.get('lims.fraction.type')
ResultModifier = pool.get('lims.result_modifier')
_ZERO = Decimal(0)
samples_in_progress = Config(1).samples_in_progress
@ -3294,7 +3295,7 @@ class Sample(ModelSQL, ModelView):
cursor.execute('SELECT nl.notebook, nl.analysis, nl.method, '
'nl.accepted, nl.result, nl.literal_result, '
'nl.result_modifier '
'rm.code '
'FROM "' + NotebookLine._table + '" nl '
'INNER JOIN "' + EntryDetailAnalysis._table + '" d '
'ON d.id = nl.analysis_detail '
@ -3304,6 +3305,8 @@ class Sample(ModelSQL, ModelView):
'ON f.id = n.fraction '
'INNER JOIN "' + FractionType._table + '" ft '
'ON ft.id = f.type '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'WHERE ft.report = TRUE '
'AND f.sample = %s '
'AND nl.report = TRUE '

View File

@ -5,7 +5,7 @@
<label name="repetition"/>
<field name="repetition"/>
<label name="result_modifier"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<label name="result"/>
<field name="result"/>
<label name="initial_unit"/>
@ -13,7 +13,7 @@
<label name="initial_concentration"/>
<field name="initial_concentration"/>
<label name="converted_result_modifier"/>
<field name="converted_result_modifier"/>
<field name="converted_result_modifier" widget="selection"/>
<label name="converted_result"/>
<field name="converted_result"/>
<label name="final_unit"/>

View File

@ -3,11 +3,11 @@
<field name="use"/>
<field name="analysis"/>
<field name="repetition"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="initial_unit"/>
<field name="initial_concentration"/>
<field name="converted_result_modifier"/>
<field name="converted_result_modifier" widget="selection"/>
<field name="converted_result"/>
<field name="final_unit"/>
<field name="final_concentration"/>

View File

@ -44,11 +44,11 @@
<field name="final_unit"/>
<group id="result_modifier" colspan="2" col="2">
<label name="result_modifier"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
</group>
<group id="converted_result_modifier" colspan="2" col="2">
<label name="converted_result_modifier"/>
<field name="converted_result_modifier"/>
<field name="converted_result_modifier" widget="selection"/>
</group>
<label name="result"/>
<field name="result"/>

View File

@ -25,11 +25,11 @@
<field name="literal_final_concentration"/>
<field name="initial_unit"/>
<field name="final_unit"/>
<field name="result_modifier"/>
<field name="converted_result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="converted_result"/>
<field name="formated_result"/>
<field name="converted_result_modifier" widget="selection"/>
<field name="converted_result"/>
<field name="formated_converted_result"/>
<field name="detection_limit"/>
<field name="quantification_limit"/>

View File

@ -45,11 +45,11 @@
<field name="final_unit"/>
<group id="result_modifier" colspan="2" col="2">
<label name="result_modifier"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
</group>
<group id="converted_result_modifier" colspan="2" col="2">
<label name="converted_result_modifier"/>
<field name="converted_result_modifier"/>
<field name="converted_result_modifier" widget="selection"/>
</group>
<label name="result"/>
<field name="result"/>

View File

@ -13,10 +13,10 @@
<field name="urgent"/>
<field name="priority"/>
<field name="report_date"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="initial_unit"/>
<field name="converted_result_modifier"/>
<field name="converted_result_modifier" widget="selection"/>
<field name="converted_result"/>
<field name="final_unit"/>
<field name="literal_result"/>

View File

@ -21,11 +21,11 @@
<field name="laboratory_professionals"/>
<field name="initial_unit"/>
<field name="final_unit"/>
<field name="result_modifier"/>
<field name="converted_result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="converted_result"/>
<field name="formated_result"/>
<field name="converted_result_modifier" widget="selection"/>
<field name="converted_result"/>
<field name="formated_converted_result"/>
<field name="detection_limit"/>
<field name="quantification_limit"/>

View File

@ -18,7 +18,7 @@
<label name="result"/>
<field name="result"/>
<label name="result_modifier"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<label name="end_date"/>
<field name="end_date"/>
<label name="end_date_copy"/>

View File

@ -9,7 +9,7 @@
<label name="repetition"/>
<field name="repetition"/>
<label name="result_modifier"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<label name="result"/>
<field name="result"/>
<label name="initial_unit"/>

View File

@ -3,7 +3,7 @@
<field name="fraction"/>
<field name="line"/>
<field name="repetition"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="initial_unit"/>
<field name="end_date"/>

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<form>
<label name="code"/>
<field name="code"/>
<label name="name"/>
<field name="name"/>
</form>

View File

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<tree>
<field name="code"/>
<field name="name"/>
</tree>

View File

@ -1052,6 +1052,7 @@ class LimitsValidation(Wizard):
def transition_validate_limits(self):
pool = Pool()
ModelData = pool.get('ir.model.data')
AnalysisSheet = pool.get('lims.analysis_sheet')
Data = pool.get('lims.interface.data')
NotebookLine = pool.get('lims.notebook.line')
@ -1062,6 +1063,9 @@ class LimitsValidation(Wizard):
sheet = AnalysisSheet(sheet_id)
table_id = sheet.compilation.table.id
result_modifier_low = ModelData.get_id('lims', 'result_modifier_low')
result_modifier_nd = ModelData.get_id('lims', 'result_modifier_nd')
result_column = self._get_template_column(
'result', table_id)
if not result_column:
@ -1090,8 +1094,8 @@ class LimitsValidation(Wizard):
result = getattr(line, result_field)
if result is None:
continue
result_modifier = getattr(line, result_modifier_field) or 'eq'
if result_modifier != 'eq':
result_modifier = getattr(line, result_modifier_field)
if result_modifier:
continue
try:
value = float(result)
@ -1113,19 +1117,19 @@ class LimitsValidation(Wizard):
line=nl.rec_name))
if dl < value and value < ql:
data[result_field] = str(ql)
data[result_modifier_field] = 'low'
data[result_modifier_field] = result_modifier_low
elif value < dl:
data[result_field] = None
data[result_modifier_field] = 'nd'
data[result_modifier_field] = result_modifier_nd
elif value == dl:
data[result_field] = str(ql)
data[result_modifier_field] = 'low'
data[result_modifier_field] = result_modifier_low
else:
data[result_modifier_field] = 'eq'
data[result_modifier_field] = None
if data:
Data.write([line], data)
if data[result_modifier_field] != 'eq':
if data[result_modifier_field]:
NotebookLine.write([nl], {'backup': str(value)})
return 'end'

View File

@ -510,11 +510,20 @@ class AnalysisSheet(Workflow, ModelSQL, ModelView):
def get_fields(cls, sheets, names):
cursor = Transaction().connection.cursor()
pool = Pool()
ModelData = pool.get('ir.model.data')
Field = pool.get('lims.interface.table.field')
notebook_line = pool.get('lims.notebook.line').__table__()
_ZERO = Decimal(0)
digits = cls.completion_percentage.digits[1]
result_modifiers = [
ModelData.get_id('lims', 'result_modifier_d'),
ModelData.get_id('lims', 'result_modifier_nd'),
ModelData.get_id('lims', 'result_modifier_pos'),
ModelData.get_id('lims', 'result_modifier_neg'),
ModelData.get_id('lims', 'result_modifier_ni'),
ModelData.get_id('lims', 'result_modifier_abs'),
ModelData.get_id('lims', 'result_modifier_pre')]
result = {
'urgent': {},
@ -575,8 +584,7 @@ class AnalysisSheet(Workflow, ModelSQL, ModelView):
literal_result_field), '') != '')
if result_modifier_field:
result_clause |= (Column(sql_table,
result_modifier_field).in_((
'd', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')))
result_modifier_field).in_(result_modifiers))
cursor.execute(*sql_join.select(Count(Literal('*')),
where=(sql_table.compilation == s.compilation.id) & (
@ -792,7 +800,8 @@ class AnalysisSheet(Workflow, ModelSQL, ModelView):
literal_result_field) not in (None, '')):
continue
if (result_modifier_field and getattr(line,
result_modifier_field) in (
result_modifier_field) and getattr(line,
result_modifier_field).code in (
'd', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre')):
continue
raise UserError(gettext(

View File

@ -352,10 +352,14 @@ class NotebookLoadResultsFile(Wizard):
('result', 'in', [None, '']),
('converted_result', 'in', [None, '']),
('literal_result', 'in', [None, '']),
('result_modifier', 'not in', ['d', 'nd', 'pos',
'neg', 'ni', 'abs', 'pre', 'na']),
('converted_result_modifier', 'not in',
['d', 'nd', 'pos', 'neg', 'ni', 'abs', 'pre']),
['OR', ('result_modifier', '=', None),
('result_modifier.code', 'not in',
['d', 'nd', 'pos', 'neg', 'ni', 'abs',
'pre', 'na'])],
['OR', ('converted_result_modifier', '=', None),
('converted_result_modifier.code', 'not in',
['d', 'nd', 'pos', 'neg', 'ni', 'abs',
'pre'])],
]
line = NotebookLine.search(clause, limit=1)
if not line:
@ -465,6 +469,7 @@ class NotebookLoadResultsFile(Wizard):
def transition_confirm(self):
cursor = Transaction().connection.cursor()
pool = Pool()
ModelData = pool.get('ir.model.data')
NotebookLine = pool.get('lims.notebook.line')
AnalyticProfessional = pool.get('lims.notebook.line.professional')
sql_table = NotebookLine.__table__()
@ -473,6 +478,7 @@ class NotebookLoadResultsFile(Wizard):
warnings = False
messages = ''
export_results = self.start.results_importer.exportResults()
result_modifier_na = ModelData.get_id('lims', 'result_modifier_na')
previous_professionals = []
new_professionals = []
@ -512,7 +518,7 @@ class NotebookLoadResultsFile(Wizard):
columns.append(sql_table.result)
values.append(Null)
columns.append(sql_table.result_modifier)
values.append(Literal('na'))
values.append(result_modifier_na)
columns.append(sql_table.report)
values.append(Literal(False))
columns.append(sql_table.annulled)

View File

@ -3,7 +3,7 @@
<field name="fraction"/>
<field name="analysis"/>
<field name="repetition"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="imported_result"/>
<field name="initial_unit"/>
<field name="imported_end_date"/>

View File

@ -2033,6 +2033,7 @@ class Compilation(Workflow, ModelSQL, ModelView):
@Workflow.transition('done')
def confirm(cls, compilations):
pool = Pool()
ModelData = pool.get('ir.model.data')
Data = pool.get('lims.interface.data')
Field = pool.get('lims.interface.table.field')
NotebookLine = pool.get('lims.notebook.line')
@ -2042,6 +2043,8 @@ class Compilation(Workflow, ModelSQL, ModelView):
now = datetime.now()
#today = now.date()
result_modifier_na = ModelData.get_id('lims', 'result_modifier_na')
for c in compilations:
fields = {}
columns = Field.search([
@ -2070,15 +2073,14 @@ class Compilation(Workflow, ModelSQL, ModelView):
result = round(float(data[nl_field]), decimals)
data[nl_field] = format(result,
'.{}f'.format(decimals))
if (nl_field == 'result_modifier' and
not data[nl_field]):
data[nl_field] = 'eq'
if nl_field == 'result_modifier' and data[nl_field]:
data[nl_field] = data[nl_field].id
if nl_field == 'literal_result' and data[nl_field]:
data_eng[nl_field] = data[nl_field]
if line.annulled:
data.update({
'result_modifier': 'na',
'result_modifier': result_modifier_na,
'annulled': True,
'annulment_date': now,
'report': False,

View File

@ -1546,6 +1546,7 @@ class ProjectGLPReport09(Report):
NotebookLine = pool.get('lims.notebook.line')
ResultsReport = pool.get('lims.results_report')
Analysis = pool.get('lims.analysis')
ResultModifier = pool.get('lims.result_modifier')
report_context = super().get_context(records, header, data)
@ -1561,10 +1562,12 @@ class ProjectGLPReport09(Report):
for fraction in fractions:
cursor.execute('SELECT DISTINCT(nl.results_report) , '
'nl.result_modifier, nl.result, a.description '
'rm.code, nl.result, a.description '
'FROM "' + NotebookLine._table + '" nl '
'INNER JOIN "' + Service._table + '" s '
'ON nl.service = s.id '
'LEFT JOIN "' + ResultModifier._table + '" rm '
'ON rm.id = nl.result_modifier '
'INNER JOIN "' + Analysis._table + '" a '
'ON a.id = nl.analysis '
'WHERE s.fraction = %s '
@ -1597,7 +1600,7 @@ class ProjectGLPReport09(Report):
re = None
analysis = None
if report_id[1] == 'eq':
if not report_id[1]:
re = report_id[2]
else:
if report_id[1] == 'low':

View File

@ -3,7 +3,7 @@
<field name="fraction"/>
<field name="repetition"/>
<field name="analysis"/>
<field name="result_modifier"/>
<field name="result_modifier" widget="selection"/>
<field name="result"/>
<field name="initial_unit"/>
<field name="method"/>

View File

@ -593,7 +593,7 @@ class NotebookLoadResultsManualLine(metaclass=PoolMeta):
if self.end_date:
return self.end_date
if (self.result or self.literal_result or self.qualitative_value or
self.result_modifier not in ('eq', 'low')):
(self.result_modifier and self.result_modifier.code != 'low')):
return Date.today()
return None
@ -628,7 +628,8 @@ class NotebookLoadResultsManual(metaclass=PoolMeta):
notebook_line_write = {
'result': data.result,
'qualitative_value': data.qualitative_value,
'result_modifier': data.result_modifier,
'result_modifier': (data.result_modifier.id if
data.result_modifier else None),
'end_date': data.end_date,
'chromatogram': data.chromatogram,
'initial_unit': (data.initial_unit.id if
@ -636,12 +637,12 @@ class NotebookLoadResultsManual(metaclass=PoolMeta):
'comments': data.comments,
'literal_result': data.literal_result,
'converted_result': None,
'converted_result_modifier': 'eq',
'converted_result_modifier': None,
'backup': None,
'verification': None,
'uncertainty': None,
}
if data.result_modifier == 'na':
if data.result_modifier and data.result_modifier.code == 'na':
notebook_line_write['annulled'] = True
notebook_line_write['annulment_date'] = datetime.now()
notebook_line_write['report'] = False