lims: add new wizard to generate results report
This commit is contained in:
parent
a7aa3e0507
commit
5821abbb2a
|
@ -173,6 +173,7 @@ def register():
|
||||||
results_report.GenerateResultsReportResultAutExcludedNotebookLine,
|
results_report.GenerateResultsReportResultAutExcludedNotebookLine,
|
||||||
results_report.GenerateResultsReportResultMan,
|
results_report.GenerateResultsReportResultMan,
|
||||||
results_report.OpenSamplesPendingReportingStart,
|
results_report.OpenSamplesPendingReportingStart,
|
||||||
|
results_report.GenerateReportStart,
|
||||||
certification.DuplicateAnalysisFamilyStart,
|
certification.DuplicateAnalysisFamilyStart,
|
||||||
results_report.ResultsReportAnnulationStart,
|
results_report.ResultsReportAnnulationStart,
|
||||||
sample.CountersampleStorageStart,
|
sample.CountersampleStorageStart,
|
||||||
|
@ -303,6 +304,7 @@ def register():
|
||||||
results_report.DivideReports,
|
results_report.DivideReports,
|
||||||
results_report.GenerateResultsReport,
|
results_report.GenerateResultsReport,
|
||||||
results_report.OpenSamplesPendingReporting,
|
results_report.OpenSamplesPendingReporting,
|
||||||
|
results_report.GenerateReport,
|
||||||
results_report.PrintResultsReport,
|
results_report.PrintResultsReport,
|
||||||
certification.DuplicateAnalysisFamily,
|
certification.DuplicateAnalysisFamily,
|
||||||
results_report.ServiceResultsReport,
|
results_report.ServiceResultsReport,
|
||||||
|
|
|
@ -2591,6 +2591,38 @@ msgctxt "field:lims.notebook.add_internal_relations.start,analysis_domain:"
|
||||||
msgid "Internal relations domain"
|
msgid "Internal relations domain"
|
||||||
msgstr "Dominio para Relaciones internas"
|
msgstr "Dominio para Relaciones internas"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,corrective:"
|
||||||
|
msgid "Corrective"
|
||||||
|
msgstr "Rectificativo"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,notebooks:"
|
||||||
|
msgid "Samples"
|
||||||
|
msgstr "Muestras"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,preliminary:"
|
||||||
|
msgid "Preliminary"
|
||||||
|
msgstr "Preliminar"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,report:"
|
||||||
|
msgid "Target Report"
|
||||||
|
msgstr "Informe destino"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,report_domain:"
|
||||||
|
msgid "Target Report domain"
|
||||||
|
msgstr "Dominio para Informe destino"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,report_readonly:"
|
||||||
|
msgid "Target Report readonly"
|
||||||
|
msgstr "Informe destino sólo lectura"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,reports_created:"
|
||||||
|
msgid "Reports created"
|
||||||
|
msgstr "Informes creados"
|
||||||
|
|
||||||
|
msgctxt "field:lims.notebook.generate_results_report.start,type:"
|
||||||
|
msgid "Type"
|
||||||
|
msgstr "Tipo"
|
||||||
|
|
||||||
msgctxt ""
|
msgctxt ""
|
||||||
"field:lims.notebook.internal_relations_calc_1.relation,internal_relation:"
|
"field:lims.notebook.internal_relations_calc_1.relation,internal_relation:"
|
||||||
msgid "Internal relation"
|
msgid "Internal relation"
|
||||||
|
@ -4684,6 +4716,10 @@ msgctxt "field:lims.results_report,english_report:"
|
||||||
msgid "English report"
|
msgid "English report"
|
||||||
msgstr "Informe en inglés"
|
msgstr "Informe en inglés"
|
||||||
|
|
||||||
|
msgctxt "field:lims.results_report,entry:"
|
||||||
|
msgid "Entry"
|
||||||
|
msgstr "Ingreso"
|
||||||
|
|
||||||
msgctxt "field:lims.results_report,generation_type:"
|
msgctxt "field:lims.results_report,generation_type:"
|
||||||
msgid "Generation type"
|
msgid "Generation type"
|
||||||
msgstr "Tipo de generación"
|
msgstr "Tipo de generación"
|
||||||
|
@ -6691,6 +6727,10 @@ msgctxt "model:ir.action,name:wiz_notebook_evaluate_rules"
|
||||||
msgid "Evaluate Rules"
|
msgid "Evaluate Rules"
|
||||||
msgstr "10) Evaluar Reglas de cuaderno"
|
msgstr "10) Evaluar Reglas de cuaderno"
|
||||||
|
|
||||||
|
msgctxt "model:ir.action,name:wiz_notebook_generate_results_report"
|
||||||
|
msgid "Generate Results Report"
|
||||||
|
msgstr "Generar informe de resultados"
|
||||||
|
|
||||||
msgctxt "model:ir.action,name:wiz_notebook_line_evaluate_rules"
|
msgctxt "model:ir.action,name:wiz_notebook_line_evaluate_rules"
|
||||||
msgid "Evaluate Rules"
|
msgid "Evaluate Rules"
|
||||||
msgstr "10) Evaluar Reglas de cuaderno"
|
msgstr "10) Evaluar Reglas de cuaderno"
|
||||||
|
@ -8383,6 +8423,10 @@ msgctxt "model:lims.notebook.evaluate_rules.start,name:"
|
||||||
msgid "Evaluate Rules"
|
msgid "Evaluate Rules"
|
||||||
msgstr "Evaluar Reglas de cuaderno"
|
msgstr "Evaluar Reglas de cuaderno"
|
||||||
|
|
||||||
|
msgctxt "model:lims.notebook.generate_results_report.start,name:"
|
||||||
|
msgid "Generate Results Report"
|
||||||
|
msgstr "Generar informe de resultados"
|
||||||
|
|
||||||
msgctxt "model:lims.notebook.initial_concentration_calc.start,name:"
|
msgctxt "model:lims.notebook.initial_concentration_calc.start,name:"
|
||||||
msgid "Initial Concentration Calculation"
|
msgid "Initial Concentration Calculation"
|
||||||
msgstr "Cálculo de concentración inicial"
|
msgstr "Cálculo de concentración inicial"
|
||||||
|
@ -11263,6 +11307,22 @@ msgctxt "selection:lims.laboratory,section:"
|
||||||
msgid "Microbiology"
|
msgid "Microbiology"
|
||||||
msgstr "Microbiología"
|
msgstr "Microbiología"
|
||||||
|
|
||||||
|
msgctxt "selection:lims.notebook.generate_results_report.start,type:"
|
||||||
|
msgid "Complementary"
|
||||||
|
msgstr "Complementario"
|
||||||
|
|
||||||
|
msgctxt "selection:lims.notebook.generate_results_report.start,type:"
|
||||||
|
msgid "Corrective"
|
||||||
|
msgstr "Rectificativo"
|
||||||
|
|
||||||
|
msgctxt "selection:lims.notebook.generate_results_report.start,type:"
|
||||||
|
msgid "Final"
|
||||||
|
msgstr "Final"
|
||||||
|
|
||||||
|
msgctxt "selection:lims.notebook.generate_results_report.start,type:"
|
||||||
|
msgid "Preliminary"
|
||||||
|
msgstr "Preliminar"
|
||||||
|
|
||||||
msgctxt ""
|
msgctxt ""
|
||||||
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
|
"selection:lims.notebook.internal_relations_calc_2.variable,converted_result_modifier:"
|
||||||
msgid "<"
|
msgid "<"
|
||||||
|
@ -13610,6 +13670,14 @@ msgctxt "wizard_button:lims.notebook.evaluate_rules,start,ok:"
|
||||||
msgid "Ok"
|
msgid "Ok"
|
||||||
msgstr "Aceptar"
|
msgstr "Aceptar"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:lims.notebook.generate_results_report,start,end:"
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:lims.notebook.generate_results_report,start,generate:"
|
||||||
|
msgid "Generate"
|
||||||
|
msgstr "Generar"
|
||||||
|
|
||||||
msgctxt "wizard_button:lims.notebook.initial_concentration_calc,start,end:"
|
msgctxt "wizard_button:lims.notebook.initial_concentration_calc,start,end:"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
|
@ -6,6 +6,7 @@ from io import BytesIO
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from PyPDF2 import PdfFileMerger
|
from PyPDF2 import PdfFileMerger
|
||||||
|
|
||||||
|
from trytond import backend
|
||||||
from trytond.model import ModelView, ModelSQL, fields
|
from trytond.model import ModelView, ModelSQL, fields
|
||||||
from trytond.wizard import Wizard, StateTransition, StateView, StateAction, \
|
from trytond.wizard import Wizard, StateTransition, StateView, StateAction, \
|
||||||
Button
|
Button
|
||||||
|
@ -28,11 +29,11 @@ __all__ = ['ResultsReport', 'ResultsReportVersion',
|
||||||
'GenerateResultsReportResultAutExcludedNotebook',
|
'GenerateResultsReportResultAutExcludedNotebook',
|
||||||
'GenerateResultsReportResultAutExcludedNotebookLine',
|
'GenerateResultsReportResultAutExcludedNotebookLine',
|
||||||
'GenerateResultsReport', 'OpenSamplesPendingReportingStart',
|
'GenerateResultsReport', 'OpenSamplesPendingReportingStart',
|
||||||
'OpenSamplesPendingReporting', 'PrintResultsReport',
|
'OpenSamplesPendingReporting', 'GenerateReportStart', 'GenerateReport',
|
||||||
'ServiceResultsReport', 'FractionResultsReport', 'SampleResultsReport',
|
'PrintResultsReport', 'ServiceResultsReport', 'FractionResultsReport',
|
||||||
'ResultsReportSample', 'ResultsReportAnnulationStart',
|
'SampleResultsReport', 'ResultsReportSample',
|
||||||
'ResultsReportAnnulation', 'ResultReport', 'GlobalResultReport',
|
'ResultsReportAnnulationStart', 'ResultsReportAnnulation', 'ResultReport',
|
||||||
'ResultReportTranscription']
|
'GlobalResultReport', 'ResultReportTranscription']
|
||||||
|
|
||||||
|
|
||||||
def get_print_date():
|
def get_print_date():
|
||||||
|
@ -53,11 +54,24 @@ class ResultsReport(ModelSQL, ModelView):
|
||||||
number = fields.Char('Number', select=True, readonly=True)
|
number = fields.Char('Number', select=True, readonly=True)
|
||||||
versions = fields.One2Many('lims.results_report.version',
|
versions = fields.One2Many('lims.results_report.version',
|
||||||
'results_report', 'Laboratories', readonly=True)
|
'results_report', 'Laboratories', readonly=True)
|
||||||
|
party = fields.Many2One('party.party', 'Party', readonly=True)
|
||||||
|
entry = fields.Many2One('lims.entry', 'Entry', readonly=True)
|
||||||
|
notebook = fields.Many2One('lims.notebook', 'Laboratory notebook')
|
||||||
report_grouper = fields.Integer('Report Grouper')
|
report_grouper = fields.Integer('Report Grouper')
|
||||||
generation_type = fields.Char('Generation type')
|
generation_type = fields.Char('Generation type')
|
||||||
cie_fraction_type = fields.Boolean('QA', readonly=True)
|
cie_fraction_type = fields.Boolean('QA', readonly=True)
|
||||||
party = fields.Many2One('party.party', 'Party', readonly=True)
|
english_report = fields.Boolean('English report')
|
||||||
notebook = fields.Many2One('lims.notebook', 'Laboratory notebook')
|
single_sending_report = fields.Function(fields.Boolean(
|
||||||
|
'Single sending'), 'get_single_sending_report',
|
||||||
|
searcher='search_single_sending_report')
|
||||||
|
single_sending_report_ready = fields.Function(fields.Boolean(
|
||||||
|
'Single sending Ready'), 'get_single_sending_report_ready')
|
||||||
|
create_date2 = fields.Function(fields.DateTime('Create Date'),
|
||||||
|
'get_create_date2', searcher='search_create_date2')
|
||||||
|
write_date2 = fields.DateTime('Write Date', readonly=True)
|
||||||
|
attachments = fields.One2Many('ir.attachment', 'resource', 'Attachments')
|
||||||
|
|
||||||
|
# PDF Report Cache
|
||||||
report_cache = fields.Binary('Report cache', readonly=True,
|
report_cache = fields.Binary('Report cache', readonly=True,
|
||||||
file_id='report_cache_id', store_prefix='results_report')
|
file_id='report_cache_id', store_prefix='results_report')
|
||||||
report_cache_id = fields.Char('Report cache id', readonly=True)
|
report_cache_id = fields.Char('Report cache id', readonly=True)
|
||||||
|
@ -66,16 +80,24 @@ class ResultsReport(ModelSQL, ModelView):
|
||||||
file_id='report_cache_eng_id', store_prefix='results_report')
|
file_id='report_cache_eng_id', store_prefix='results_report')
|
||||||
report_cache_eng_id = fields.Char('Report cache id', readonly=True)
|
report_cache_eng_id = fields.Char('Report cache id', readonly=True)
|
||||||
report_format_eng = fields.Char('Report format', readonly=True)
|
report_format_eng = fields.Char('Report format', readonly=True)
|
||||||
single_sending_report = fields.Function(fields.Boolean(
|
|
||||||
'Single sending'), 'get_single_sending_report',
|
@classmethod
|
||||||
searcher='search_single_sending_report')
|
def __register__(cls, module_name):
|
||||||
single_sending_report_ready = fields.Function(fields.Boolean(
|
TableHandler = backend.get('TableHandler')
|
||||||
'Single sending Ready'), 'get_single_sending_report_ready')
|
tablehandler = TableHandler(cls, module_name)
|
||||||
english_report = fields.Boolean('English report')
|
|
||||||
create_date2 = fields.Function(fields.DateTime('Create Date'),
|
notebook_exist = tablehandler.column_exist('notebook')
|
||||||
'get_create_date2', searcher='search_create_date2')
|
entry_exist = tablehandler.column_exist('entry')
|
||||||
write_date2 = fields.DateTime('Write Date', readonly=True)
|
super(ResultsReport, cls).__register__(module_name)
|
||||||
attachments = fields.One2Many('ir.attachment', 'resource', 'Attachments')
|
|
||||||
|
if notebook_exist and not entry_exist:
|
||||||
|
cursor = Transaction().connection.cursor()
|
||||||
|
cursor.execute('UPDATE "lims_results_report" r '
|
||||||
|
'SET entry = s.entry '
|
||||||
|
'FROM "lims_sample" s '
|
||||||
|
'INNER JOIN "lims_fraction" f ON s.id = f.sample '
|
||||||
|
'INNER JOIN "lims_notebook" n ON f.id = n.fraction '
|
||||||
|
'WHERE r.notebook = n.id')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
|
@ -120,47 +142,42 @@ class ResultsReport(ModelSQL, ModelView):
|
||||||
return [
|
return [
|
||||||
'number',
|
'number',
|
||||||
'versions',
|
'versions',
|
||||||
|
'party',
|
||||||
|
'entry',
|
||||||
|
'notebook',
|
||||||
'report_grouper',
|
'report_grouper',
|
||||||
'generation_type',
|
'generation_type',
|
||||||
'cie_fraction_type',
|
'cie_fraction_type',
|
||||||
'party',
|
|
||||||
'notebook',
|
|
||||||
'english_report',
|
'english_report',
|
||||||
'attachments',
|
'attachments',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_single_sending_report(self, name):
|
def get_single_sending_report(self, name):
|
||||||
pool = Pool()
|
if self.entry:
|
||||||
Notebook = pool.get('lims.notebook')
|
return self.entry.single_sending_report
|
||||||
|
|
||||||
if self.notebook:
|
|
||||||
with Transaction().set_user(0):
|
|
||||||
notebook = Notebook(self.notebook.id)
|
|
||||||
return notebook.fraction.sample.entry.single_sending_report
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search_single_sending_report(cls, name, clause):
|
def search_single_sending_report(cls, name, clause):
|
||||||
return [('notebook.fraction.sample.entry.' + name,) +
|
return [('entry.' + name,) + tuple(clause[1:])]
|
||||||
tuple(clause[1:])]
|
|
||||||
|
|
||||||
def get_single_sending_report_ready(self, name):
|
@classmethod
|
||||||
pool = Pool()
|
def get_single_sending_report_ready(cls, reports, name):
|
||||||
Notebook = pool.get('lims.notebook')
|
EntryDetailAnalysis = Pool().get('lims.entry.detail.analysis')
|
||||||
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
result = {}
|
||||||
|
for r in reports:
|
||||||
if not self.single_sending_report:
|
if not r.single_sending_report or not not r.entry:
|
||||||
return False
|
result[r.id] = False
|
||||||
with Transaction().set_user(0):
|
elif EntryDetailAnalysis.search_count([
|
||||||
notebook = Notebook(self.notebook.id)
|
('entry', '=', r.entry),
|
||||||
if EntryDetailAnalysis.search([
|
('report_grouper', '=', r.report_grouper),
|
||||||
('fraction', '=', notebook.fraction.id),
|
('report', '=', True),
|
||||||
('report', '=', True),
|
('state', '!=', 'reported'),
|
||||||
('report_grouper', '=', self.report_grouper),
|
]) > 0:
|
||||||
('state', '!=', 'reported'),
|
result[r.id] = False
|
||||||
]):
|
else:
|
||||||
return False
|
result[r.id] = True
|
||||||
return True
|
return result
|
||||||
|
|
||||||
def get_create_date2(self, name):
|
def get_create_date2(self, name):
|
||||||
return self.create_date.replace(microsecond=0)
|
return self.create_date.replace(microsecond=0)
|
||||||
|
@ -587,44 +604,46 @@ class ResultsReportVersionDetail(ModelSQL, ModelView):
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
def release(cls, details):
|
def release(cls, details):
|
||||||
ResultsLine = Pool().get('lims.results_report.version.detail.line')
|
ResultsSample = Pool().get('lims.results_report.version.detail.sample')
|
||||||
cls.link_notebook_lines(details)
|
cls.link_notebook_lines(details)
|
||||||
for detail in details:
|
for detail in details:
|
||||||
defaults = {
|
# copy samples from previous valid version
|
||||||
'state': 'released',
|
|
||||||
'valid': True,
|
|
||||||
'release_uid': int(Transaction().user),
|
|
||||||
'release_date': datetime.now(),
|
|
||||||
}
|
|
||||||
valid_details = cls.search([
|
valid_details = cls.search([
|
||||||
('report_version', '=', detail.report_version.id),
|
('report_version', '=', detail.report_version.id),
|
||||||
('valid', '=', True),
|
('valid', '=', True),
|
||||||
])
|
])
|
||||||
if valid_details:
|
for vd in valid_details:
|
||||||
vd_ids = []
|
for valid_sample in vd.samples:
|
||||||
samples = []
|
sample_default = ResultsSample._get_sample_copy(
|
||||||
for vd in valid_details:
|
valid_sample)
|
||||||
vd_ids.append(vd.id)
|
existing_sample = ResultsSample.search([
|
||||||
for sample in vd.samples:
|
('version_detail', '=', detail.id),
|
||||||
notebook_lines = [
|
('notebook', '=', valid_sample.notebook.id),
|
||||||
{'notebook_line': nline.notebook_line.id}
|
], limit=1)
|
||||||
for nline in sample.notebook_lines]
|
if not existing_sample:
|
||||||
samples.append({
|
sample_default['version_detail'] = detail.id
|
||||||
'notebook': sample.notebook.id,
|
sample_default['notebook'] = valid_sample.notebook.id
|
||||||
'notebook_lines': [('create', notebook_lines)],
|
ResultsSample.create([sample_default])
|
||||||
})
|
else:
|
||||||
if samples:
|
ResultsSample.write(existing_sample, sample_default)
|
||||||
defaults['samples'] = [('create', samples)]
|
|
||||||
|
|
||||||
cls.write(valid_details, {
|
# delete samples from previous valid version
|
||||||
'valid': False,
|
old_samples = ResultsSample.search([
|
||||||
})
|
('version_detail.report_version', '=',
|
||||||
old_lines = ResultsLine.search([
|
detail.report_version.id),
|
||||||
('detail_sample.version_detail.id', 'in', vd_ids),
|
('version_detail.valid', '=', True),
|
||||||
])
|
])
|
||||||
ResultsLine.delete(old_lines)
|
ResultsSample.delete(old_samples)
|
||||||
|
|
||||||
cls.write([detail], defaults)
|
cls.write(valid_details, {
|
||||||
|
'valid': False,
|
||||||
|
})
|
||||||
|
cls.write([detail], {
|
||||||
|
'state': 'released',
|
||||||
|
'valid': True,
|
||||||
|
'release_uid': int(Transaction().user),
|
||||||
|
'release_date': datetime.now(),
|
||||||
|
})
|
||||||
detail.generate_report()
|
detail.generate_report()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -843,11 +862,12 @@ class ResultsReportVersionDetail(ModelSQL, ModelView):
|
||||||
def get_fraction_comments(cls, details, name):
|
def get_fraction_comments(cls, details, name):
|
||||||
result = {}
|
result = {}
|
||||||
for d in details:
|
for d in details:
|
||||||
result[d.id] = None
|
comments = []
|
||||||
notebook = getattr(d.report_version.results_report,
|
for sample in d.samples:
|
||||||
'notebook', None)
|
fraction_comments = sample.notebook.fraction_comments
|
||||||
if notebook:
|
if fraction_comments:
|
||||||
result[d.id] = getattr(notebook, 'fraction_comments')
|
comments.append(fraction_comments)
|
||||||
|
result[d.id] = comments and '\n'.join(comments) or None
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_icon(self, name):
|
def get_icon(self, name):
|
||||||
|
@ -855,6 +875,19 @@ class ResultsReportVersionDetail(ModelSQL, ModelView):
|
||||||
return 'lims-blue'
|
return 'lims-blue'
|
||||||
return 'lims-white'
|
return 'lims-white'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_detail_copy(cls, detail):
|
||||||
|
detail_default = {}
|
||||||
|
detail_default['report_type_forced'] = detail.report_type_forced
|
||||||
|
detail_default['report_result_type_forced'] = (
|
||||||
|
detail.report_result_type_forced)
|
||||||
|
if detail.signer:
|
||||||
|
detail_default['signer'] = detail.signer.id
|
||||||
|
if detail.resultrange_origin:
|
||||||
|
detail_default['resultrange_origin'] = detail.resultrange_origin.id
|
||||||
|
detail_default['comments'] = str(detail.comments or '')
|
||||||
|
return detail_default
|
||||||
|
|
||||||
|
|
||||||
class ResultsReportVersionDetailSample(ModelSQL, ModelView):
|
class ResultsReportVersionDetailSample(ModelSQL, ModelView):
|
||||||
'Results Report Version Detail Sample'
|
'Results Report Version Detail Sample'
|
||||||
|
@ -885,6 +918,16 @@ class ResultsReportVersionDetailSample(ModelSQL, ModelView):
|
||||||
result[name][s.id] = getattr(s.notebook, name, None)
|
result[name][s.id] = getattr(s.notebook, name, None)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_sample_copy(cls, sample):
|
||||||
|
sample_default = {}
|
||||||
|
notebook_lines = [
|
||||||
|
{'notebook_line': nline.notebook_line.id}
|
||||||
|
for nline in sample.notebook_lines]
|
||||||
|
if notebook_lines:
|
||||||
|
sample_default['notebook_lines'] = [('create', notebook_lines)]
|
||||||
|
return sample_default
|
||||||
|
|
||||||
|
|
||||||
class ResultsReportVersionDetailLine(ModelSQL, ModelView):
|
class ResultsReportVersionDetailLine(ModelSQL, ModelView):
|
||||||
'Results Report Version Detail Line'
|
'Results Report Version Detail Line'
|
||||||
|
@ -1647,6 +1690,7 @@ class GenerateResultsReport(Wizard):
|
||||||
if line.notebook.id not in notebooks:
|
if line.notebook.id not in notebooks:
|
||||||
notebooks[line.notebook.id] = {
|
notebooks[line.notebook.id] = {
|
||||||
'party': line.notebook.party.id,
|
'party': line.notebook.party.id,
|
||||||
|
'entry': line.notebook.fraction.entry.id,
|
||||||
'notebook': line.notebook.id,
|
'notebook': line.notebook.id,
|
||||||
'divided_report': line.notebook.divided_report,
|
'divided_report': line.notebook.divided_report,
|
||||||
'english_report': (
|
'english_report': (
|
||||||
|
@ -1676,6 +1720,7 @@ class GenerateResultsReport(Wizard):
|
||||||
}
|
}
|
||||||
reports = {
|
reports = {
|
||||||
'party': notebook['party'],
|
'party': notebook['party'],
|
||||||
|
'entry': notebook['entry'],
|
||||||
'notebook': notebook['notebook'],
|
'notebook': notebook['notebook'],
|
||||||
'report_grouper': 0,
|
'report_grouper': 0,
|
||||||
'generation_type': 'aut',
|
'generation_type': 'aut',
|
||||||
|
@ -1711,6 +1756,7 @@ class GenerateResultsReport(Wizard):
|
||||||
}
|
}
|
||||||
reports = {
|
reports = {
|
||||||
'party': notebook['party'],
|
'party': notebook['party'],
|
||||||
|
'entry': notebook['entry'],
|
||||||
'notebook': notebook['notebook'],
|
'notebook': notebook['notebook'],
|
||||||
'report_grouper': grouper,
|
'report_grouper': grouper,
|
||||||
'generation_type': 'aut',
|
'generation_type': 'aut',
|
||||||
|
@ -1907,6 +1953,7 @@ class GenerateResultsReport(Wizard):
|
||||||
if key not in parties:
|
if key not in parties:
|
||||||
parties[key] = {
|
parties[key] = {
|
||||||
'party': line.notebook.party.id,
|
'party': line.notebook.party.id,
|
||||||
|
'entry': line.notebook.fraction.entry.id,
|
||||||
'english_report': (
|
'english_report': (
|
||||||
line.notebook.fraction.entry.english_report),
|
line.notebook.fraction.entry.english_report),
|
||||||
'cie_fraction_type': (
|
'cie_fraction_type': (
|
||||||
|
@ -1953,6 +2000,7 @@ class GenerateResultsReport(Wizard):
|
||||||
}
|
}
|
||||||
reports = {
|
reports = {
|
||||||
'party': party['party'],
|
'party': party['party'],
|
||||||
|
'entry': party['entry'],
|
||||||
'notebook': None,
|
'notebook': None,
|
||||||
'report_grouper': grouper,
|
'report_grouper': grouper,
|
||||||
'generation_type': 'man',
|
'generation_type': 'man',
|
||||||
|
@ -1971,6 +2019,7 @@ class GenerateResultsReport(Wizard):
|
||||||
if line.notebook.id not in notebooks:
|
if line.notebook.id not in notebooks:
|
||||||
notebooks[line.notebook.id] = {
|
notebooks[line.notebook.id] = {
|
||||||
'party': line.notebook.party.id,
|
'party': line.notebook.party.id,
|
||||||
|
'entry': line.notebook.fraction.entry.id,
|
||||||
'notebook': line.notebook.id,
|
'notebook': line.notebook.id,
|
||||||
'divided_report': line.notebook.divided_report,
|
'divided_report': line.notebook.divided_report,
|
||||||
'english_report': (
|
'english_report': (
|
||||||
|
@ -2001,6 +2050,7 @@ class GenerateResultsReport(Wizard):
|
||||||
}
|
}
|
||||||
reports = {
|
reports = {
|
||||||
'party': notebook['party'],
|
'party': notebook['party'],
|
||||||
|
'entry': notebook['entry'],
|
||||||
'notebook': notebook['notebook'],
|
'notebook': notebook['notebook'],
|
||||||
'report_grouper': 0,
|
'report_grouper': 0,
|
||||||
'generation_type': 'man',
|
'generation_type': 'man',
|
||||||
|
@ -2039,6 +2089,7 @@ class GenerateResultsReport(Wizard):
|
||||||
}
|
}
|
||||||
reports = {
|
reports = {
|
||||||
'party': notebook['party'],
|
'party': notebook['party'],
|
||||||
|
'entry': notebook['entry'],
|
||||||
'notebook': notebook['notebook'],
|
'notebook': notebook['notebook'],
|
||||||
'report_grouper': grouper,
|
'report_grouper': grouper,
|
||||||
'generation_type': 'man',
|
'generation_type': 'man',
|
||||||
|
@ -2069,6 +2120,7 @@ class GenerateResultsReport(Wizard):
|
||||||
|
|
||||||
actual_report = ResultsReport.search([
|
actual_report = ResultsReport.search([
|
||||||
('party', '=', reports['party']),
|
('party', '=', reports['party']),
|
||||||
|
('entry', '=', reports['entry']),
|
||||||
('notebook', '=', reports['notebook']),
|
('notebook', '=', reports['notebook']),
|
||||||
('report_grouper', '=', reports['report_grouper']),
|
('report_grouper', '=', reports['report_grouper']),
|
||||||
('generation_type', '=', reports['generation_type']),
|
('generation_type', '=', reports['generation_type']),
|
||||||
|
@ -2191,6 +2243,425 @@ class OpenSamplesPendingReporting(Wizard):
|
||||||
return 'end'
|
return 'end'
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateReportStart(ModelView):
|
||||||
|
'Generate Results Report'
|
||||||
|
__name__ = 'lims.notebook.generate_results_report.start'
|
||||||
|
|
||||||
|
notebooks = fields.One2Many('lims.notebook', None, 'Samples',
|
||||||
|
readonly=True)
|
||||||
|
report = fields.Many2One('lims.results_report', 'Target Report',
|
||||||
|
states={'readonly': Bool(Eval('report_readonly'))},
|
||||||
|
domain=[('id', 'in', Eval('report_domain'))],
|
||||||
|
depends=['report_readonly', 'report_domain'])
|
||||||
|
report_readonly = fields.Boolean('Target Report readonly')
|
||||||
|
report_domain = fields.One2Many('lims.results_report', None,
|
||||||
|
'Target Report domain')
|
||||||
|
type = fields.Selection([
|
||||||
|
('preliminary', 'Preliminary'),
|
||||||
|
('final', 'Final'),
|
||||||
|
('complementary', 'Complementary'),
|
||||||
|
('corrective', 'Corrective'),
|
||||||
|
], 'Type', states={'readonly': True})
|
||||||
|
preliminary = fields.Boolean('Preliminary')
|
||||||
|
corrective = fields.Boolean('Corrective',
|
||||||
|
states={'readonly': ~Eval('type').in_(
|
||||||
|
['complementary', 'corrective'])},
|
||||||
|
depends=['type'])
|
||||||
|
reports_created = fields.One2Many('lims.results_report.version.detail',
|
||||||
|
None, 'Reports created')
|
||||||
|
|
||||||
|
@fields.depends('report', 'preliminary', 'corrective')
|
||||||
|
def on_change_with_type(self, name=None):
|
||||||
|
if self.preliminary:
|
||||||
|
return 'preliminary'
|
||||||
|
report_state = self._get_report_state()
|
||||||
|
if report_state == 'draft':
|
||||||
|
return 'final'
|
||||||
|
if self.corrective:
|
||||||
|
return 'corrective'
|
||||||
|
return 'complementary'
|
||||||
|
|
||||||
|
def _get_report_state(self):
|
||||||
|
ResultsDetail = Pool().get('lims.results_report.version.detail')
|
||||||
|
if not self.report:
|
||||||
|
return 'draft'
|
||||||
|
report_id = self.report.id
|
||||||
|
laboratory_id = Transaction().context.get(
|
||||||
|
'samples_pending_reporting_laboratory', None)
|
||||||
|
if not laboratory_id:
|
||||||
|
return 'draft'
|
||||||
|
last_detail = ResultsDetail.search([
|
||||||
|
('report_version.results_report', '=', report_id),
|
||||||
|
('report_version.laboratory', '=', laboratory_id),
|
||||||
|
], order=[('id', 'DESC')], limit=1)
|
||||||
|
if last_detail:
|
||||||
|
return last_detail[0].state
|
||||||
|
return 'draft'
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateReport(Wizard):
|
||||||
|
'Generate Results Report'
|
||||||
|
__name__ = 'lims.notebook.generate_results_report'
|
||||||
|
|
||||||
|
start = StateView('lims.notebook.generate_results_report.start',
|
||||||
|
'lims.notebook_generate_results_report_view_form', [
|
||||||
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
|
Button('Generate', 'generate', 'tryton-ok', default=True),
|
||||||
|
])
|
||||||
|
generate = StateTransition()
|
||||||
|
open_ = StateAction('lims.act_lims_results_report_version_detail')
|
||||||
|
|
||||||
|
def default_start(self, fields):
|
||||||
|
pool = Pool()
|
||||||
|
Notebook = pool.get('lims.notebook')
|
||||||
|
ResultsReport = pool.get('lims.results_report')
|
||||||
|
ResultsDetail = pool.get('lims.results_report.version.detail')
|
||||||
|
|
||||||
|
res = {
|
||||||
|
'notebooks': [],
|
||||||
|
'report_readonly': False,
|
||||||
|
'report_domain': [],
|
||||||
|
'type': 'final',
|
||||||
|
'preliminary': False,
|
||||||
|
'corrective': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
party = None
|
||||||
|
report_grouper = None
|
||||||
|
cie_fraction_type = None
|
||||||
|
|
||||||
|
for notebook in Notebook.browse(Transaction().context['active_ids']):
|
||||||
|
res['notebooks'].append(notebook.id)
|
||||||
|
if not res['report_readonly']:
|
||||||
|
if not party:
|
||||||
|
party = notebook.party.id
|
||||||
|
elif party != notebook.party.id:
|
||||||
|
res['report_readonly'] = True
|
||||||
|
for line in notebook.lines:
|
||||||
|
if not report_grouper:
|
||||||
|
report_grouper = line.analysis_detail.report_grouper
|
||||||
|
elif report_grouper != line.analysis_detail.report_grouper:
|
||||||
|
res['report_readonly'] = True
|
||||||
|
break
|
||||||
|
if cie_fraction_type is None:
|
||||||
|
cie_fraction_type = notebook.fraction.cie_fraction_type
|
||||||
|
elif cie_fraction_type != notebook.fraction.cie_fraction_type:
|
||||||
|
res['report_readonly'] = True
|
||||||
|
|
||||||
|
if notebook.state != 'complete':
|
||||||
|
res['preliminary'] = True
|
||||||
|
res['type'] = 'preliminary'
|
||||||
|
|
||||||
|
if not res['report_readonly']:
|
||||||
|
if res['preliminary']:
|
||||||
|
laboratory_id = Transaction().context.get(
|
||||||
|
'samples_pending_reporting_laboratory', None)
|
||||||
|
last_detail = ResultsDetail.search([
|
||||||
|
('party', '=', party),
|
||||||
|
('laboratory', '=', laboratory_id),
|
||||||
|
], order=[('id', 'DESC')], limit=1)
|
||||||
|
if last_detail and last_detail[0].state == 'preliminary':
|
||||||
|
res['report_domain'] = [
|
||||||
|
last_detail[0].report_version.results_report.id]
|
||||||
|
else:
|
||||||
|
reports = ResultsReport.search([
|
||||||
|
('party', '=', party),
|
||||||
|
('report_grouper', '=', report_grouper),
|
||||||
|
('cie_fraction_type', '=', cie_fraction_type),
|
||||||
|
])
|
||||||
|
if reports:
|
||||||
|
res['report_domain'] = [r.id for r in reports]
|
||||||
|
return res
|
||||||
|
|
||||||
|
def transition_generate(self):
|
||||||
|
pool = Pool()
|
||||||
|
Laboratory = pool.get('lims.laboratory')
|
||||||
|
ResultsVersion = pool.get('lims.results_report.version')
|
||||||
|
ResultsDetail = pool.get('lims.results_report.version.detail')
|
||||||
|
ResultsSample = pool.get('lims.results_report.version.detail.sample')
|
||||||
|
|
||||||
|
laboratory_id = Transaction().context.get(
|
||||||
|
'samples_pending_reporting_laboratory', None)
|
||||||
|
signer = Laboratory(laboratory_id).default_signer.id
|
||||||
|
|
||||||
|
reports_created = []
|
||||||
|
|
||||||
|
state = ('in_progress' if self.start.type == 'preliminary' else
|
||||||
|
'complete')
|
||||||
|
|
||||||
|
if self.start.report: # Result report selected
|
||||||
|
samples = []
|
||||||
|
for notebook in self.start.notebooks:
|
||||||
|
lines = self._get_notebook_lines(notebook.id, laboratory_id,
|
||||||
|
state)
|
||||||
|
notebook_lines = [{'notebook_line': line.id} for line in lines]
|
||||||
|
samples.append({
|
||||||
|
'notebook': notebook.id,
|
||||||
|
'notebook_lines': [('create', notebook_lines)],
|
||||||
|
})
|
||||||
|
details = {
|
||||||
|
'report_type_forced': 'polisample',
|
||||||
|
'type': self.start.type,
|
||||||
|
'signer': signer,
|
||||||
|
'samples': [('create', samples)],
|
||||||
|
}
|
||||||
|
actual_version = ResultsVersion.search([
|
||||||
|
('results_report', '=', self.start.report.id),
|
||||||
|
('laboratory', '=', laboratory_id),
|
||||||
|
], limit=1)
|
||||||
|
if not actual_version:
|
||||||
|
version, = ResultsVersion.create([{
|
||||||
|
'results_report': self.start.report.id,
|
||||||
|
'laboratory': laboratory_id,
|
||||||
|
'details': [('create', [details])],
|
||||||
|
}])
|
||||||
|
reports_details = [d.id for d in version.details]
|
||||||
|
else:
|
||||||
|
actual_version = actual_version[0]
|
||||||
|
draft_detail = ResultsDetail.search([
|
||||||
|
('report_version', '=', actual_version.id),
|
||||||
|
('state', '=', 'draft'),
|
||||||
|
], limit=1)
|
||||||
|
if not draft_detail:
|
||||||
|
details['report_version'] = actual_version.id
|
||||||
|
valid_detail = ResultsDetail.search([
|
||||||
|
('report_version', '=', actual_version.id),
|
||||||
|
('valid', '=', True),
|
||||||
|
], limit=1)
|
||||||
|
if valid_detail:
|
||||||
|
valid_detail = valid_detail[0]
|
||||||
|
details.update(ResultsDetail._get_detail_copy(
|
||||||
|
valid_detail))
|
||||||
|
detail, = ResultsDetail.create([details])
|
||||||
|
reports_details = [detail.id]
|
||||||
|
else:
|
||||||
|
draft_detail = draft_detail[0]
|
||||||
|
for sample in samples:
|
||||||
|
existing_sample = ResultsSample.search([
|
||||||
|
('version_detail', '=', draft_detail.id),
|
||||||
|
('notebook', '=', sample['notebook']),
|
||||||
|
], limit=1)
|
||||||
|
if not existing_sample:
|
||||||
|
sample['version_detail'] = draft_detail.id
|
||||||
|
ResultsSample.create([sample])
|
||||||
|
else:
|
||||||
|
del sample['notebook']
|
||||||
|
ResultsSample.write(existing_sample, sample)
|
||||||
|
|
||||||
|
del details['type']
|
||||||
|
del details['signer']
|
||||||
|
del details['samples']
|
||||||
|
ResultsDetail.write([draft_detail], details)
|
||||||
|
reports_details = [draft_detail.id]
|
||||||
|
|
||||||
|
reports_created.extend(reports_details)
|
||||||
|
|
||||||
|
else: # Not Result report selected
|
||||||
|
|
||||||
|
parties = {}
|
||||||
|
for notebook in self.start.notebooks:
|
||||||
|
key = (notebook.party.id, notebook.fraction.cie_fraction_type)
|
||||||
|
if key not in parties:
|
||||||
|
parties[key] = {
|
||||||
|
'party': notebook.party.id,
|
||||||
|
'entry': notebook.fraction.entry.id,
|
||||||
|
'cie_fraction_type': (
|
||||||
|
notebook.fraction.cie_fraction_type),
|
||||||
|
'english_report': (
|
||||||
|
notebook.fraction.entry.english_report),
|
||||||
|
'lines': [],
|
||||||
|
}
|
||||||
|
lines = self._get_notebook_lines(notebook.id, laboratory_id,
|
||||||
|
state)
|
||||||
|
parties[key]['lines'].extend(lines)
|
||||||
|
|
||||||
|
reports_details = []
|
||||||
|
for party in parties.values():
|
||||||
|
grouped_reports = {}
|
||||||
|
for line in party['lines']:
|
||||||
|
report_grouper = line.analysis_detail.report_grouper
|
||||||
|
if report_grouper not in grouped_reports:
|
||||||
|
grouped_reports[report_grouper] = []
|
||||||
|
grouped_reports[report_grouper].append(line)
|
||||||
|
|
||||||
|
for grouper, nlines in grouped_reports.items():
|
||||||
|
notebooks = {}
|
||||||
|
for line in nlines:
|
||||||
|
if line.notebook.id not in notebooks:
|
||||||
|
notebooks[line.notebook.id] = {
|
||||||
|
'notebook': line.notebook.id,
|
||||||
|
'lines': [],
|
||||||
|
}
|
||||||
|
notebooks[line.notebook.id]['lines'].append(line)
|
||||||
|
|
||||||
|
samples = []
|
||||||
|
for notebook in notebooks.values():
|
||||||
|
notebook_lines = [{'notebook_line': line.id}
|
||||||
|
for line in notebook['lines']]
|
||||||
|
samples.append({
|
||||||
|
'notebook': notebook['notebook'],
|
||||||
|
'notebook_lines': [('create', notebook_lines)],
|
||||||
|
})
|
||||||
|
details = {
|
||||||
|
'report_type_forced': 'polisample',
|
||||||
|
'type': self.start.type,
|
||||||
|
'signer': signer,
|
||||||
|
'samples': [('create', samples)],
|
||||||
|
}
|
||||||
|
versions = {
|
||||||
|
'laboratory': laboratory_id,
|
||||||
|
'details': [('create', [details])],
|
||||||
|
}
|
||||||
|
reports = {
|
||||||
|
'party': party['party'],
|
||||||
|
'entry': party['entry'],
|
||||||
|
'notebook': None,
|
||||||
|
'report_grouper': grouper,
|
||||||
|
'cie_fraction_type': party['cie_fraction_type'],
|
||||||
|
'english_report': party['english_report'],
|
||||||
|
'versions': [('create', [versions])],
|
||||||
|
}
|
||||||
|
report_detail = self._get_results_report(laboratory_id,
|
||||||
|
reports, versions, details, samples)
|
||||||
|
reports_details.extend(report_detail)
|
||||||
|
|
||||||
|
reports_created.extend(reports_details)
|
||||||
|
|
||||||
|
self.start.reports_created = reports_created
|
||||||
|
return 'open_'
|
||||||
|
|
||||||
|
def _get_notebook_lines(self, notebook_id, laboratory_id, state):
|
||||||
|
cursor = Transaction().connection.cursor()
|
||||||
|
pool = Pool()
|
||||||
|
ResultsLine = pool.get('lims.results_report.version.detail.line')
|
||||||
|
NotebookLine = pool.get('lims.notebook.line')
|
||||||
|
EntryDetailAnalysis = pool.get('lims.entry.detail.analysis')
|
||||||
|
Notebook = pool.get('lims.notebook')
|
||||||
|
|
||||||
|
draft_lines_ids = []
|
||||||
|
draft_lines = ResultsLine.search([
|
||||||
|
('detail_sample.notebook', '=', notebook_id),
|
||||||
|
('detail_sample.version_detail.laboratory', '=', laboratory_id),
|
||||||
|
('detail_sample.version_detail.state', 'in', ['draft', 'revised']),
|
||||||
|
('detail_sample.version_detail.type', '!=', 'preliminary'),
|
||||||
|
])
|
||||||
|
if draft_lines:
|
||||||
|
draft_lines_ids = [dl.notebook_line.id for dl in draft_lines]
|
||||||
|
|
||||||
|
clause = [
|
||||||
|
('notebook', '=', notebook_id),
|
||||||
|
('laboratory', '=', laboratory_id),
|
||||||
|
('notebook.fraction.type.report', '=', True),
|
||||||
|
('report', '=', True),
|
||||||
|
('annulled', '=', False),
|
||||||
|
('results_report', '=', None),
|
||||||
|
('id', 'not in', draft_lines_ids),
|
||||||
|
]
|
||||||
|
if state == 'in_progress':
|
||||||
|
clause.extend(Notebook._get_samples_in_progress_clause())
|
||||||
|
else:
|
||||||
|
clause.append(('accepted', '=', True))
|
||||||
|
excluded_notebooks = Notebook._get_excluded_notebooks(
|
||||||
|
[notebook_id], laboratory_id)
|
||||||
|
if excluded_notebooks:
|
||||||
|
for n_id, grouper in excluded_notebooks:
|
||||||
|
cursor.execute('SELECT nl.id '
|
||||||
|
'FROM "' + NotebookLine._table + '" nl '
|
||||||
|
'INNER JOIN "' + EntryDetailAnalysis._table + '" d '
|
||||||
|
'ON d.id = nl.analysis_detail '
|
||||||
|
'WHERE nl.notebook = %s AND d.report_grouper = %s',
|
||||||
|
(n_id, grouper))
|
||||||
|
excluded_notebook_lines = [x[0] for x in cursor.fetchall()]
|
||||||
|
clause.append(('id', 'not in', excluded_notebook_lines))
|
||||||
|
|
||||||
|
return NotebookLine.search(clause)
|
||||||
|
|
||||||
|
def _get_results_report(self, laboratory_id, reports, versions, details,
|
||||||
|
samples, append=True):
|
||||||
|
pool = Pool()
|
||||||
|
ResultsReport = pool.get('lims.results_report')
|
||||||
|
ResultsVersion = pool.get('lims.results_report.version')
|
||||||
|
ResultsDetail = pool.get('lims.results_report.version.detail')
|
||||||
|
ResultsSample = pool.get('lims.results_report.version.detail.sample')
|
||||||
|
|
||||||
|
if not append:
|
||||||
|
report, = ResultsReport.create([reports])
|
||||||
|
reports_details = [d.id for d in report.versions[0].details]
|
||||||
|
return reports_details
|
||||||
|
|
||||||
|
actual_report = ResultsReport.search([
|
||||||
|
('party', '=', reports['party']),
|
||||||
|
('entry', '=', reports['entry']),
|
||||||
|
('report_grouper', '=', reports['report_grouper']),
|
||||||
|
('cie_fraction_type', '=', reports['cie_fraction_type']),
|
||||||
|
], limit=1)
|
||||||
|
if not actual_report:
|
||||||
|
report, = ResultsReport.create([reports])
|
||||||
|
reports_details = [d.id for d in report.versions[0].details]
|
||||||
|
return reports_details
|
||||||
|
|
||||||
|
actual_report = actual_report[0]
|
||||||
|
actual_version = ResultsVersion.search([
|
||||||
|
('results_report', '=', actual_report.id),
|
||||||
|
('laboratory', '=', laboratory_id),
|
||||||
|
], limit=1)
|
||||||
|
if not actual_version:
|
||||||
|
version, = ResultsVersion.create([{
|
||||||
|
'results_report': actual_report.id,
|
||||||
|
'laboratory': laboratory_id,
|
||||||
|
'details': [('create', [details])],
|
||||||
|
}])
|
||||||
|
reports_details = [d.id for d in version.details]
|
||||||
|
return reports_details
|
||||||
|
|
||||||
|
actual_version = actual_version[0]
|
||||||
|
draft_detail = ResultsDetail.search([
|
||||||
|
('report_version', '=', actual_version.id),
|
||||||
|
('state', '=', 'draft'),
|
||||||
|
], limit=1)
|
||||||
|
if not draft_detail:
|
||||||
|
details['report_version'] = actual_version.id
|
||||||
|
valid_detail = ResultsDetail.search([
|
||||||
|
('report_version', '=', actual_version.id),
|
||||||
|
('valid', '=', True),
|
||||||
|
], limit=1)
|
||||||
|
if valid_detail:
|
||||||
|
valid_detail = valid_detail[0]
|
||||||
|
details.update(ResultsDetail._get_detail_copy(valid_detail))
|
||||||
|
detail, = ResultsDetail.create([details])
|
||||||
|
reports_details = [detail.id]
|
||||||
|
return reports_details
|
||||||
|
|
||||||
|
draft_detail = draft_detail[0]
|
||||||
|
for sample in samples:
|
||||||
|
existing_sample = ResultsSample.search([
|
||||||
|
('version_detail', '=', draft_detail.id),
|
||||||
|
('notebook', '=', sample['notebook']),
|
||||||
|
], limit=1)
|
||||||
|
if not existing_sample:
|
||||||
|
sample['version_detail'] = draft_detail.id
|
||||||
|
ResultsSample.create([sample])
|
||||||
|
else:
|
||||||
|
del sample['notebook']
|
||||||
|
ResultsSample.write(existing_sample, sample)
|
||||||
|
|
||||||
|
reports_details = [draft_detail.id]
|
||||||
|
return reports_details
|
||||||
|
|
||||||
|
def do_open_(self, action):
|
||||||
|
action['pyson_domain'] = PYSONEncoder().encode([
|
||||||
|
('id', 'in', [r.id for r in self.start.reports_created]),
|
||||||
|
])
|
||||||
|
self.start.reports_created = None
|
||||||
|
return action, {}
|
||||||
|
|
||||||
|
def transition_open_(self):
|
||||||
|
return 'end'
|
||||||
|
|
||||||
|
def end(self):
|
||||||
|
return 'reload'
|
||||||
|
|
||||||
|
|
||||||
class PrintResultsReport(Wizard):
|
class PrintResultsReport(Wizard):
|
||||||
'Print Results Report'
|
'Print Results Report'
|
||||||
__name__ = 'lims.print_results_report'
|
__name__ = 'lims.print_results_report'
|
||||||
|
|
|
@ -285,6 +285,24 @@
|
||||||
<field name="wiz_name">lims.samples_pending_reporting</field>
|
<field name="wiz_name">lims.samples_pending_reporting</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- Wizard Generate Results Report -->
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="notebook_generate_results_report_view_form">
|
||||||
|
<field name="model">lims.notebook.generate_results_report.start</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">notebook_generate_results_report_form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.action.wizard" id="wiz_notebook_generate_results_report">
|
||||||
|
<field name="name">Generate Results Report</field>
|
||||||
|
<field name="wiz_name">lims.notebook.generate_results_report</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.keyword" id="wiz_notebook_generate_results_report_keyword">
|
||||||
|
<field name="keyword">form_action</field>
|
||||||
|
<field name="model">lims.notebook,-2</field>
|
||||||
|
<field name="action" ref="wiz_notebook_generate_results_report"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
<!-- Wizard Generate Results Reports -->
|
<!-- Wizard Generate Results Reports -->
|
||||||
|
|
||||||
<record model="ir.ui.view" id="lims_generate_results_report_start_view_form">
|
<record model="ir.ui.view" id="lims_generate_results_report_start_view_form">
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<form>
|
||||||
|
<label name="report"/>
|
||||||
|
<field name="report"/>
|
||||||
|
<group id="type" colspan="2" col="4">
|
||||||
|
<label name="type"/>
|
||||||
|
<field name="type"/>
|
||||||
|
<label name="corrective"/>
|
||||||
|
<field name="corrective" xexpand="0"/>
|
||||||
|
</group>
|
||||||
|
<field name="notebooks" colspan="4" mode="tree,form"
|
||||||
|
view_ids="lims.lims_samples_pending_reporting_view_list,lims.lims_samples_pending_reporting_view_form"/>
|
||||||
|
<group id="invisible" colspan="4" col="1">
|
||||||
|
<field name="report_readonly" invisible="1"/>
|
||||||
|
<field name="report_domain" invisible="1"/>
|
||||||
|
<field name="preliminary" invisible="1"/>
|
||||||
|
</group>
|
||||||
|
</form>
|
|
@ -56,6 +56,16 @@ class ResultsReportVersionDetail(metaclass=PoolMeta):
|
||||||
for sample in self.samples:
|
for sample in self.samples:
|
||||||
sample.diagnosis = content
|
sample.diagnosis = content
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_detail_copy(cls, detail):
|
||||||
|
detail_default = super(ResultsReportVersionDetail,
|
||||||
|
cls)._get_detail_copy(detail)
|
||||||
|
if detail.diagnostician:
|
||||||
|
detail_default['diagnostician'] = detail.diagnostician.id
|
||||||
|
if detail.diagnosis_template:
|
||||||
|
detail_default['diagnosis_template'] = detail.diagnosis_template.id
|
||||||
|
return detail_default
|
||||||
|
|
||||||
|
|
||||||
class ResultsReportVersionDetailSample(metaclass=PoolMeta):
|
class ResultsReportVersionDetailSample(metaclass=PoolMeta):
|
||||||
__name__ = 'lims.results_report.version.detail.sample'
|
__name__ = 'lims.results_report.version.detail.sample'
|
||||||
|
@ -78,6 +88,14 @@ class ResultsReportVersionDetailSample(metaclass=PoolMeta):
|
||||||
self.version_detail.diagnosis_template.diagnosis_states]
|
self.version_detail.diagnosis_template.diagnosis_states]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_sample_copy(cls, sample):
|
||||||
|
sample_default = super(ResultsReportVersionDetailSample,
|
||||||
|
cls)._get_sample_copy(sample)
|
||||||
|
sample_default['diagnosis'] = sample.diagnosis
|
||||||
|
sample_default['diagnosis_states'] = sample.diagnosis_states
|
||||||
|
return sample_default
|
||||||
|
|
||||||
|
|
||||||
class ResultReport(metaclass=PoolMeta):
|
class ResultReport(metaclass=PoolMeta):
|
||||||
__name__ = 'lims.result_report'
|
__name__ = 'lims.result_report'
|
||||||
|
|
|
@ -30,6 +30,18 @@ class ResultsReportVersionDetailSample(metaclass=PoolMeta):
|
||||||
domain=[('component', '=', Eval('component'))],
|
domain=[('component', '=', Eval('component'))],
|
||||||
depends=['component'])
|
depends=['component'])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_sample_copy(cls, sample):
|
||||||
|
sample_default = super(ResultsReportVersionDetailSample,
|
||||||
|
cls)._get_sample_copy(sample)
|
||||||
|
sample_default['precedent1'] = (sample.precedent1 and
|
||||||
|
sample.precedent1 or None)
|
||||||
|
sample_default['precedent2'] = (sample.precedent2 and
|
||||||
|
sample.precedent2 or None)
|
||||||
|
sample_default['precedent3'] = (sample.precedent3 and
|
||||||
|
sample.precedent3 or None)
|
||||||
|
return sample_default
|
||||||
|
|
||||||
|
|
||||||
class ResultsReportVersionDetailLine(metaclass=PoolMeta):
|
class ResultsReportVersionDetailLine(metaclass=PoolMeta):
|
||||||
__name__ = 'lims.results_report.version.detail.line'
|
__name__ = 'lims.results_report.version.detail.line'
|
||||||
|
@ -91,6 +103,7 @@ class ResultsReportVersionDetailLine(metaclass=PoolMeta):
|
||||||
res = round(float(result), decimals)
|
res = round(float(result), decimals)
|
||||||
if decimals == 0:
|
if decimals == 0:
|
||||||
res = int(res)
|
res = int(res)
|
||||||
|
res = str(res)
|
||||||
else:
|
else:
|
||||||
res = ''
|
res = ''
|
||||||
|
|
||||||
|
|
|
@ -1137,6 +1137,8 @@
|
||||||
|
|
||||||
{% endif %} <!-- END POLISAMPLE -->
|
{% endif %} <!-- END POLISAMPLE -->
|
||||||
|
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -29,6 +29,14 @@ class ResultsReportVersionDetail(metaclass=PoolMeta):
|
||||||
if 'required' in cls.resultrange_origin.states:
|
if 'required' in cls.resultrange_origin.states:
|
||||||
del cls.resultrange_origin.states['required']
|
del cls.resultrange_origin.states['required']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_detail_copy(cls, detail):
|
||||||
|
detail_default = super(ResultsReportVersionDetail,
|
||||||
|
cls)._get_detail_copy(detail)
|
||||||
|
if detail.template:
|
||||||
|
detail_default['template'] = detail.template.id
|
||||||
|
return detail_default
|
||||||
|
|
||||||
|
|
||||||
class ResultReport(metaclass=PoolMeta):
|
class ResultReport(metaclass=PoolMeta):
|
||||||
__name__ = 'lims.result_report'
|
__name__ = 'lims.result_report'
|
||||||
|
|
Loading…
Reference in New Issue