konova/process/enums.py
2021-07-01 13:36:07 +02:00

202 lines
6.6 KiB
Python

"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 25.11.20
"""
from django.contrib.auth.models import User
from konova.enums import BaseEnum
from organisation.enums import RoleTypeEnum
class ProcessStateEnum(BaseEnum):
"""
ProcessStates define in which state a process can be:
private
Only the user can see and edit this process. Not viewable by any others
accessible
The user and all participated users can see this process. Only the responsible next user can edit
the process
licensed
The user and all participated users can see this process. Only the responsible next user can edit
the process
official
The user and all participated users can see this process. Only the registration office user can now
change details. If a process is changed in this state, the state will be set back to accessible, so all
participated users need to take a look on the changed data again.
recorded [Will be set automatically after certain time]
The user and all participated users can see this process. No one can edit data. To change any details,
the process has to be set to accessible manually again.
"""
PRIVATE = 0
ACCESSIBLE = 1
LICENSED = 2
OFFICIAL = 3
RECORDED = 4
@classmethod
def as_choices(cls, drop_empty_choice: bool = False) -> list:
""" Extends as_choices, so choices will be translated
Args:
drop_empty_choice (bool): Whether the empty choice shall be dropped or not
Returns:
trans_choices (list): Translated choices
"""
choices = super().as_choices(drop_empty_choice)
return ProcessStateEnum.__translate_choices(choices)
@staticmethod
def __translate_choices(choices: list) -> list:
""" Translates a list of prepared but untranslated choices
Args:
choices (list): A list of tuple chocies
Returns:
choices (list): The same list but translated
"""
from process.settings import PROCESS_STATE_STRINGS
trans_choices = []
# Translate
for choice in choices:
if choice[0] is not None:
choice = list(choice)
trans = PROCESS_STATE_STRINGS.get(choice[0])
choice[1] = trans
choice = tuple(choice)
trans_choices.append(choice)
return trans_choices
@classmethod
def is_state(cls, state: int) -> bool:
""" Checks whether the given state is a valid Enum
Args:
state (int): The state to be checked
Returns:
is_valid (bool)
"""
valid_vals = {enum.value for enum in cls}
return state in valid_vals
@classmethod
def as_role_choices(cls, user: User) -> list:
""" Checks whether the given state is a valid Enum
Args:
user (User): The performing user
Returns:
is_valid (bool)
"""
role = user.current_role
if role is None:
return []
role_type = role.role.type
role_type_enum = RoleTypeEnum[role_type]
choices = PROCESS_ROLE_STATES.get(role_type_enum)
choices = [(enum.value, enum.name) for enum in choices]
choices = ProcessStateEnum.__translate_choices(choices)
return choices
@classmethod
def as_next_role_choices(cls, user: User, current_state: int, is_owner: bool = False) -> list:
""" Returns a list of valid choices depending on the current role of the user and the current state
Args:
user (User): The performing user
current_state (int): The current state of the process
Returns:
choices (list): A list of valid choices
"""
role = user.current_role
if role is None:
return []
role_type = role.role.type
role_type_enum = RoleTypeEnum[role_type]
# Merge the possible choices depending on the current user role
# with the possible choices depending on the process state
role_choices = PROCESS_ROLE_STATES.get(role_type_enum)
status_choices = PROCESS_STATE_NEXT_CHOICES.get(current_state)
current_choice = {ProcessStateEnum(current_state)}
choices = (status_choices & role_choices) | current_choice
# If user is owner of this process, we shall add the private choice if not existing, yet
if is_owner:
choices = {ProcessStateEnum.PRIVATE} | choices
# Make sure enums are ordered by numerical value
choices = sorted(choices, key=lambda _enum: _enum.value)
# Create selectable and translated choices from enum list
choices = [(enum.value, enum.name) for enum in choices]
choices = ProcessStateEnum.__translate_choices(choices)
return choices
# DEFINES THE AVAILABLE STATES FOR EACH ROLE
PROCESS_ROLE_STATES = {
RoleTypeEnum.DATAPROVIDER: {
ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
},
RoleTypeEnum.LICENSINGAUTHORITY: {
#ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
ProcessStateEnum.LICENSED,
},
RoleTypeEnum.REGISTRATIONOFFICE: {
#ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
ProcessStateEnum.OFFICIAL,
},
}
# DEFINES POSSIBLE NEXT STATES FOR EACH PROCESS STATE
PROCESS_STATE_NEXT_CHOICES = {
ProcessStateEnum.PRIVATE.value: {
ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
},
ProcessStateEnum.ACCESSIBLE.value: {
ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
ProcessStateEnum.LICENSED,
},
ProcessStateEnum.LICENSED.value: {
ProcessStateEnum.PRIVATE,
ProcessStateEnum.ACCESSIBLE,
ProcessStateEnum.LICENSED,
ProcessStateEnum.OFFICIAL,
},
ProcessStateEnum.OFFICIAL.value: {
ProcessStateEnum.ACCESSIBLE,
ProcessStateEnum.OFFICIAL,
ProcessStateEnum.RECORDED,
},
}
# DEFINES FOR EACH STATE WHICH ROLE CAN EDIT THE PROCESS
PROCESS_EDITABLE_STATE = {
ProcessStateEnum.PRIVATE.value: {
RoleTypeEnum.DATAPROVIDER,
RoleTypeEnum.LICENSINGAUTHORITY,
},
ProcessStateEnum.ACCESSIBLE.value: {
RoleTypeEnum.LICENSINGAUTHORITY,
},
ProcessStateEnum.LICENSED.value: {
RoleTypeEnum.REGISTRATIONOFFICE,
},
ProcessStateEnum.OFFICIAL.value: {
RoleTypeEnum.REGISTRATIONOFFICE,
}
}