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

Doctors assigned to other clients are listed when logged as Client #102

Merged
merged 9 commits into from
Aug 31, 2018
4 changes: 3 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog

**Added**

- #102 Add Primary Referrer column in Doctor listings
- #85 Allow client contact to list/add/edit Batches from its own Client
- #83 Allow client contact to create and edit Doctors

Expand All @@ -18,7 +19,8 @@ Changelog

**Fixed**

- #102 All Samples are listed inside Case context
- #102 Doctors assigned to other clients are listed when logged as Client
- #103 All Samples are listed inside Case context
- #99 Traceback when publishing health results from inside a client
- #97 Traceback accessing Doctor samples when user is not Manager, LabManager or LabClerk
- #82 Inconsistent behavior with health' skins priority over core's
Expand Down
130 changes: 60 additions & 70 deletions bika/health/browser/doctors/folder_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
# Copyright 2018 by it's authors.
# Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst.

from Products.CMFCore.utils import getToolByName
from collections import OrderedDict

from Products.CMFCore.utils import getToolByName
from bika.health import bikaMessageFactory as _
from bika.health.permissions import *
from bika.lims import api
from bika.lims.browser.client import ClientContactsView
from bika.lims.interfaces import IClient, ILabContact
from bika.lims.interfaces import IClient
from bika.lims.utils import get_link
from plone.memoize import view as viewcache


class DoctorsView(ClientContactsView):
Expand All @@ -24,31 +27,36 @@ def __init__(self, context, request):
self.title = self.context.translate(_("Doctors"))
self.icon = self.portal_url + "/++resource++bika.health.images/doctor_big.png"
self.description = ""
self.show_sort_column = False
self.show_select_row = False
self.show_select_column = False
self.pagesize = 50

self.columns = {
'getDoctorID': {'title': _('Doctor ID'),
'index': 'getDoctorID'},
'getFullname': {'title': _('Full Name'),
'index': 'getFullname'},
'getEmailAddress': {'title': _('Email Address')},
'getBusinessPhone': {'title': _('Business Phone')},
'getMobilePhone': {'title': _('Mobile Phone')},
}
self.columns = OrderedDict((
("getDoctorID", {
"title": _('Doctor ID'),
"index": "getDoctorID",
"sortable": True, }),
("getFullname", {
"title": _("Full Name"),
"index": "getFullname",
"sortable": True, }),
("getPrimaryReferrer", {
"title": _("Primary Referrer"),
"index": "getPrimaryReferrerUID",
"sortable": True, }),
("Username", {
"title": _("User Name"), }),
("getEmailAddress", {
"title": _("Email Address"), }),
("getBusinessPhone", {
"title": _("Business Phone"), }),
("getMobilePhone", {
"title": _("MobilePhone"), }),
))

self.review_states = [
{'id':'default',
'title': _('Active'),
'contentFilter': {'inactive_state': 'active'},
'transitions': [],
'columns': ['getDoctorID',
'getFullname',
'getEmailAddress',
'getBusinessPhone',
'getMobilePhone']},
'columns': self.columns.keys()},
]

def __call__(self):
Expand All @@ -68,68 +76,50 @@ def __call__(self):
'title': _('Dormant'),
'contentFilter': {'inactive_state': 'inactive'},
'transitions': [{'id':'activate'}, ],
'columns': ['getDoctorID',
'getFullname',
'getEmailAddress',
'getBusinessPhone',
'getMobilePhone']})
'columns': self.columns.keys()})
self.review_states.append(
{'id':'all',
'title': _('All'),
'contentFilter':{},
'transitions':[{'id':'empty'}],
'columns': ['getDoctorID',
'getFullname',
'getEmailAddress',
'getBusinessPhone',
'getMobilePhone']})
'columns': self.columns.keys()})
stat = self.request.get("%s_review_state"%self.form_id, 'default')
self.show_select_column = stat != 'all'
self._apply_filter_by_client()
return super(DoctorsView, self).__call__()

def folderitems(self):
items = super(DoctorsView, self).folderitems()
for x in range(len(items)):
if not 'obj' in items[x]:
continue
obj = items[x]['obj']
items[x]['replace']['getDoctorID'] = "<a href='%s'>%s</a>" % \
(items[x]['url'], items[x]['getDoctorID'])
items[x]['replace']['getFullname'] = "<a href='%s'>%s</a>" % \
(items[x]['url'], items[x]['getFullname'])

return items

def _apply_filter_by_client(self):
"""
From the current user and the context, update the filter that will be
used for filtering the Doctor's list.
"""
# If the current context is a Client, filter Doctors by Client UID
if IClient.providedBy(self.context):
client_uid = api.get_uid(self.context)
self.contentFilter['getPrimaryReferrerUID'] = client_uid
return

# If the current user is a Client contact, filter the Doctors in
# accordance. For the rest of users (LabContacts), the visibility of
# the doctors depend on their permissions
user = api.get_current_user()
roles = user.getRoles()
if 'Client' not in roles:
return
# If the current user is a client contact, do not display the doctors
# assigned to other clients
elif self.get_user_client_uid():
client_uid = self.get_user_client_uid()
self.contentFilter['getPrimaryReferrerUID'] = [client_uid, None]

# Are we sure this a ClientContact?
# May happen that this is a Plone member, w/o having a ClientContact
# assigned or having a LabContact assigned... weird
contact = api.get_user_contact(user)
if not contact or ILabContact.providedBy(contact):
return
return super(DoctorsView, self).__call__()

# Is the parent from the Contact a Client?
client = api.get_parent(contact)
if not client or not IClient.providedBy(client):
return
client_uid = api.get_uid(client)
self.contentFilter['getPrimaryReferrerUID'] = client_uid
@viewcache.memoize
def get_user_client_uid(self, default=None):
"""Returns the id of the client the current user belongs to
"""
client = api.get_current_client()
if client:
return api.get_uid(client)
return default

def folderitem(self, obj, item, index):
"""Applies new properties to the item to be rendered
"""
item = super(DoctorsView, self).folderitem(obj, item, index)
url = item.get("url")
doctor_id = item.get("getDoctorID")
item['replace']['getDoctorID'] = get_link(url, value=doctor_id)
item['getPrimaryReferrer'] = ""
doctor = api.get_object(obj)
pri = doctor.getPrimaryReferrer()
if pri:
pri_url = pri.absolute_url()
pri = pri.Title()
item['replace']['getPrimaryReferrer'] = get_link(pri_url, value=pri)
return item
59 changes: 41 additions & 18 deletions bika/health/browser/doctors/getdoctors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
# Copyright 2018 by it's authors.
# Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst.

from Products.CMFCore.utils import getToolByName
from bika.health import bikaMessageFactory as _
from bika.health.permissions import *
from bika.lims import bikaMessageFactory as _b
from bika.lims.browser import BrowserView
from operator import itemgetter
import json
from operator import itemgetter

import plone
from bika.lims import api
from bika.lims.browser import BrowserView
from bika.lims.interfaces import ILabContact, IClient


class ajaxGetDoctors(BrowserView):
Expand All @@ -25,21 +24,27 @@ def __call__(self):
nr_rows = self.request['rows']
sord = self.request['sord']
sidx = self.request['sidx']

rows = []

pc = self.portal_catalog
proxies = pc(portal_type="Doctor")
for doctor in proxies:
doctor = doctor.getObject()
if self.portal_workflow.getInfoFor(doctor, 'inactive_state', 'active') == 'inactive':
query = dict(portal_type="Doctor", inactive_state="active")
client = self.get_current_client()
if client:
# Search those Doctors that are assigned to the same client or
# that do not have any client assigned
query["getPrimaryReferrerUID"] = [api.get_uid(client), None]

doctors = api.search(query, 'portal_catalog')
for doctor in doctors:
doctor_id = doctor.id
doctor_title = doctor.Title
search_val = ('{} {}'.format(doctor_id, doctor_title)).lower()
if searchTerm not in search_val:
continue
if doctor.Title().lower().find(searchTerm) > -1 \
or doctor.getDoctorID().lower().find(searchTerm) > -1:
rows.append({'Title': doctor.Title() or '',
'DoctorID': doctor.getDoctorID(),
'DoctorSysID': doctor.id,
'DoctorUID': doctor.UID()})

rows.append({'Title': doctor.Title() or '',
'DoctorID': doctor.getDoctorID(),
'DoctorSysID': doctor.id,
'DoctorUID': doctor.UID()})

rows = sorted(rows, cmp=lambda x, y: cmp(x.lower(), y.lower()), key = itemgetter(sidx and sidx or 'Title'))
if sord == 'desc':
Expand All @@ -52,3 +57,21 @@ def __call__(self):
'rows': rows[(int(page) - 1) * int(nr_rows): int(page) * int(nr_rows)]}

return json.dumps(ret)

def get_current_client(self, default=None):
"""Returns the client the current user belongs to
"""
user = api.get_current_user()
roles = user.getRoles()
if 'Client' not in roles:
return default

contact = api.get_user_contact(user)
if not contact or ILabContact.providedBy(contact):
return default

client = api.get_parent(contact)
if not client or not IClient.providedBy(client):
return default

return client
6 changes: 6 additions & 0 deletions bika/health/static/js/bika.health.analysisrequest.add.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ function HealthAnalysisRequestAddView() {
if (element.length > 0) {
filter_combogrid(element[0], "getParentUID", clientuid);
}

// Doctor searches
element = $("#Doctor-" + col);
if (element.length > 0) {
filter_combogrid(element[0], "getPrimaryReferrerUID", [clientuid, null]);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions bika/health/static/js/bika.health.batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ function HealthBatchEditView() {
// client inside patient-related combos
applyFilter($("#Patient"), 'getPrimaryReferrerUID', rcuid);
applyFilter($("#ClientPatientID"), 'getPrimaryReferrerUID', rcuid);
// Also, show only the Doctors that are not from a different client
applyFilter($("#Doctor"), 'getPrimaryReferrerUID', [rcuid, null]);
}

// By default, get the referrer uids from the form itself. If the form is
Expand Down