Skip to content

Commit

Permalink
action handler updates
Browse files Browse the repository at this point in the history
  - now uses ActionEnum
  - takes outcome_id as argument when available
  • Loading branch information
salabh-aot committed Oct 26, 2023
1 parent 5da30ae commit b2d611a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 35 deletions.
1 change: 1 addition & 0 deletions epictrack-api/src/api/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module holds all the action handlers."""
from .disable_work_start_date import DisableWorkStartDate
28 changes: 8 additions & 20 deletions epictrack-api/src/api/actions/action_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,27 @@
import re
from importlib import import_module

from api.actions.base import ActionBase
from api.actions.base import ACTION_HANDLER_CLASS_MAPS, ActionFactory
from api.exceptions import UnprocessableEntityError
from api.models.action import ActionEnum


class ActionHandler: # pylint: disable=too-few-public-methods
"""Handles action handlers"""

def __init__(self, action_class_name: str) -> None:
def __init__(self, action_class_enum: ActionEnum) -> None:
"""Initialize and configure the action handler class"""
module_name = self._convert_class_name_to_module_name(action_class_name)
action_classes_path = f"api.actions.{module_name}"
action_classes_path = f"api.actions"
try:
action_class_name = ACTION_HANDLER_CLASS_MAPS[action_class_enum]
action_module = import_module(action_classes_path)
self.action_class: ActionBase = getattr(action_module, action_class_name)
except ModuleNotFoundError as e:
print(f"{e.name} action handler module not found")
self.action_class: ActionFactory = getattr(action_module, action_class_name)
except (ModuleNotFoundError, KeyError) as e:
print(f"{action_class_enum.name} action handler module not found")
self.action_class = None
except AttributeError as e:
raise UnprocessableEntityError(f"Action class {action_class_name} not configured properly.") from e

def _convert_class_name_to_module_name(self, class_name: str) -> str:
"""Convert class name into valid python module names
Eg: ActionHandler -> action_handler
"""
module_name = re.sub(
"([A-Z])",
r'_\1',
class_name,
)
# Discard preceding _
return module_name[1:].lower()

def apply(self, params: dict = None) -> None:
"""Perform the action"""
# So that actions not done yet won't raise errors
Expand Down
9 changes: 8 additions & 1 deletion epictrack-api/src/api/actions/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
"""Base for all action handlers"""
from abc import ABC, abstractmethod

from api.models.action import ActionEnum

class ActionBase(ABC): # pylint: disable=too-few-public-methods

class ActionFactory(ABC): # pylint: disable=too-few-public-methods
"""Base class for action handlers"""

@abstractmethod
def run(self, params):
"""Perform the action"""


ACTION_HANDLER_CLASS_MAPS = {
ActionEnum.LOCK_WORK_START_DATE : "DisableWorkStartDate"
}
4 changes: 2 additions & 2 deletions epictrack-api/src/api/actions/disable_work_start_date.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Disable work start date action handler"""

from api.actions.base import ActionBase
from api.actions.base import ActionFactory
from api.models import db
from api.models.work import Work


class DisableWorkStartDate(ActionBase): # pylint: disable=too-few-public-methods
class DisableWorkStartDate(ActionFactory): # pylint: disable=too-few-public-methods
"""Disable work start date action"""

def run(self, params: dict) -> None:
Expand Down
4 changes: 4 additions & 0 deletions epictrack-api/src/api/schemas/response/work_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class Meta(AutoSchemaBase.Meta):
substitution_act = fields.Nested(SubstitutionActSchema, dump_only=True)
eac_decision_by = fields.Nested(StaffSchema, exclude=("position",), dump_only=True)
decision_by = fields.Nested(StaffSchema, exclude=("position",), dump_only=True)
work_state = fields.Method("get_work_state")

def get_work_state(self, obj: Work) -> str:
return obj.work_state.value


class WorkPhaseResponseSchema(
Expand Down
25 changes: 13 additions & 12 deletions epictrack-api/src/api/services/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def update_event(cls, data: dict, event_id: int, commit: bool = True) -> Event:
cls._process_event(
current_work_phase, event, event_old, current_event_old_index
)
cls._process_actions(event)
cls._process_actions(event, data.get("outcome_id", None))
if commit:
db.session.commit()
return event
Expand Down Expand Up @@ -556,23 +556,24 @@ def delete_event(cls, event_id: int):
return "Deleted successfully"

@classmethod
def _process_actions(cls, event: Event) -> None:
def _process_actions(cls, event: Event, outcome_id: int = None) -> None:
if event.actual_date is None:
return
outcomes = OutcomeConfigurationService.find_by_configuration_id(
event.event_configuration_id
)
if not outcomes:
return
outcome_ids = list(map(lambda x: x.id, outcomes))
if outcome_id is None:
outcomes = OutcomeConfigurationService.find_by_configuration_id(
event.event_configuration_id
)
if not outcomes:
return
outcome_id = outcomes[0].id
action_configurations = (
db.session.query(ActionConfiguration)
.join(Action, Action.id == ActionConfiguration.action_id)
.filter(ActionConfiguration.outcome_configuration_id.in_(outcome_ids))
.filter(ActionConfiguration.outcome_configuration_id == outcome_id)
.all()
)
for action_configuration in action_configurations:
action_handler = ActionHandler(action_configuration.action.name)
if action_configuration.action.id == ActionEnum.DISABLE_WORK_START_DATE.value:
params = {"work_id": event.work_id, "start_date": event.actual_date}
action_handler = ActionHandler(ActionEnum(action_configuration.action_id))
if action_configuration.action.id == ActionEnum.LOCK_WORK_START_DATE.value:
params = {"work_id": event.work_id, "start_date": event.actual_date, "start_date_locked": True}
action_handler.apply(params)

0 comments on commit b2d611a

Please sign in to comment.