Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Allow ReferenceWidgetAdapter to be exclusive #195

Merged
merged 5 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog

**Added**

- #195 Allow Reference Widget adapters to be exclusive
- #183 Internal Clients functionality
- #187 Allow to introduce the Age instead of Date of Birth for Patient

Expand Down
35 changes: 23 additions & 12 deletions bika/health/adapters/referencewidget/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,27 @@

from bika.health import logger
from bika.health.utils import get_client_from_chain
from bika.health.utils import is_internal_client
from bika.health.utils import resolve_query_for_shareable
from bika.lims import api
from bika.lims.adapters.referencewidgetvocabulary import \
DefaultReferenceWidgetVocabulary
from bika.lims.interfaces import IClient
from bika.lims.interfaces import IReferenceWidgetVocabulary
from bika.lims.utils import chain
from bika.lims.utils import get_client


class IReferenceWidgetAdapter(IReferenceWidgetVocabulary):
"""Marker interface for reference widget adapters
"""

def is_supported(self):
"""Returns whether the current adapter supports the search
"""


class IExclusiveReferenceWidgetAdapter(IReferenceWidgetAdapter):
"""Marker interface for 'exclusive' reference widget adapters
"""


class ClientAwareReferenceWidgetAdapter(DefaultReferenceWidgetVocabulary):
"""Injects search criteria (filters) in the query when the current context
Expand Down Expand Up @@ -82,6 +88,13 @@ class ClientAwareReferenceWidgetAdapter(DefaultReferenceWidgetVocabulary):
("Contact", "getParentUID"),
]

def is_supported(self):
"""Returns whether the adapter supports the portal_type from the query
"""
query = self.get_baseline_query()
portal_type = self.get_portal_type(query)
return portal_type in self.client_aware_types

def get_client_from_query(self, query, purge=False):
"""Resolves the client from the query passed-in
"""
Expand All @@ -98,24 +111,22 @@ def get_client_from_query(self, query, purge=False):
return client
return None

def get_baseline_query(self):
"""Returns the baseline query to work with
"""
return super(ClientAwareReferenceWidgetAdapter, self).get_raw_query()

def get_raw_query(self):
"""Returns the raw query to use for current search, based on the
base query + update query
"""
query = super(ClientAwareReferenceWidgetAdapter, self).get_raw_query()
query = self.get_baseline_query()
logger.info("===============================================")
logger.info("Custom client-aware reference widget vocabulary")
logger.info(repr(query))

# Get the portal types from the query
# Get the portal type from the query
portal_type = self.get_portal_type(query)
if not portal_type:
# Don't know the type we are searching for, do nothing
return query

if portal_type not in self.client_aware_types:
# The portal type is not client aware, do nothing
return query

# Try to resolve the client from the query
client = self.get_client_from_query(query, purge=True)
Expand Down
30 changes: 27 additions & 3 deletions bika/health/browser/referencewidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

from zope.component import getAdapters

from bika.health import logger
from bika.health.adapters.referencewidget import IReferenceWidgetAdapter
from bika.health.adapters.referencewidget import IExclusiveReferenceWidgetAdapter
from bika.lims.browser.widgets.referencewidget import \
ajaxReferenceWidgetSearch as base

Expand All @@ -36,13 +38,35 @@ def search(self):
"""Returns the list of brains that match with the request criteria
"""
params = (self.context, self.request)
adapters = list(getAdapters(params, IReferenceWidgetAdapter))
adapters = list(getAdapters(params, IReferenceWidgetAdapter)) or []

# Convert adapters to a list (don't need the name)
adapters = map(lambda ad: ad[1], adapters)

# Filter supported adapters
adapters = filter(lambda ad: ad.is_supported(), adapters)

if not adapters:
# No health-specific adapters found, fallback to core's defaults
# Fallback to core's defaults
return super(ajaxReferenceWidgetSearch, self).search()

# Do not consider other adapters when an "exclusive" adapter is found
exclusive = filter(lambda adapter:
IExclusiveReferenceWidgetAdapter.providedBy(adapter),
adapters)

if exclusive and len(exclusive) > 1:
logger.error("Multiple exclusive adapters found!")
# We do not fallback to core's default. We return empty to prevent
# inconsistencies
return []

elif exclusive:
# Discard other adapters
adapters = [exclusive[0]]

brains = []
for name, adapter in adapters:
for adapter in adapters:
brains.extend(adapter())

return brains