Ejemplo n.º 1
0
    def __call__(self, value, *args, **kwargs):
        field = kwargs['field']
        fieldname = field.getName()
        instance = kwargs['instance']
        translate = getToolByName(instance, 'translation_service').translate

        # return directly if nothing changed
        if value == field.get(instance):
            return True

        # We want to use the catalog to speed things up, as using `objectValues`
        # is very expensive if the parent object contains many items
        parent_objects = []

        # 1. Get the right catalog for this object
        catalogs = api.get_catalogs_for(instance)
        catalog = catalogs[0]

        # 2. Check if the field accessor is indexed
        field_index = None
        accessor = field.getAccessor(instance)
        if accessor:
            field_index = accessor.__name__

        # 3. Check if the field index is in the indexes
        # Field is indexed, use the catalog instead of objectValues
        parent_path = api.get_parent_path(instance)
        portal_type = instance.portal_type
        catalog_query = {"portal_type": portal_type,
                            "path": {"query": parent_path, "depth": 1}}

        if field_index and field_index in catalog.indexes():
            # We use the field index to reduce the results list
            catalog_query[field_index] = value
            parent_objects = map(api.get_object, catalog(catalog_query))
        elif fieldname in catalog.indexes():
            # We use the fieldname as index to reduce the results list
            catalog_query[fieldname] = value
            parent_objects = map(api.get_object, catalog(catalog_query))
        else:
            # fall back to the objectValues :(
            parent_object = api.get_parent(instance)
            parent_objects = parent_object.objectValues()

        for item in parent_objects:
            if hasattr(item, 'UID') and item.UID() != instance.UID() and \
               fieldname in item.Schema() and \
               str(item.Schema()[fieldname].get(item)) == str(value):
                # We have to compare them as strings because
                # even if a number (as an  id) is saved inside
                # a string widget and string field, it will be
                # returned as an int. I don't know if it is
                # caused because is called with
                # <item.Schema()[fieldname].get(item)>,
                # but it happens...
                msg = _("Validation failed: '${value}' is not unique",
                        mapping={'value': safe_unicode(value)})
                return to_utf8(translate(msg))
        return True
Ejemplo n.º 2
0
    def folderitem(self, obj, item, index):
        """Service triggered each time an item is iterated in folderitems.

        The use of this service prevents the extra-loops in child objects.

        :obj: the instance of the class to be foldered
        :item: dict containing the properties of the object to be used by
            the template
        :index: current index of the item
        """
        item["replace"]["Title"] = get_link_for(obj)
        item["Description"] = obj.Description()

        retention_period = obj.getRetentionPeriod()
        if retention_period:
            hours = retention_period.get("hours", "0")
            minutes = retention_period.get("minutes", "0")
            days = retention_period.get("days", "0")
            item["RetentionPeriod"] = _(
                "hours: {} minutes: {} days: {}".format(hours, minutes, days))

        sample_matrix = obj.getSampleMatrix()
        item["replace"]["SampleMatrix"] = get_link_for(sample_matrix)

        container_type = obj.getContainerType()
        item["replace"]["ContainerType"] = get_link_for(container_type)

        # Hide sample points assigned to this sample type that do not belong
        # to the same container (Client or Setup)
        sample_points = obj.getSamplePoints()
        path = api.get_path(self.context)
        setup = api.get_setup()
        if api.get_parent(self.context) == setup:
            path = api.get_path(setup.bika_samplepoints)

        sample_points = filter(lambda sp: api.get_parent_path(sp) == path,
                               sample_points)

        # Display the links to the sample points
        links = map(get_link_for, sample_points)
        item["replace"]["SamplePoints"] = ", ".join(links)

        return item
Ejemplo n.º 3
0
    def make_catalog_query(self, context, field, value):
        """Create a catalog query for the field
        """

        # get the catalogs for the context
        catalogs = api.get_catalogs_for(context)
        # context not in any catalog?
        if not catalogs:
            logger.warn("UniqueFieldValidator: Context '{}' is not assigned"
                        "to any catalog!".format(repr(context)))
            return None

        # take the first catalog
        catalog = catalogs[0]

        # Check if the field accessor is indexed
        field_index = field.getName()
        accessor = field.getAccessor(context)
        if accessor:
            field_index = accessor.__name__

        # return if the field is not indexed
        if field_index not in catalog.indexes():
            return None

        # build a catalog query
        query = {
            "portal_type": api.get_portal_type(context),
            "path": {
                "query": api.get_parent_path(context),
                "depth": 1,
            }
        }
        query[field_index] = value
        logger.info("UniqueFieldValidator:Query={}".format(query))
        return query
Ejemplo n.º 4
0
    def make_catalog_query(self, context, field, value):
        """Create a catalog query for the field
        """

        # get the catalogs for the context
        catalogs = api.get_catalogs_for(context)
        # context not in any catalog?
        if not catalogs:
            logger.warn("UniqueFieldValidator: Context '{}' is not assigned"
                        "to any catalog!".format(repr(context)))
            return None

        # take the first catalog
        catalog = catalogs[0]

        # Check if the field accessor is indexed
        field_index = field.getName()
        accessor = field.getAccessor(context)
        if accessor:
            field_index = accessor.__name__

        # return if the field is not indexed
        if field_index not in catalog.indexes():
            return None

        # build a catalog query
        query = {
            "portal_type": api.get_portal_type(context),
            "path": {
                "query": api.get_parent_path(context),
                "depth": 1,
            }
        }
        query[field_index] = value
        logger.info("UniqueFieldValidator:Query={}".format(query))
        return query
Ejemplo n.º 5
0
    def __call__(self, value, *args, **kwargs):
        field = kwargs['field']
        fieldname = field.getName()
        instance = kwargs['instance']
        translate = getToolByName(instance, 'translation_service').translate

        # return directly if nothing changed
        if value == field.get(instance):
            return True

        # We want to use the catalog to speed things up, as using `objectValues`
        # is very expensive if the parent object contains many items
        parent_objects = []

        # 1. Get the right catalog for this object
        catalogs = api.get_catalogs_for(instance)
        catalog = catalogs[0]

        # 2. Check if the field accessor is indexed
        field_index = None
        accessor = field.getAccessor(instance)
        if accessor:
            field_index = accessor.__name__

        # 3. Check if the field index is in the indexes
        # Field is indexed, use the catalog instead of objectValues
        parent_path = api.get_parent_path(instance)
        portal_type = instance.portal_type
        catalog_query = {
            "portal_type": portal_type,
            "path": {
                "query": parent_path,
                "depth": 1
            }
        }

        if field_index and field_index in catalog.indexes():
            # We use the field index to reduce the results list
            catalog_query[field_index] = value
            parent_objects = map(api.get_object, catalog(catalog_query))
        elif fieldname in catalog.indexes():
            # We use the fieldname as index to reduce the results list
            catalog_query[fieldname] = value
            parent_objects = map(api.get_object, catalog(catalog_query))
        else:
            # fall back to the objectValues :(
            parent_object = api.get_parent(instance)
            parent_objects = parent_object.objectValues()

        for item in parent_objects:
            if hasattr(item, 'UID') and item.UID() != instance.UID() and \
               fieldname in item.Schema() and \
               str(item.Schema()[fieldname].get(item)) == str(value):
                # We have to compare them as strings because
                # even if a number (as an  id) is saved inside
                # a string widget and string field, it will be
                # returned as an int. I don't know if it is
                # caused because is called with
                # <item.Schema()[fieldname].get(item)>,
                # but it happens...
                msg = _("Validation failed: '${value}' is not unique",
                        mapping={'value': safe_unicode(value)})
                return to_utf8(translate(msg))
        return True
Ejemplo n.º 6
0
def get_parent_path(brain_or_object):
    """Proxy to bika.lims.api.get_parent_path
    """
    return api.get_parent_path(brain_or_object)
Ejemplo n.º 7
0
def get_parent_path(brain_or_object):
    """Proxy to bika.lims.api.get_parent_path
    """
    return api.get_parent_path(brain_or_object)
Ejemplo n.º 8
0
def get_parent_path(brain_or_object):
    """Proxy to senaite.api.get_parent_path
    """
    return api.get_parent_path(brain_or_object)