Esempio n. 1
0
def update_sample(content, record):
    """
    Custom code for updating a sample because of special requirements for storage location and sample type.
    :param content:  The sample object that has to be modified
    :param record:  This object has a dictionary, items, that has the values that are to be changed.
    :return: The updated sample object
    """
    # set and unset the storage locations
    for k, v in record.items():
        if k == 'StorageLocation':
            storage_location_results = search(portal_type='StoragePosition',
                                              Title=v)
            if not storage_location_results:
                storage_location_results = search(
                    portal_type='StoragePosition', uid=v)
            storage_location = storage_location_results and get_object(
                storage_location_results[0]) or None

            wf_tool = get_tool("portal_workflow")
            location_status = wf_tool.getStatusOf(
                'bika_storageposition_workflow', storage_location)
            if location_status and location_status.get("review_state",
                                                       None) == "available":

                current_location = content.getStorageLocation()
                if current_location:
                    doActionFor(current_location, 'liberate')

                # assign the sample to the storage location
                content.setStorageLocation(storage_location)
                sample_status = wf_tool.getStatusOf('bika_sample_workflow',
                                                    content)

                if sample_status and sample_status.get(
                        "review_state", None) == "sample_received":
                    doActionFor(storage_location, 'occupy')
                else:
                    doActionFor(storage_location, 'reserve')

        if k == 'SampleType':
            sample_type_results = search(portal_type="SampleType", title=v)
            if not sample_type_results:
                sample_type_results = search(portal_type="SampleType", uid=v)

            sample_type = sample_type_results and get_object(
                sample_type_results[0]) or None

            if isinstance(sample_type, tuple):
                sample_type = sample_type[0]
            content.setSampleType(sample_type)

    return content
Esempio n. 2
0
def create_project(container, portal_type, **data):
    """
        Create a project via API
    """

    container = get_object(container)
    title = data.get("title", "")
    if not title:
        fail(404, "Title is required.")

    obj = bika_create_object(container, portal_type, **data)

    st_titles = data.get("SampleType", "")

    st_uids = []
    if st_titles and type(st_titles) is list:
        for st_title in st_titles:
            brains = search(portal_type="SampleType", title=st_title)
            if brains:
                st_uids.append(brains[0].UID)
        if st_uids:
            obj.setSampleType(st_uids)

    return obj
Esempio n. 3
0
def create_sample(container, **data):
    """
    create a sample from here that doesnt go via api create
    :param container:
    :param data:
    :return: Sample object
    """
    container = get_object(container)
    request = req.get_request()
    # we need to resolve the SampleType to a full object
    sample_type = data.get("SampleType", None)
    if sample_type is None:
        fail(400, "Please provide a SampleType")

    # TODO We should handle the same values as in the DataManager for this field
    #      (UID, path, objects, dictionaries ...)
    sample_type_results = search(portal_type="SampleType", title=sample_type)
    if not sample_type_results:
        sample_type_results = search(portal_type="SampleType", uid=sample_type)

    # StorageLocation
    storage_location = data.get("StorageLocation", None)
    if storage_location is None:
        fail(400, "Please provide a StorageLocation")

    linked_sample_list = search(portal_type="Sample",
                                title=data.get('LinkedSample', ''))
    linked_sample = linked_sample_list and linked_sample_list[0].getObject(
    ) or None

    try:
        volume = str(data.get('Volume'))
        float_volume = float(volume)
        if not float_volume:
            fail(400, "Please provide a correct Volume")
    except:
        raise

    # TODO We should handle the same values as in the DataManager for this field
    #      (UID, path, objects, dictionaries ...)
    storage_location_results = search(portal_type='StoragePosition',
                                      Title=storage_location)
    if not storage_location_results:
        storage_location_results = search(portal_type='StoragePosition',
                                          uid=storage_location)

    # set the values and call the create function
    values = {
        "title":
        data.get('title', ''),
        "description":
        data.get("description", ""),
        "Project":
        container,  #because the container is in fact the project this sample belongs to.
        "AllowSharing":
        data.get('AllowSharing', 0),
        "StorageLocation":
        storage_location_results and get_object(storage_location_results[0])
        or None,
        "SampleType":
        sample_type_results and get_object(sample_type_results[0]) or None,
        "SubjectID":
        data.get("SubjectID", ""),
        "Barcode":
        data.get("Barcode", ""),
        "Volume":
        volume,
        "Unit":
        data.get("Unit", ""),
        "LinkedSample":
        linked_sample,
        "DateCreated":
        data.get("DateCreated", ""),
    }

    api_source = data.get('APISource', None)
    if api_source:
        values['APISource'] = api_source

    return create_smp(container, request, values)
Esempio n. 4
0
def create_storage(container, portal_type, **data):
    """
        Create a storage unit and (un-)managed storage via API
    """
    def set_inputs_into_schema(instance, temperature, department, unit_type):
        # Set field values across each object if possible
        schema = instance.Schema()
        if temperature and 'Temperature' in schema:
            instance.Schema()['Temperature'].set(instance, temperature)
        if department and 'Department' in schema:
            instance.Schema()['Department'].set(instance, department)
        if unit_type and 'UnitType' in schema:
            instance.Schema()['UnitType'].set(instance, unit_type)

    def set_storage_types(instance, storage_interfaces):
        schema = instance.Schema()
        if storage_interfaces and 'StorageTypes' in schema:
            instance.Schema()['StorageTypes'].set(instance, storage_interfaces)

        for storage_interface in storage_interfaces:
            inter = resolve(storage_interface)
            alsoProvides(instance, inter)

    container = get_object(container)

    # variables for storage unit
    department_title = data.get("department", "")
    temperature = data.get("temperature", "")
    unit_type = data.get("unit_type", "")

    department = None
    if container.portal_type == "StorageUnit":
        department = container.getDepartment()
        temperature = container.getTemperature()
    else:
        brains = search(portal_type="Department", title=department_title)
        if not brains:
            department = brains[0].getObject()

    # variables for managed storage
    if portal_type == "ManagedStorage":
        number_positions = data.get("number_positions", "")
        x_axis = data.get("x_axis", "")
        y_axis = data.get("y_axis", "")
        try:
            x_axis = x_axis and int(x_axis) or ''
            y_axis = y_axis and int(y_axis) or ''
            number_positions = number_positions and int(number_positions) or ''
        except ValueError:
            fail(401, "Number positions, X axis and Y axis must be integers.")

        if not number_positions or not x_axis or not y_axis:
            fail(
                400,
                "Number positions, X axis and Y axis are required to create storage positions."
            )

    # common variables
    prefix = data.get("prefix", "")
    leading_zeros = data.get("leading_zeros", "")
    if not prefix or not leading_zeros:
        fail(
            400,
            "Prefix and leading_zeros are required to construct storage unit title and Id."
        )

    number_items = data.get("number_items", "")
    try:
        number_items = number_items and int(number_items) or 1
    except ValueError:
        fail(401, "Number items must be integer.")

    seq_start = data.get("seq_start", "")
    try:
        seq_start = seq_start and int(seq_start) or 1
    except ValueError:
        fail(401, "Id sequence start must be integer.")

    sequence = range(seq_start, seq_start + number_items)

    units = []
    for x in sequence:
        id_obj = prefix + '-' + str(x).zfill(len(leading_zeros) + 1)
        title_obj = prefix + ' ' + str(x).zfill(len(leading_zeros) + 1)

        instance = api.content.create(container=container,
                                      type=portal_type,
                                      id=id_obj,
                                      title=title_obj)

        if instance.portal_type == "StorageUnit":
            set_inputs_into_schema(instance, temperature, department,
                                   unit_type)
        elif instance.portal_type == "UnmanagedStorage":
            set_storage_types(instance,
                              ["baobab.lims.interfaces.IStockItemStorage"])
        elif instance.portal_type == "ManagedStorage":
            instance.setXAxis(x_axis)
            instance.setYAxis(y_axis)
            set_storage_types(
                instance, ["baobab.lims.interfaces.ISampleStorageLocation"])
            positions = storage_positions(instance, number_positions)
            for position in positions:
                set_storage_types(
                    position,
                    ["baobab.lims.interfaces.ISampleStorageLocation"])
                position.reindexObject()

        instance.reindexObject()

        units.append(instance)

    return units
Esempio n. 5
0
    def set(self, instance, value, **kw):  # noqa
        """Set the value of the refernce field
        """
        ref = []

        # The value is an UID
        if api.is_uid(value):
            ref.append(api.get_object_by_uid(value))

        # The value is already an object
        if api.is_at_content(value):
            ref.append(value)

        # The value is a dictionary
        # -> handle it like a catalog query
        if u.is_dict(value):
            results = api.search(portal_type=self.allowed_types, **value)
            ref = map(api.get_object, results)

        # The value is a list
        if u.is_list(value):
            for item in value:
                # uid
                if api.is_uid(item):
                    ref.append(api.get_object_by_uid(item))
                    continue

                # object
                if api.is_at_content(item):
                    ref.append(api.get_object(item))
                    continue

                # path
                if api.is_path(item):
                    ref.append(api.get_object_by_path(item))
                    continue

                # dict (catalog query)
                if u.is_dict(item):
                    results = api.search(portal_type=self.allowed_types, **item)
                    objs = map(api.get_object, results)
                    ref.extend(objs)
                    continue

                # Plain string
                # -> do a catalog query for title
                if isinstance(item, basestring):
                    results = api.search(portal_type=self.allowed_types, title=item)
                    objs = map(api.get_object, results)
                    ref.extend(objs)
                    continue

        # The value is a physical path
        if api.is_path(value):
            ref.append(api.get_object_by_path(value))

        # Handle non multi valued fields
        if not self.multi_valued and len(ref) > 1:
            raise ValueError("Multiple values given for single valued field {}"
                             .format(self.field))

        return self._set(instance, ref, **kw)
Esempio n. 6
0
    def set(self, instance, value, **kw):  # noqa
        """Set the value of the refernce field
        """
        ref = []

        # The value is an UID
        if api.is_uid(value):
            ref.append(api.get_object_by_uid(value))

        # The value is already an object
        if api.is_at_content(value):
            ref.append(value)

        # The value is a dictionary
        # -> handle it like a catalog query
        if u.is_dict(value):
            results = api.search(portal_type=self.allowed_types, **value)
            ref = map(api.get_object, results)

        # The value is a list
        if u.is_list(value):
            for item in value:
                # uid
                if api.is_uid(item):
                    ref.append(api.get_object_by_uid(item))
                    continue

                # object
                if api.is_at_content(item):
                    ref.append(api.get_object(item))
                    continue

                # path
                if api.is_path(item):
                    ref.append(api.get_object_by_path(item))
                    continue

                # dict (catalog query)
                if u.is_dict(item):
                    results = api.search(portal_type=self.allowed_types,
                                         **item)
                    objs = map(api.get_object, results)
                    ref.extend(objs)
                    continue

                # Plain string
                # -> do a catalog query for title
                if isinstance(item, basestring):
                    results = api.search(portal_type=self.allowed_types,
                                         title=item)
                    objs = map(api.get_object, results)
                    ref.extend(objs)
                    continue

        # The value is a physical path
        if api.is_path(value):
            ref.append(api.get_object_by_path(value))

        # Handle non multi valued fields
        if not self.multi_valued and len(ref) > 1:
            raise ValueError(
                "Multiple values given for single valued field {}".format(
                    self.field))

        return self._set(instance, ref, **kw)