""" 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, } }