kalenislims/lims_instrument_custom_set/custom_set_xls.py
2020-08-06 18:36:35 -03:00

145 lines
5.2 KiB
Python

# -*- coding: utf-8 -*-
# This file is part of lims_instrument_custom_set module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
import io
import xlrd
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.modules.lims.formula_parser import FormulaParser
IGNORE_SHEET = '###'
ANALYSIS_CODE = 'Analysis Code'
DATA_HEADER = 'Data Header'
FORMULA = 'Formula'
def getControllerName():
if Transaction().language in ('es', 'es_419'):
return 'Planilla personalizada - XLS'
else:
return 'Custom Set - XLS'
def parse(self, infile):
LabWorkYear = Pool().get('lims.lab.workyear')
filedata = io.StringIO(infile)
workbook = xlrd.open_workbook(file_contents=filedata.getvalue())
worksheets = workbook.sheet_names()
for worksheet_name in worksheets:
worksheet = workbook.sheet_by_name(worksheet_name)
if worksheet.cell_value(0, 0) == IGNORE_SHEET:
continue
self.analysis_code = None
self.formula = None
self.header = []
num_rows = worksheet.nrows - 1
curr_row = -1
header_found = False
while curr_row < num_rows:
curr_row += 1
row = worksheet.row(curr_row)
if not self.analysis_code:
self.getAnalysisCode(row)
if not self.formula:
self.getFormula(row)
if not self.header:
curr_row += self.getDataHeader(worksheet, curr_row)
if self.analysis_code and self.formula and self.header:
row = [cell for cell in row
if cell.ctype != xlrd.XL_CELL_EMPTY]
row = row[:len(self.header)]
if header_found is False:
row = [cell.value for cell in row]
if row == self.header:
header_found = True
continue
# Start reading data:
# they must be numbers and as many as header elements
for cell in row:
if cell.ctype != xlrd.XL_CELL_NUMBER:
header_found = False
continue
row = [cell.value for cell in row]
if len(row) < len(self.header):
header_found = False
continue
workyear = LabWorkYear.search(
['code', '=', str(int(row[1]))
])
padding = None
if workyear and workyear[0] and workyear[0].sample_sequence:
padding = workyear[0].sample_sequence.padding
if padding:
sample = '%%0%sd' % padding % int(row[0])
fraction = str(int(row[1])) + '/' + sample + \
'-' + str(int(row[2]))
repetition = int(row[3])
values = {}
remaining_header = self.header[4:]
i = 4
for h in remaining_header:
# remove whitespaces and dots
h = ''.join(h.split())
h = ''.join(h.split('.'))
values[h] = row[i]
i += 1
formulaParser = FormulaParser(self.formula, values)
values['result'] = formulaParser.getValue()
values['row_number'] = curr_row + 1
if fraction in self.rawresults:
if self.analysis_code in self.rawresults[fraction]:
self.rawresults[fraction][self.analysis_code][
repetition] = values
else:
self.rawresults[fraction][self.analysis_code] = {
repetition: values,
}
else:
self.rawresults[fraction] = {
self.analysis_code: {
repetition: values,
},
}
def getAnalysisCode(self, row):
found = False
for cell in row:
if found and cell.ctype == xlrd.XL_CELL_TEXT:
self.analysis_code = cell.value
return
if cell.value == ANALYSIS_CODE:
found = True
def getDataHeader(self, worksheet, curr_row):
row = worksheet.row(curr_row)
for cell in row:
if cell.value == DATA_HEADER:
curr_row += 1
if curr_row < (worksheet.nrows - 1):
# Look up in the next row
next_row = worksheet.row(curr_row)
for c in next_row:
if c.ctype == xlrd.XL_CELL_TEXT:
self.header.append(c.value)
return 1
return 0
def getFormula(self, row):
found = False
for cell in row:
if found and cell.ctype == xlrd.XL_CELL_TEXT:
# remove whitespaces and dots
value = ''.join(cell.value.split())
self.formula = ''.join(value.split('.'))
return
if cell.value == FORMULA:
found = True