From 190a034e023b8792a5de5bce224bcb949440298b Mon Sep 17 00:00:00 2001 From: Kamil Malinowski Date: Mon, 21 Aug 2023 13:05:09 +0200 Subject: [PATCH] OP-1500 Fixed duplicate resolve, business_event --- calcrule_social_protection/apps.py | 23 ++++-- calcrule_social_protection/signals.py | 72 +++---------------- .../benefit_package_base_strategy.py | 10 ++- 3 files changed, 33 insertions(+), 72 deletions(-) diff --git a/calcrule_social_protection/apps.py b/calcrule_social_protection/apps.py index 179ed33..689519e 100644 --- a/calcrule_social_protection/apps.py +++ b/calcrule_social_protection/apps.py @@ -2,16 +2,17 @@ import inspect from django.apps import AppConfig from calculation.apps import CALCULATION_RULES -from core.abs_calculation_rule import AbsCalculationRule - -MODULE_NAME = "calcrule_social_protection" -DEFAULT_CFG = {} +MODULE_NAME = 'calcrule_social_protection' +DEFAULT_CFG = { + 'calculate_business_event': 'calcrule_social_protection.calculate' +} def read_all_calculation_rules(): """function to read all calculation rules from that module""" - for name, cls in inspect.getmembers(importlib.import_module("calcrule_social_protection.calculation_rule"), inspect.isclass): + for name, cls in inspect.getmembers(importlib.import_module('calcrule_social_protection.calculation_rule'), + inspect.isclass): if cls.__module__.split('.')[1] == 'calculation_rule': CALCULATION_RULES.append(cls) cls.ready() @@ -20,7 +21,19 @@ def read_all_calculation_rules(): class CalcruleSocialProtectionConfig(AppConfig): name = MODULE_NAME + calculate_business_event = None + def ready(self): from core.models import ModuleConfiguration cfg = ModuleConfiguration.get_or_default(MODULE_NAME, DEFAULT_CFG) read_all_calculation_rules() + self.__load_config(cfg) + + @classmethod + def __load_config(cls, cfg): + """ + Load all config fields that match current AppConfig class fields, all custom fields have to be loaded separately + """ + for field in cfg: + if hasattr(CalcruleSocialProtectionConfig, field): + setattr(CalcruleSocialProtectionConfig, field, cfg[field]) diff --git a/calcrule_social_protection/signals.py b/calcrule_social_protection/signals.py index b7d3755..f75ea6c 100644 --- a/calcrule_social_protection/signals.py +++ b/calcrule_social_protection/signals.py @@ -1,7 +1,7 @@ -import ast import json import logging +from calcrule_social_protection.apps import CalcruleSocialProtectionConfig from core.models import User from core.service_signals import ServiceSignalBindType from core.signals import bind_service_signal @@ -11,7 +11,6 @@ from invoice.models import Bill from invoice.services import BillService from tasks_management.models import Task -from tasks_management.services import TaskService logger = logging.getLogger(__name__) imis_modules = openimis_apps() @@ -20,82 +19,33 @@ def bind_service_signals(): def on_task_complete_calculate(**kwargs): - def create_bill(convert_results, bill_status): - convert_results['bill_data']['status'] = bill_status + def create_bill(results, bill_status): + results['bill_data']['status'] = bill_status user = User.objects.get(id=result['data']['user']['id']) - convert_results['user'] = user - BillService(user).bill_create(convert_results=convert_results) + results['user'] = user + BillService(user).bill_create(convert_results=results) try: result = kwargs.get('result', None) + task = result['data']['task'] if result \ and result['success'] \ - and result['data']['task']['business_event'] == 'benefit_plan_update': - convert_results = result['data']['task']['data'] + and task['business_event'] == CalcruleSocialProtectionConfig.calculate_business_event: + convert_results = task['data'] convert_results = convert_results.replace("'", '"') convert_results = json.loads(convert_results) - if result['data']['task']['status'] == Task.Status.COMPLETED: + task_status = task['status'] + if task_status == Task.Status.COMPLETED: create_bill(convert_results, Bill.Status.VALIDATED) - if result['data']['task']['status'] == Task.Status.FAILED: + if task_status == Task.Status.FAILED: create_bill(convert_results, Bill.Status.CANCELLED) else: pass except Exception as e: logger.error("Error while executing on_task_complete_calculate", exc_info=e) - def on_task_resolve_calculate(**kwargs): - def resolve_task_all(_task, _user): - if 'FAILED' in _task.business_status.values(): - TaskService(_user).complete_task({"id": _task.id, 'failed': True}) - if sum(map('APPROVED'.__eq__, _task.business_status.values())) == _task.task_group.taskexecutor_set.count(): - TaskService(_user).complete_task({"id": _task.id}) - - def resolve_task_any(_task, _user): - if 'FAILED' in _task.business_status.values(): - TaskService(_user).complete_task({"id": _task.id, 'failed': True}) - if 'APPROVED' in _task.business_status.values(): - TaskService(_user).complete_task({"id": _task.id}) - - def resolve_task_n(_task, _user): - # TODO for now hardcoded to any, to be updated - resolve_task_any(_task, _user) - - try: - result = kwargs.get('result', None) - if result and result['success'] \ - and result['data']['task']['business_event'] == 'benefit_plan_update' \ - and result['data']['task']['status'] == Task.Status.ACCEPTED: - data = kwargs.get("result").get("data") - task = Task.objects.select_related('task_group').prefetch_related('task_group__taskexecutor_set').get( - id=data["task"]["id"]) - user = User.objects.get(id=data["user"]["id"]) - - if not task.task_group: - logger.error("Resolving task not assigned to TaskGroup") - return ['Task not assigned to TaskGroup'] - - resolvers = { - 'ALL': resolve_task_all, - 'ANY': resolve_task_any, - 'N': resolve_task_n, - } - - if task.task_group.completion_policy not in resolvers: - logger.error("Resolving task with unknown completion_policy: %s", task.task_group.completion_policy) - return ['Unknown completion_policy: %s' % task.task_group.completion_policy] - - resolvers[task.task_group.completion_policy](task, user) - except Exception as e: - logger.error("Error while executing on_task_resolve_benefit_plan_update", exc_info=e) - return [str(e)] - bind_service_signal( 'task_service.complete_task', on_task_complete_calculate, bind_type=ServiceSignalBindType.AFTER ) - bind_service_signal( - 'task_service.resolve_task', - on_task_resolve_calculate, - bind_type=ServiceSignalBindType.AFTER - ) diff --git a/calcrule_social_protection/strategies/benefit_package_base_strategy.py b/calcrule_social_protection/strategies/benefit_package_base_strategy.py index 985540f..164e8ea 100644 --- a/calcrule_social_protection/strategies/benefit_package_base_strategy.py +++ b/calcrule_social_protection/strategies/benefit_package_base_strategy.py @@ -1,13 +1,12 @@ -import json - -from django.core.serializers.json import DjangoJSONEncoder from django.db import transaction +from calcrule_social_protection.apps import CalcruleSocialProtectionConfig from core.models import User from core.utils import convert_to_python_value from core.signals import register_service_signal from invoice.services import BillService from social_protection.models import BeneficiaryStatus +from tasks_management.apps import TasksManagementConfig from tasks_management.models import Task from tasks_management.services import TaskService @@ -114,12 +113,11 @@ def _convert_entity_to_bill( @register_service_signal('calcrule_social_protection.create_task') def create_task_after_exceeding_limit(cls, convert_results): user = convert_results.pop('user') - # TODO change the executor and business events TaskService(user).create({ 'source': 'calcrule_social_protection', 'entity': None, 'status': Task.Status.RECEIVED, - 'executor_action_event': 'benefit_plan_update', - 'business_event': 'benefit_plan_update', + 'executor_action_event': TasksManagementConfig.default_executor_event, + 'business_event': CalcruleSocialProtectionConfig.calculate_business_event, 'data': f"{convert_results}" })