Esempio n. 1
0
 widget=RecordsWidget(
     label=_("Formatting Configuration"),
     allowDelete=True,
     description=_(
         " <p>The Bika LIMS ID Server provides unique sequential IDs "
         "for objects such as Samples and Worksheets etc, based on a "
         "format specified for each content type.</p>"
         "<p>The format is constructed similarly to the Python format"
         " syntax, using predefined variables per content type, and"
         " advancing the IDs through a sequence number, 'seq' and its"
         " padding as a number of digits, e.g. '03d' for a sequence of"
         " IDs from 001 to 999.</p>"
         "<p>Alphanumeric prefixes for IDs are included as is in the"
         " formats, e.g. WS for Worksheet in WS-{seq:03d} produces"
         " sequential Worksheet IDs: WS-001, WS-002, WS-003 etc.</p>"
         "<p>Variables that can be used include:"
         "<table>"
         "<tr>"
         "<th style='width:150px'>Content Type</th><th>Variables</th>"
         "</tr>"
         "<tr><td>Client</td><td>{client}</td></tr>"
         "<tr><td>Year</td><td>{year}</td></tr>"
         "<tr><td>Sample ID</td><td>{sampleId}</td></tr>"
         "<tr><td>Sample Type</td><td>{sampleType}</td></tr>"
         "<tr><td>Sampling Date</td><td>{samplingDate}</td></tr>"
         "<tr><td>Date Sampled</td><td>{dateSampled}</td></tr>"
         "</table>"
         "</p>"
         "<p>Configuration Settings:"
         "<ul>"
         "<li>format:"
         "<ul><li>a python format string constructed from predefined"
         " variables like sampleId, client, sampleType.</li>"
         "<li>special variable 'seq' must be positioned last in the"
         "format string</li></ul></li>"
         "<li>sequence type: [generated|counter]</li>"
         "<li>context: if type counter, provides context the counting"
         " function</li>"
         "<li>counter type: [backreference|contained]</li>"
         "<li>counter reference: a parameter to the counting"
         " function</li>"
         "<li>prefix: default prefix if none provided in format"
         " string</li>"
         "<li>split length: the number of parts to be included in the"
         " prefix</li>"
         "</ul></p>"))),
Esempio n. 2
0
Calculation = HistoryAwareReferenceField('Calculation',
                                         allowed_types=('Calculation', ),
                                         relationship='AnalysisCalculation',
                                         referenceClass=HoldingReference)

# InterimFields are defined in Calculations, Services, and Analyses.
# In Analysis Services, the default values are taken from Calculation.
# In Analyses, the default values are taken from the Analysis Service.
# When instrument results are imported, the values in analysis are overridden
# before the calculation is performed.
InterimFields = InterimFieldsField(
    'InterimFields',
    schemata='Method',
    widget=RecordsWidget(
        label=_("Calculation Interim Fields"),
        description=_(
            "Values can be entered here which will override the defaults "
            "specified in the Calculation Interim Fields."),
    ))

schema = schema.copy() + Schema((
    AnalysisService,
    Analyst,
    Attachment,
    DetectionLimitOperand,
    # NumberOfRequiredVerifications overrides AbstractBaseClass
    NumberOfRequiredVerifications,
    Result,
    ResultCaptureDate,
    RetestOf,
    Uncertainty,
    Calculation,
Esempio n. 3
0
    ),

    #TODO: To be removed?
    RecordsField(
        'DataInterfaceOptions',
        type='interfaceoptions',
        subfields=('Key', 'Value'),
        required_subfields=('Key', 'Value'),
        subfield_labels={
            'OptionValue': _('Key'),
            'OptionText': _('Value'),
        },
        widget=RecordsWidget(
            label=_("Data Interface Options"),
            description=
            _("Use this field to pass arbitrary parameters to the export/import modules."
              ),
            visible=False,
        ),
    ),

    # References to all analyses performed with this instrument.
    # Includes regular analyses, QC analyes and Calibration tests.
    ReferenceField(
        'Analyses',
        required=0,
        multiValued=1,
        allowed_types=('ReferenceAnalysis', 'DuplicateAnalysis', 'Analysis'),
        relationship='InstrumentAnalyses',
        widget=ReferenceWidget(visible=False, ),
    ),
Esempio n. 4
0
     required_subfields=('intercept_min', 'intercept_max', 'errorvalue'),
     subfield_sizes={
         'intercept_min': 10,
         'intercept_max': 10,
         'errorvalue': 10,
     },
     subfield_labels={
         'intercept_min': _('Range min'),
         'intercept_max': _('Range max'),
         'errorvalue': _('Uncertainty value'),
     },
     widget=RecordsWidget(
         label=_("Uncertainty"),
         description=
         _("Specify the uncertainty value for a given range, e.g. for results "
           "in a range with minimum of 0 and maximum of 10, the uncertainty "
           "value is 0.5 - a result of 6.67 will be reported as 6.67 +- 0.5. "
           "Please ensure successive ranges are continuous, e.g. 0.00 - 10.00 "
           "is followed by 10.01 - 20.00, 20.01 - 30 .00 etc."),
     ),
 ),
 RecordsField(
     'ResultOptions',
     schemata=PMF("Result Options"),
     type='resultsoptions',
     subfields=('ResultValue', 'ResultText'),
     required_subfields=('ResultValue', 'ResultText'),
     subfield_labels={
         'ResultValue': _('Result Value'),
         'ResultText': _('Display Value'),
     },
Esempio n. 5
0
class BikaSetupSchemaExtender(object):
    adapts(IBikaSetup)
    implements(ISchemaExtender)

    fields = [
        ExtFixedPointField(
            'LevyAmount',
            schemata='Accounting',
            default='0.00',
            widget=DecimalWidget(
                label=_("Levy Amount"),
                description=
                _("The levy percentage the university or parent organisation raises on all invoiced amounts"
                  ),
            )),
        ExtRecordsField(
            'StoragePricing',
            schemata='Storage',
            subfields=('storage_type', 'price', 'storage_type_uid'),
            subfield_hidden={'storage_type_uid': True},
            required_subfields=('storage_type', 'price', 'storage_type_uid'),
            subfield_sizes={
                'storage_type': 50,
                'price': 5
            },
            subfield_labels={
                'storage_type': _('Storage Type'),
                'price': _('Price')
            },
            widget=RecordsWidget(
                label=_("Storage Pricing"),
                description=_(
                    "Set Sample storage pricing depending on storage type."),
                allowDelete=False,
                combogrid_options={
                    'storage_type': {
                        'colModel': [{
                            'columnName': 'storage_type',
                            'width': '30',
                            'label': _('Title')
                        }, {
                            'columnName': 'Description',
                            'width': '70',
                            'label': _('Description')
                        }, {
                            'columnName': 'storage_type_uid',
                            'hidden': True
                        }],
                        'url':
                        'getstoragetypes',
                        'showOn':
                        True,
                        'width':
                        '550px'
                    },
                },
            )),
        ExtBooleanField(
            'ShowPartitions',
            schemata="Analyses",
            default=False,
            widget=BooleanWidget(
                label=_("Display individual sample partitions "),
                description=_(
                    "Turn this on if you want to work with sample partitions")
            ),
        ),
        ExtBooleanField(
            'StoreKitBiospecimens',
            schemata="Storage",
            default=True,
            widget=BooleanWidget(
                label=_("Store biospecimens when kit creation"),
                description=
                _("Turn this off if you want create kits without storing its biospecimens in managed storages"
                  )),
        ),
    ]

    def __init__(self, context):
        self.context = context

    def getFields(self):
        return self.fields
Esempio n. 6
0
        subfield_readonly={'module': False, 'function': False},
        subfield_types={'module': 'string', 'function': 'string'},
        default=[
            {'module': 'math', 'function': 'ceil'},
            {'module': 'math', 'function': 'floor'},
        ],
        subfield_validators={
            'module': 'importvalidator',
        },
        widget=RecordsWidget(
            label=_("Additional Python Libraries"),
            description=_(
                "If your formula needs a special function from an external "
                "Python library, you can import it here. E.g. if you want to "
                "use the 'floor' function from the Python 'math' module, "
                "you add 'math' to the Module field and 'floor' to the "
                "function field. The equivalent in Python would be 'from math "
                "import floor'. In your calculation you could use then "
                "'floor([Ca] + [Mg])'. "
            ),
            allowDelete=True,
        ),
    ),

    TextField(
        'Formula',
        validators=('formulavalidator',),
        default_content_type='text/plain',
        allowable_content_types=('text/plain',),
        widget=TextAreaWidget(
            label=_("Calculation Formula"),
Esempio n. 7
0
     'ResultFilesFolder',
     subfields=('InterfaceName', 'Folder'),
     subfield_labels={
         'InterfaceName': _('Interface Code'),
         'Folder': _('Folder that results will be saved')
     },
     subfield_readonly={
         'InterfaceName': True,
         'Folder': False
     },
     widget=RecordsWidget(
         label=_("Result files folders"),
         description=_("For each interface of this instrument, \
                   you can define a folder where \
                   the system should look for the results files while \
                   automatically importing results. Having a folder \
                   for each Instrument and inside that folder creating \
                   different folders for each of its Interfaces \
                   can be a good approach. You can use Interface codes \
                   to be sure that folder names are unique."),
         visible=True,
     ),
 ),
 RecordsField(
     'DataInterfaceOptions',
     type='interfaceoptions',
     subfields=('Key', 'Value'),
     required_subfields=('Key', 'Value'),
     subfield_labels={
         'OptionValue': _('Key'),
         'OptionText': _('Value'),
     },
Esempio n. 8
0
             'prefix': 'WS',
             'padding': '4'
         },
         {
             'portal_type': 'Pricelist',
             'prefix': 'PL',
             'padding': '4'
         },
     ],
     #        fixedSize=8,
     widget=RecordsWidget(
         label=_("Prefixes"),
         description=
         _("Define the prefixes for the unique sequential IDs the system issues for "
           "objects. In the 'Padding' field, indicate with how many leading zeros the "
           "numbers must be padded. E.g. a prefix of WS for worksheets with padding of "
           "4, will see them numbered from WS-0001 to WS-9999. NB: Note that samples "
           "and analysis requests are prefixed with sample type abbreviations and are "
           "not configured in this table - their padding can be set in the specified "
           "fields below"),
         allowDelete=False,
     )),
 BooleanField(
     'YearInPrefix',
     schemata="ID Server",
     default=False,
     widget=BooleanWidget(
         label=_("Include year in ID prefix"),
         description=_("Adds a two-digit year after the ID prefix")),
 ),
 IntegerField(
     'SampleIDPadding',
Esempio n. 9
0
             'portal_type': 'Project',
             'prefix': 'SU',
             'padding': '4',
             'separator': '-',
             'sequence_start': '0'
         },
     ],
     #        fixedSize=8,
     widget=RecordsWidget(
         label=_("Prefixes"),
         description=
         _("Define the prefixes for the unique sequential IDs the system issues for "
           "objects. In the 'Padding' field, indicate with how many leading zeros the "
           "numbers must be padded. E.g. a prefix of WS for worksheets with padding of "
           "4, will see them numbered from WS-0001 to WS-9999. Sequence Start "
           "indicates the number from which the next ID should start. This is "
           "set only if it is greater than existing id numbers. Note that the "
           "gap created by jumping IDs cannot be refilled. NB: Note that samples "
           "and analysis requests are prefixed with sample type abbreviations and are "
           "not configured in this table - their padding can be set in the specified "
           "fields below"),
         allowDelete=False,
     )),
 BooleanField(
     'YearInPrefix',
     schemata="ID Server",
     default=False,
     widget=BooleanWidget(
         label=_("Include year in ID prefix"),
         description=_("Adds a two-digit year after the ID prefix")),
 ),
Esempio n. 10
0
schema = BikaSchema.copy() + Schema((RecordsField(
    'AetiologicAgentSubtypes',
    type='aetiologicagentsubtypes',
    subfields=('Subtype', 'SubtypeRemarks'),
    subfield_labels={
        'Subtype': _('Subtype'),
        'SubtypeRemarks': _('Remarks')
    },
    subfield_sizes={
        'Subtype': 10,
        'SubtypeRemarks': 25
    },
    widget=RecordsWidget(
        label='Subtypes',
        description=_("A list of aetiologic agent subtypes."),
        visible=True,
    ),
), ))
schema['description'].widget.visible = True
schema['description'].schemata = 'default'


class AetiologicAgent(BaseContent):
    security = ClassSecurityInfo()
    displayContentsTab = False
    schema = schema

    _at_rename_after_creation = True

    def _renameAfterCreation(self, check_auto_id=False):
Esempio n. 11
0
    def process_form(self,
                     instance,
                     field,
                     form,
                     empty_marker=None,
                     emptyReturnsMarker=False):
        """
        Gets the values from the ReflexRule section and returns them in the
        correct way to be saved.
        So the function will return a list of dictionaries:

        [...,{
            'conditions':[{
                'range1': 'X', 'range0': 'X',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                }, {...}],
            'trigger': 'xxx',
            'actions':[{'action':'<action_name>', 'act_row_idx':'X',
                            'otherWS':'to_another', 'analyst': '<analyst_id>',
                            'an_result_id':'rep-1',...},
                    ]
        },
        {
            'conditions':[{
                'range1': 'X', 'range0': 'X',
                'trigger': 'xxx',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                },
                {
                'discreteresult': 'X',
                'trigger': 'xxx',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                }, {...}],
            'trigger': 'xxx',
            'actions':[{'action':'<action_name>', 'act_row_idx':'X',
                        'otherWS':to_another, 'analyst': '<analyst_id>',
                        'an_result_id':'rep-1',...},
                      {'action':'<action_name>', 'act_row_idx':'X',
                        'otherWS':to_another, 'analyst': '<analyst_id>',
                        'an_result_id':'rep-2'...},
                ]
        }, ...]
        """
        if field.getName() != 'ReflexRules':
            return RecordsWidget.process_form(self, instance, field, form,
                                              empty_marker, emptyReturnsMarker)
        raw_data = RecordsWidget.process_form(self, instance, field, form,
                                              empty_marker, emptyReturnsMarker)
        # 'value' is a list which will be saved
        value = []
        rulenum = 0
        # Building the actions and conditions list
        for raw_set in raw_data[0]:
            d = self._format_conditions_and_actions(raw_set)
            # Adding the rule number
            d['rulenumber'] = str(rulenum)
            # Filling the dict with the mother service UID
            d['mother_service_uid'] = raw_data[0][0].get(
                'analysisservice-0', '')
            value.append(d)
            rulenum += 1

        return value, {}
Esempio n. 12
0
     subfield_sizes={
         'Identifier': 15,
         'Identifier Type': 25
     },
     widget=RecordsWidget(
         label=_('Additional identifiers'),
         description=_('Patient additional identifiers'),
         combogrid_options={
             'IdentifierType': {
                 'colModel': [
                     {
                         'columnName': 'IdentifierType',
                         'width': '30',
                         'label': _('Title')
                     },
                     {
                         'columnName': 'Description',
                         'width': '70',
                         'label': _('Description')
                     }
                 ],
                 'url': 'getidentifiertypes',
                 'showOn': True,
                 'width': '550px'
             },
         },
     ),
 ),
 ComputedField(
     'PatientIdentifiersStr',
     expression="context.getPatientIdentifiersStr()",
Esempio n. 13
0
    def process_form(self, instance, field, form, empty_marker=None,
                     emptyReturnsMarker=False):
        """
        Gets the values from the ReflexRule section and returns them in the
        correct way to be saved.
        So the function will return a list of dictionaries:

        [...,{
            'conditions':[{
                'range1': 'X', 'range0': 'X',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                }, {...}],
            'trigger': 'xxx',
            'actions':[{'action':'<action_name>', 'act_row_idx':'X',
                            'otherWS':'to_another', 'analyst': '<analyst_id>',
                            'an_result_id':'rep-1',...},
                    ]
        },
        {
            'conditions':[{
                'range1': 'X', 'range0': 'X',
                'trigger': 'xxx',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                },
                {
                'discreteresult': 'X',
                'trigger': 'xxx',
                'cond_row_idx':'X'
                'and_or': 'and',
                'analysisservice': '<as_uid>',
                }, {...}],
            'trigger': 'xxx',
            'actions':[{'action':'<action_name>', 'act_row_idx':'X',
                        'otherWS':to_another, 'analyst': '<analyst_id>',
                        'an_result_id':'rep-1',...},
                      {'action':'<action_name>', 'act_row_idx':'X',
                        'otherWS':to_another, 'analyst': '<analyst_id>',
                        'an_result_id':'rep-2'...},
                ]
        }, ...]
        """
        if field.getName() != 'ReflexRules':
            return RecordsWidget.process_form(
                self, instance, field, form, empty_marker, emptyReturnsMarker)
        raw_data = RecordsWidget.process_form(
            self, instance, field, form, empty_marker, emptyReturnsMarker)
        # 'value' is a list which will be saved
        value = []
        rulenum = 0
        # Building the actions and conditions list
        for raw_set in raw_data[0]:
            d = self._format_conditions_and_actions(raw_set)
            # Adding the rule number
            d['rulenumber'] = str(rulenum)
            # Filling the dict with the mother service UID
            d['mother_service_uid'] = raw_data[0][0].get(
                'analysisservice-0', '')
            value.append(d)
            rulenum += 1

        return value, {}
Esempio n. 14
0
    },
    widget=RecordsWidget(
        label=_('Identifiers for this object'),
        description=_(
            "Select identifiers by which this object can be referenced."),
        visible={
            'view': 'visible',
            'edit': 'visible'
        },
        combogrid_options={
            'IdentifierType': {
                'colModel': [{
                    'columnName': 'identifiertype_uid',
                    'hidden': True
                }, {
                    'columnName': 'IdentifierType',
                    'width': '30',
                    'label': _('Identifier Type')
                }, {
                    'columnName': 'Description',
                    'width': '70',
                    'label': _('Description')
                }],
                'url':
                'getidentifiertypes',
                'showOn':
                True,
                'width':
                '500px',
            }
        }))