Esempio n. 1
0
def create_test_data(portal):
    """Populates with storage-like test data
    """
    if not CREATE_TEST_DATA:
        return
    logger.info("Creating test data ...")
    facilities = portal.senaite_storage
    if len(facilities.objectValues()) > 0:
        logger.info("There are facilities created already [SKIP]")
        return

    def get_random(min, max):
        if not CREATE_TEST_DATA_RANDOM:
            return min
        return int(round(random.uniform(min, max)))

    # Facilities
    for x in range(get_random(3, 8)):
        facility = api.create(
            facilities,
            "StorageFacility",
            title="Storage facility {:02d}".format(x + 1),
            Phone="123456789",
            EmailAddress="storage{:02d}@example.com".format(x + 1),
            PhysicalAddress={
                "address": "Av. Via Augusta 15 - 25",
                "city": "Sant Cugat del Valles",
                "zip": "08174",
                "state": "",
                "country": "Spain",
            })

        # Fridges
        for i in range(get_random(2, 5)):
            container = api.create(facility,
                                   "StorageContainer",
                                   title="Fridge {:02d}".format(i + 1),
                                   Rows=get_random(4, 8),
                                   Columns=get_random(4, 6))

            # Racks
            for j in range(get_random(4, container.get_capacity())):
                rack = api.create(container,
                                  "StorageContainer",
                                  title="Rack {:02d}".format(j + 1),
                                  Rows=get_random(3, 4),
                                  Columns=get_random(2, 3))

                # Boxes
                for k in range(get_random(2, rack.get_capacity())):
                    box = api.create(rack,
                                     "StorageSamplesContainer",
                                     title="Sample box {:02d}".format(k + 1),
                                     Rows=get_random(5, 10),
                                     Columns=get_random(5, 10))
Esempio n. 2
0
    def create_report(self, parent, pdf, html, uids, metadata):
        """Create a new report object

        NOTE: We limit the creation of reports to 1 to avoid conflict errors on
              simultaneous publication.

        :param parent: parent object where to create the report inside
        :returns: ARReport
        """

        parent_id = api.get_id(parent)
        logger.info("Create Report for {} ...".format(parent_id))

        # Manually update the view on the database to avoid conflict errors
        parent._p_jar.sync()

        # Create the report object
        report = api.create(parent,
                            "ARReport",
                            AnalysisRequest=api.get_uid(parent),
                            Pdf=pdf,
                            Html=html,
                            ContainedAnalysisRequests=uids,
                            Metadata=metadata)

        # Commit the changes
        transaction.commit()

        logger.info("Create Report for {} [DONE]".format(parent_id))

        return report
Esempio n. 3
0
 def create_attachment(self, container, attachment_file, **kw):
     """Create an Attachment object in the given container
     """
     filename = getattr(attachment_file, "filename", "Attachment")
     attachment = api.create(container, "Attachment", title=filename)
     attachment.edit(AttachmentFile=attachment_file, **kw)
     attachment.processForm()
     attachment.reindexObject()
     logger.info("Created new Attachment {} in {}".format(
         repr(attachment), repr(container)))
     return attachment
Esempio n. 4
0
def create_object(container, portal_type, **data):
    """Creates an object slug

    :returns: The new created content object
    :rtype: object
    """

    if "id" in data:
        # always omit the id as senaite LIMS generates a proper one
        id = data.pop("id")
        logger.warn("Passed in ID '{}' omitted! Senaite LIMS "
                    "generates a proper ID for you".format(id))

    try:
        # Is there any adapter registered to handle the creation of this type?
        adapter = queryAdapter(container, ICreate, name=portal_type)
        if adapter and adapter.is_creation_delegated():
            logger.info("Delegating 'create' operation of '{}' in '{}'".format(
                portal_type, api.get_path(container)))
            return adapter.create_object(**data)

        # Special case for ARs
        # => return immediately w/o update
        if portal_type == "AnalysisRequest":
            obj = create_analysisrequest(container, **data)
            # Omit values which are already set through the helper
            data = u.omit(data, "SampleType", "Analyses")
            # Set the container as the client, as the AR lives in it
            data["Client"] = container
            return obj
        # Standard content creation
        else:
            # we want just a minimun viable object and set the data later
            obj = api.create(container, portal_type)
            # obj = api.create(container, portal_type, **data)
    except Unauthorized:
        fail(401, "You are not allowed to create this content")

    # Update the object with the given data, but omit the id
    try:
        update_object_with_data(obj, data)
    except APIError:
        # Failure in creation process, delete the invalid object
        # NOTE: We bypass the permission checks
        container._delObject(obj.id)
        # reraise the error
        raise

    return obj
Esempio n. 5
0
def setup_antibiotic_classes(portal):
    """Setup default antibiotic classes if do not exist yet
    """
    logger.info("Setup default antibiotic classes ...")

    # Get the titles of the existing classes first
    folder = api.get_setup().get("antibiotic_classes")
    existing = map(api.get_title, folder.objectValues())

    # Create the antibiotic classes
    for ac in ANTIBIOTIC_CLASSES:
        if ac in existing:
            logger.warn("Antibiotic class {} already exists [SKIP]".format(ac))
            continue

        logger.info("Adding antibiotic class: {}".format(ac))
        api.create(folder, "AntibioticClass", title=ac)

    # Don't know why yet, but after adding the antibiotic classes, the folder
    # looses the title
    folder.title = "Antibiotic classes"
    folder.reindexObject()

    logger.info("Setup default antibiotic classes [DONE]")
Esempio n. 6
0
    def create_report(self, parent, pdf, html, uids, metadata, csv_text=None):
        """Create a new report object

        NOTE: We limit the creation of reports to 1 to avoid conflict errors on
              simultaneous publication.

        :param parent: parent object where to create the report inside
        :returns: ARReport
        """

        parent_id = api.get_id(parent)
        logger.info("Create Report for {} ...".format(parent_id))

        # Manually update the view on the database to avoid conflict errors
        parent._p_jar.sync()
        query = {
            'portal_type': 'ARReport',
            'path': {
                'query': api.get_path(parent),
                'depth': 1
            }
        }
        brains = api.search(query, 'portal_catalog')
        coa_num = '{}-COA-{}'.format(parent_id, len(brains) + 1)

        # Create the report object
        report = api.create(parent,
                            "ARReport",
                            AnalysisRequest=api.get_uid(parent),
                            Pdf=pdf,
                            Html=html,
                            CSV=csv_text,
                            ContainedAnalysisRequests=uids,
                            Metadata=metadata)
        fld = report.getField('Pdf')
        fld.get(report).setFilename(coa_num + ".pdf")
        fld.get(report).setContentType('application/pdf')
        fld = report.getField('CSV')
        fld.get(report).setFilename(coa_num + ".csv")
        fld.get(report).setContentType('text/csv')

        # Commit the changes
        transaction.commit()

        logger.info("Create Report for {} [DONE]".format(parent_id))

        return report
Esempio n. 7
0
def setup_antibiotics(portal):
    """Setup default antibiotics if do not exist yet
    """
    logger.info("Setup default antibiotics ...")

    # Get the titles of the existing antibiotics first
    folder = api.get_setup().get("antibiotics")
    existing = map(api.get_title, folder.objectValues())

    def get_antibiotic_class(name):
        query = {
            "portal_type": "AntibioticClass",
            "title": name,
        }
        brains = api.search(query)
        if len(brains) == 1:
            return api.get_object(brains[0])
        return None

    # Create the antibiotic classes
    for name, props in ANTIBIOTICS:
        if name in existing:
            logger.warn("Antibiotic {} already exists [SKIP]".format(name))
            continue

        logger.info("Adding antibiotic: {}".format(name))

        # Get the antibiotic class by name
        a_class_name = props.get("antibiotic_class")
        a_class = get_antibiotic_class(a_class_name)
        if not a_class:
            logger.error("Antibiotic class missing: '{}' [SKIP]".format(
                a_class_name))
            continue

        obj = api.create(folder, "Antibiotic", title=name)
        obj.antibiotic_class = api.get_uid(a_class)
        obj.abbreviation = props.get("abbreviation")
        obj.reindexObject()

    # After adding the antibiotic, the folder looses the title
    folder.title = "Antibiotics"
    folder.reindexObject()
    logger.info("Setup default antibiotics [DONE]")
Esempio n. 8
0
def create_object(container, portal_type, **data):
    """Creates an object slug

    :returns: The new created content object
    :rtype: object
    """

    if "id" in data:
        # always omit the id as Bika LIMS generates a proper one
        id = data.pop("id")
        logger.warn("Passed in ID '{}' omitted! Bika LIMS "
                    "generates a proper ID for you".format(id))

    try:
        # Special case for ARs
        # => return immediately w/o update
        if portal_type == "AnalysisRequest":
            obj = create_analysisrequest(container, **data)
            # Omit values which are already set through the helper
            data = u.omit(data, "SampleType", "Analyses")
            # Set the container as the client, as the AR lives in it
            data["Client"] = container
        # Standard content creation
        else:
            # we want just a minimun viable object and set the data later
            obj = api.create(container, portal_type)
            # obj = api.create(container, portal_type, **data)

    except Unauthorized:
        fail(401, "You are not allowed to create this content")

    # Update the object with the given data, but omit the id
    try:
        update_object_with_data(obj, data)  #start point
    except APIError:

        # Failure in creation process, delete the invalid object
        container.manage_delObjects(obj.id)
        # reraise the error
        raise

    return obj
Esempio n. 9
0
def create_object(container, portal_type, **data):
    """Creates an object slug

    :returns: The new created content object
    :rtype: object
    """

    if "id" in data:
        # always omit the id as Bika LIMS generates a proper one
        id = data.pop("id")
        logger.warn("Passed in ID '{}' omitted! Bika LIMS "
                    "generates a proper ID for you" .format(id))

    try:
        # Special case for ARs
        # => return immediately w/o update
        if portal_type == "AnalysisRequest":
            obj = create_analysisrequest(container, **data)
            # Omit values which are already set through the helper
            data = u.omit(data, "SampleType", "Analyses")
            # Set the container as the client, as the AR lives in it
            data["Client"] = container
        # Standard content creation
        else:
            # we want just a minimun viable object and set the data later
            obj = api.create(container, portal_type)
            # obj = api.create(container, portal_type, **data)

    except Unauthorized:
        fail(401, "You are not allowed to create this content")

    # Update the object with the given data, but omit the id
    try:
        update_object_with_data(obj, data)    #start point
    except APIError:

        # Failure in creation process, delete the invalid object
        container.manage_delObjects(obj.id)
        # reraise the error
        raise

    return obj
Esempio n. 10
0
def setup_baseline_data(portal):
    """Setups baseline data for testing purposes
    """
    setup = portal.bika_setup
    client = _api.create(portal.clients,
                         "Client",
                         Name="Happy Hills",
                         ClientID="HH")
    contact = _api.create(client,
                          "Contact",
                          Firstname="Rita",
                          Lastname="Mohale")
    sample_type = _api.create(setup.bika_sampletypes,
                              "SampleType",
                              title="Water",
                              Prefix="W")
    lab_contact = _api.create(setup.bika_labcontacts,
                              "LabContact",
                              Firstname="Lab",
                              Lastname="Manager")
    department = _api.create(setup.bika_departments,
                             "Department",
                             title="Chemistry",
                             Manager=lab_contact)
    category = _api.create(setup.bika_analysiscategories,
                           "AnalysisCategory",
                           title="Metals",
                           Department=department)
    Cu = _api.create(setup.bika_analysisservices,
                     "AnalysisService",
                     title="Copper",
                     Keyword="Cu",
                     Category=category.UID())
    Fe = _api.create(setup.bika_analysisservices,
                     "AnalysisService",
                     title="Iron",
                     Keyword="Fe",
                     Category=category.UID())
Esempio n. 11
0
    def action_add(self):
        """Form action to add a new attachment

        Code taken from bika.lims.content.addARAttachment.
        """
        form = self.request.form
        parent = api.get_parent(self.context)
        this_file = form.get('AttachmentFile_file', None)

        # nothing to do if the attachment file is missing
        if this_file is None:
            logger.warn(
                "AttachmentView.action_add_attachment: Attachment file is missing"
            )
            return

        # create attachment
        attachmentid = self.context.generateUniqueId('Attachment')
        attachment = api.create(parent, "Attachment", id=attachmentid)

        # update the attachment with the values from the form
        attachment.edit(
            AttachmentFile=this_file,
            AttachmentType=form.get('AttachmentType', ''),
            AttachmentKeys=form.get('AttachmentKeys', ''),
            ReportOption=form.get('ReportOption', 'a'),
        )

        # process and reindex
        attachment.processForm()
        attachment.reindexObject()

        # append the new UID to the end of the current order
        self.set_attachments_order(api.get_uid(attachment))

        # handle analysis attachment
        analysis_uid = form.get("Analysis", None)
        if analysis_uid:
            rc = api.get_tool("reference_catalog")
            analysis = rc.lookupObject(analysis_uid)
            others = analysis.getAttachment()
            attachments = []
            for other in others:
                attachments.append(other.UID())
            attachments.append(attachment.UID())
            analysis.setAttachment(attachments)

            if api.get_workflow_status_of(analysis) == 'attachment_due':
                api.do_transition_for(analysis, 'attach')
        else:
            others = self.context.getAttachment()
            attachments = []
            for other in others:
                attachments.append(other.UID())
            attachments.append(attachment.UID())

            self.context.setAttachment(attachments)

        if self.request['HTTP_REFERER'].endswith('manage_results'):
            self.request.response.redirect('{}/manage_results'.format(
                self.context.absolute_url()))
        else:
            self.request.response.redirect(self.context.absolute_url())