Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Patient Workflows and Permissions #69

Merged
merged 19 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from 17 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 docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Changelog
1.4.0 (unreleased)
------------------

- #69 Fix Patient Workflows and Permissions
- #68 Allow client local patients
- #66 Fix widget view mode
- #65 Fix cannot create partitions from samples with Patient assigned
Expand Down
29 changes: 26 additions & 3 deletions src/senaite/patient/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from bika.lims.utils import tmpID
from dateutil.relativedelta import relativedelta
from senaite.patient.config import PATIENT_CATALOG
from senaite.patient.permissions import AddPatient
from zope.component import getUtility
from zope.component.interfaces import IFactory
from zope.event import notify
Expand Down Expand Up @@ -155,12 +156,15 @@ def create_temporary_patient():
return patient


def store_temporary_patient(patient):
def store_temporary_patient(container, patient):
"""Store temporary patient to the patients folder
:param container: The container where the patient should be stored
:param patient: A temporary patient object
"""
portal = api.get_portal()
container = portal.patients
# Notify `ObjectCreateEvent` to generate a UID first
notify(ObjectCreatedEvent(patient))
# set the patient in the container
container._setObject(patient.id, patient)
patient = container.get(patient.getId())
return patient
Expand Down Expand Up @@ -333,3 +337,22 @@ def is_patient_allowed_in_client():
allowed = api.get_registry_record(
"senaite.patient.allow_patients_in_clients", False)
return allowed


def get_patient_folder():
"""Returns the global patient folder
:returns: global patients folder
"""
portal = api.get_portal()
return portal.patients


def is_patient_creation_allowed(container):
"""Check if the security context allows to add a new patient
:param container: The container to check the permission
:returns: True if it is allowed to create a patient in the container,
otherwise False
"""
return api.security.check_permission(AddPatient, container)
12 changes: 8 additions & 4 deletions src/senaite/patient/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@
for="senaite.patient.content.patientfolder.IPatientFolder"
class=".patientfolder.PatientFolderView"
permission="zope2.View"
layer="senaite.patient.interfaces.ISenaitePatientLayer"
/>

<!-- Patient Controlpanel -->
<browser:page
name="patient-controlpanel"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
class=".controlpanel.PatientControlPanelView"
permission="senaite.core.permissions.ManageBika"
layer="senaite.patient.interfaces.ISenaitePatientLayer" />
permission="senaite.patient.permissions.ManagePatients"
layer="senaite.patient.interfaces.ISenaitePatientLayer"
/>

<!-- Static directory for js, css and image resources -->
<plone:static
directory="static"
type="plone"
name="senaite.patient.static" />
name="senaite.patient.static"
/>

<!-- Static Resources Viewlet -->
<browser:viewlet
Expand All @@ -40,6 +43,7 @@
class="senaite.core.browser.viewlets.resources.ResourcesViewlet"
permission="zope2.View"
template="./static/resources.pt"
layer="senaite.patient.interfaces.ISenaitePatientLayer" />
layer="senaite.patient.interfaces.ISenaitePatientLayer"
/>

</configure>
3 changes: 2 additions & 1 deletion src/senaite/patient/browser/patientfolder.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from senaite.patient.api import to_identifier_type_name
from senaite.patient.api import tuplify_identifiers
from senaite.patient.catalog import PATIENT_CATALOG
from senaite.patient.permissions import AddPatient


class PatientFolderView(ListingView):
Expand Down Expand Up @@ -57,7 +58,7 @@ def __init__(self, context, request):
self.context_actions = {
_("Add"): {
"url": "++add++Patient",
"permission": "Add portal content",
"permission": AddPatient,
"icon": "++resource++bika.lims.images/add.png"}
}

Expand Down
1 change: 1 addition & 0 deletions src/senaite/patient/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
description="Run various configuration actions"
handler=".setuphandlers.setup_handler">
<depends name="typeinfo"/>
<depends name="workflow"/>
</genericsetup:importStep>

<!-- Uninstall profile -->
Expand Down
9 changes: 6 additions & 3 deletions src/senaite/patient/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
# Copyright 2020-2022 by it's authors.
# Some rights reserved, see README and LICENSE.

ManagePatients = "senaite.patient: Manage Patients"

AddPatientFolder = "senaite.patient: Add PatientFolder"
# Add permission for our custom content types.
# Slso see `initialize` function in `__init__.py`
AddPatient = "senaite.patient: Add Patient"
AddPatientFolder = "senaite.patient: Add PatientFolder"

# Permission that governs the control panel view
ManagePatients = "senaite.patient: Manage Patients"

# Transition permissions
TransitionActivate = "senaite.patient: Transition: Activate"
Expand Down
4 changes: 2 additions & 2 deletions src/senaite/patient/permissions.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<permission id="senaite.patient.permissions.ManagePatients" title="senaite.patient: Manage Patients"/>

<!-- Content permissions -->
<permission id="senaite.patient.permissions.AddPatientFolder" title="senaite.patient: Add Patient Folder"/>
<!-- Add content permissions -->
<permission id="senaite.patient.permissions.AddPatient" title="senaite.patient: Add Patient"/>
<permission id="senaite.patient.permissions.AddPatientFolder" title="senaite.patient: Add Patient Folder"/>

<!-- Transition permissions -->
<permission id="senaite.patient.permissions.TransitionActivate" title="senaite.patient: Transition: Activate"/>
Expand Down
10 changes: 1 addition & 9 deletions src/senaite/patient/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
<?xml version="1.0"?>
<!-- This file contains add-on dependency and version information. Is read
during Plone start-up and is required to be present and well-formatted for the
add-on to appear in the installer control panel.
If dependencies are defined, "portal_setup" installs the profiles listed as
dependencies before installing this add-on own profile.
-->
<metadata>
<version>1407</version>

<!-- Be sure to install the following dependencies if not yet installed -->
<version>1408</version>
<dependencies>
<dependency>profile-senaite.lims:default</dependency>
</dependencies>
Expand Down
9 changes: 8 additions & 1 deletion src/senaite/patient/profiles/default/rolemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,24 @@
<role name="LabClerk"/>
<role name="LabManager"/>
<role name="Manager"/>
<!-- for client local patients -->
<role name="Owner"/>
</permission>

<!-- Transition permissions -->
<permission name="senaite.patient: Transition: Activate" acquire="False">
<role name="LabManager"/>
<role name="LabClerk"/>
<role name="LabManager"/>
<role name="Manager"/>
<!-- for client local patients -->
<role name="Owner"/>
</permission>
<permission name="senaite.patient: Transition: Deactivate" acquire="False">
<role name="LabClerk"/>
<role name="LabManager"/>
<role name="Manager"/>
<!-- for client local patients -->
<role name="Owner"/>
</permission>

<!-- Permissions for Sample fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,68 @@
manager_bypass="False"
i18n:domain="senaite.patient">

<!-- PLONE permissions -->
<!-- MANAGED PERMISSIONS -->
<permission>Add portal content</permission>
<permission>Access contents information</permission>
<permission>Delete objects</permission>
<permission>List folder contents</permission>
<permission>Modify portal content</permission>
<permission>View</permission>
<!-- Custom Add permission to create Patients in this folder
Also see `initialize` function in `__init__.py`
-->
<permission>senaite.patient: Add Patient</permission>
<!-- /MANAGED PERMISSIONS -->

<!-- State: active -->

<!-- State: active (initial) -->
<state state_id="active" title="Active" i18n:attributes="title">

<!-- TRANSITIONS -->
<exit-transition transition_id="" />
<!-- /TRANSITIONS -->

<!-- PERMISSION MAPPINGS -->
<!-- This permission governs if the patients folder should appear in searches -->
<permission-map name="Access contents information" acquired="False">
<!-- All except Anonymous and Client -->
<permission-role>Analyst</permission-role>
<permission-role>ClientGuest</permission-role>
<permission-role>LabClerk</permission-role>
<permission-role>LabManager</permission-role>
<permission-role>Preserver</permission-role>
<permission-role>RegulatoryInspector</permission-role>
<permission-role>Sampler</permission-role>
<permission-role>SamplingCoordinator</permission-role>
<!-- Plone roles -->
<permission-role>Manager</permission-role>
<permission-role>Owner</permission-role>
<permission-role>Site Administrator</permission-role>
</permission-map>
<permission-map name="Delete objects" acquired="False" />
<permission-map name="List folder contents" acquired="False">
<!-- All except Anonymous and Client -->
<permission-role>Analyst</permission-role>
<permission-role>ClientGuest</permission-role>
<!-- Roles needed to add other contents inside the patients folder.
Not needed at the moment, but we use the default roles -->
<permission-map name="Add portal content" acquired="False">
<permission-role>LabClerk</permission-role>
<permission-role>LabManager</permission-role>
<permission-role>Preserver</permission-role>
<permission-role>RegulatoryInspector</permission-role>
<permission-role>Sampler</permission-role>
<permission-role>SamplingCoordinator</permission-role>
<!-- Plone roles -->
<permission-role>Manager</permission-role>
<permission-role>Site Administrator</permission-role>
</permission-map>
<permission-map name="Add portal content" acquired="False">
<permission-role>Client</permission-role>
<!-- Roles that are needed to create a new Patient -->
<permission-map name="senaite.patient: Add Patient" acquired="False">
<permission-role>LabClerk</permission-role>
<permission-role>LabManager</permission-role>
<!-- Plone roles -->
<permission-role>Manager</permission-role>
</permission-map>
<permission-map name="Modify portal content" acquired="False">
<!-- Never allow to delete contents -->
<permission-map name="Delete objects" acquired="False">
</permission-map>
<!-- Roles needed to list all patients -->
<permission-map name="List folder contents" acquired="False">
<permission-role>LabClerk</permission-role>
<permission-role>LabManager</permission-role>
<!-- Plone roles -->
<permission-role>Manager</permission-role>
<permission-role>Owner</permission-role>
</permission-map>
<!-- Only the Manager can modify the folder -->
<permission-map name="Modify portal content" acquired="False">
<permission-role>Manager</permission-role>
</permission-map>
<!-- Roles that are needed to see the patients folder / that it appears in
the side navigation bar -->
<permission-map name="View" acquired="False">
<!-- All except Anonymous -->
<permission-role>Analyst</permission-role>
<permission-role>Client</permission-role>
<permission-role>ClientGuest</permission-role>
<permission-role>LabClerk</permission-role>
<permission-role>LabManager</permission-role>
<permission-role>Preserver</permission-role>
<permission-role>RegulatoryInspector</permission-role>
<permission-role>Sampler</permission-role>
<permission-role>SamplingCoordinator</permission-role>
<!-- Plone roles -->
<permission-role>Manager</permission-role>
<permission-role>Owner</permission-role>
<permission-role>Site Administrator</permission-role>
</permission-map>
<!-- /PERMISSION MAPPINGS -->
</state>

<variable variable_id="action" for_catalog="False" for_status="True" update_always="True">
Expand Down
Loading