diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index 0c9b1d104..e77ca86e6 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -94,7 +94,6 @@ class TicketFlowViewSet(JMSBulkModelViewSet): def perform_create_or_update(self, serializer): instance = serializer.save() instance.save() - instance.rules.model.change_assignees_display(instance.rules.all()) def perform_create(self, serializer): self.perform_create_or_update(serializer) diff --git a/apps/tickets/migrations/0011_remove_approvalrule_assignees_display.py b/apps/tickets/migrations/0011_remove_approvalrule_assignees_display.py new file mode 100644 index 000000000..f709114d8 --- /dev/null +++ b/apps/tickets/migrations/0011_remove_approvalrule_assignees_display.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.13 on 2021-12-15 09:56 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('tickets', '0010_auto_20210812_1618'), + ] + + operations = [ + migrations.RemoveField( + model_name='approvalrule', + name='assignees_display', + ), + ] diff --git a/apps/tickets/models/flow.py b/apps/tickets/models/flow.py index 6add3696e..ae5eea0ff 100644 --- a/apps/tickets/models/flow.py +++ b/apps/tickets/models/flow.py @@ -3,13 +3,11 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +from users.models import User from common.mixins.models import CommonModelMixin -from common.db.encoder import ModelJSONFieldEncoder from orgs.mixins.models import OrgModelMixin -from orgs.models import Organization -from orgs.utils import tmp_to_root_org, tmp_to_org +from orgs.utils import tmp_to_root_org, tmp_to_org, get_current_org_id from ..const import TicketType, TicketApprovalLevel, TicketApprovalStrategy -from ..signals import post_or_update_change_ticket_flow_approval __all__ = ['TicketFlow', 'ApprovalRule'] @@ -29,10 +27,6 @@ class ApprovalRule(CommonModelMixin): 'users.User', related_name='assigned_ticket_flow_approval_rule', verbose_name=_("Assignees") ) - assignees_display = models.JSONField( - encoder=ModelJSONFieldEncoder, default=list, - verbose_name=_('Assignees display') - ) class Meta: verbose_name = _('Ticket flow approval rule') @@ -40,9 +34,19 @@ class ApprovalRule(CommonModelMixin): def __str__(self): return '{}({})'.format(self.id, self.level) - @classmethod - def change_assignees_display(cls, qs): - post_or_update_change_ticket_flow_approval.send(sender=cls, qs=qs) + def get_assignees(self, org_id=None): + assignees = [] + org_id = org_id if org_id else get_current_org_id() + with tmp_to_org(org_id): + if self.strategy == TicketApprovalStrategy.super_admin: + assignees = User.get_super_admins() + elif self.strategy == TicketApprovalStrategy.org_admin: + assignees = User.get_org_admins() + elif self.strategy == TicketApprovalStrategy.super_org_admin: + assignees = User.get_super_and_org_admins() + elif self.strategy == TicketApprovalStrategy.custom_user: + assignees = self.assignees.all() + return assignees class TicketFlow(CommonModelMixin, OrgModelMixin): diff --git a/apps/tickets/models/ticket.py b/apps/tickets/models/ticket.py index beb6d129b..59646a6ac 100644 --- a/apps/tickets/models/ticket.py +++ b/apps/tickets/models/ticket.py @@ -140,24 +140,29 @@ class Ticket(CommonModelMixin, OrgModelMixin): self.status = TicketStatus.closed def create_related_node(self): + org_id = self.flow.org_id approval_rule = self.get_current_ticket_flow_approve() ticket_step = TicketStep.objects.create(ticket=self, level=self.approval_step) ticket_assignees = [] - assignees = approval_rule.assignees.all() + assignees = approval_rule.get_assignees(org_id=org_id) for assignee in assignees: ticket_assignees.append(TicketAssignee(step=ticket_step, assignee=assignee)) TicketAssignee.objects.bulk_create(ticket_assignees) def create_process_map(self): + org_id = self.flow.org_id approval_rules = self.flow.rules.order_by('level') nodes = list() for node in approval_rules: + assignees = node.get_assignees(org_id=org_id) + assignee_ids = [assignee.id for assignee in assignees] + assignees_display = [str(assignee) for assignee in assignees] nodes.append( { 'approval_level': node.level, 'state': ProcessStatus.notified, - 'assignees': [i for i in node.assignees.values_list('id', flat=True)], - 'assignees_display': node.assignees_display + 'assignees': assignee_ids, + 'assignees_display': assignees_display } ) return nodes diff --git a/apps/tickets/serializers/ticket/ticket.py b/apps/tickets/serializers/ticket/ticket.py index 276da4267..b93ee2543 100644 --- a/apps/tickets/serializers/ticket/ticket.py +++ b/apps/tickets/serializers/ticket/ticket.py @@ -8,7 +8,6 @@ from orgs.mixins.serializers import OrgResourceModelSerializerMixin from perms.models import AssetPermission from orgs.models import Organization from orgs.utils import tmp_to_org -from users.models import User from tickets.models import Ticket, TicketFlow, ApprovalRule from tickets.const import TicketApprovalStrategy from .meta import type_serializer_classes_mapping @@ -139,7 +138,8 @@ class TicketApproveSerializer(TicketSerializer): class TicketFlowApproveSerializer(serializers.ModelSerializer): strategy_display = serializers.ReadOnlyField(source='get_strategy_display', label=_('Approve strategy')) - assignees_read_only = serializers.SerializerMethodField(label=_("Assignees")) + assignees_read_only = serializers.SerializerMethodField(label=_('Assignees')) + assignees_display = serializers.SerializerMethodField(label=_('Assignees display')) class Meta: model = ApprovalRule @@ -153,6 +153,9 @@ class TicketFlowApproveSerializer(serializers.ModelSerializer): 'assignees': {'write_only': True, 'allow_empty': True, 'required': False} } + def get_assignees_display(self, obj): + return [str(assignee) for assignee in obj.get_assignees()] + def get_assignees_read_only(self, obj): if obj.strategy == TicketApprovalStrategy.custom_user: return obj.assignees.values_list('id', flat=True) @@ -190,7 +193,9 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin): raise serializers.ValidationError(error) return value - def create_or_update(self, action, validated_data, related, assignees, instance=None): + def create_or_update(self, action, validated_data, instance=None): + related = 'rules' + assignees = 'assignees' childs = validated_data.pop(related, []) if not instance: instance = getattr(super(), action)(validated_data) @@ -203,12 +208,6 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin): for level, data in enumerate(childs, 1): data_m2m = data.pop(assignees, None) child_instance = related_model.objects.create(**data, level=level) - if child_instance.strategy == TicketApprovalStrategy.super_admin: - data_m2m = list(User.get_super_admins()) - elif child_instance.strategy == TicketApprovalStrategy.org_admin: - data_m2m = list(User.get_org_admins()) - elif child_instance.strategy == TicketApprovalStrategy.super_org_admin: - data_m2m = list(User.get_super_and_org_admins()) getattr(child_instance, assignees).set(data_m2m) child_instances.append(child_instance) instance_related.set(child_instances) @@ -216,12 +215,12 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin): @atomic def create(self, validated_data): - return self.create_or_update('create', validated_data, 'rules', 'assignees') + return self.create_or_update('create', validated_data) @atomic def update(self, instance, validated_data): if instance.org_id == Organization.ROOT_ID: instance = self.create(validated_data) else: - instance = self.create_or_update('update', validated_data, 'rules', 'assignees', instance) + instance = self.create_or_update('update', validated_data, instance) return instance diff --git a/apps/tickets/signals_handler/ticket.py b/apps/tickets/signals_handler/ticket.py index 2d036f936..8bcbc521b 100644 --- a/apps/tickets/signals_handler/ticket.py +++ b/apps/tickets/signals_handler/ticket.py @@ -12,12 +12,3 @@ logger = get_logger(__name__) @receiver(post_change_ticket_action, sender=Ticket) def on_post_change_ticket_action(sender, ticket, action, **kwargs): ticket.handler.dispatch(action) - - -@receiver(post_or_update_change_ticket_flow_approval, sender=ApprovalRule) -def post_or_update_change_ticket_flow_approval(sender, qs, **kwargs): - updates = [] - for instance in qs: - instance.assignees_display = [str(assignee) for assignee in instance.assignees.all()] - updates.append(instance) - sender.objects.bulk_update(updates, ['assignees_display', ])