perf: Approval process role selection supports multiple strategies

This commit is contained in:
feng
2024-07-26 16:23:38 +08:00
committed by Bryan
parent 920cfdac5c
commit 41b2ce06a8
4 changed files with 103 additions and 87 deletions

View File

@@ -1,51 +1,23 @@
from django.db.transaction import atomic
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from common.serializers.fields import LabeledChoiceField
from common.serializers.fields import LabeledChoiceField, JSONManyToManyField
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from orgs.models import Organization
from orgs.utils import get_current_org_id
from tickets.const import TicketApprovalStrategy, TicketType
from tickets.const import TicketType
from tickets.models import TicketFlow, ApprovalRule
__all__ = ['TicketFlowSerializer']
class TicketFlowApproveSerializer(serializers.ModelSerializer):
strategy = LabeledChoiceField(
choices=TicketApprovalStrategy.choices, required=True, label=_('Approve strategy')
)
assignees_read_only = serializers.SerializerMethodField(label=_('Assignees'))
assignees_display = serializers.SerializerMethodField(label=_('Assignees display'))
users = JSONManyToManyField(label=_('User'))
class Meta:
model = ApprovalRule
fields_small = [
'level', 'strategy', 'assignees_read_only', 'assignees_display',
]
fields_m2m = ['assignees', ]
fields = fields_small + fields_m2m
read_only_fields = ['level', 'assignees_display']
extra_kwargs = {
'assignees': {'write_only': True, 'allow_empty': True, 'required': False}
}
@staticmethod
def get_assignees_display(instance):
return [str(assignee) for assignee in instance.get_assignees()]
@staticmethod
def get_assignees_read_only(instance):
if instance.strategy == TicketApprovalStrategy.custom_user:
return instance.assignees.values_list('id', flat=True)
return []
def validate(self, attrs):
if attrs['strategy'] == TicketApprovalStrategy.custom_user and not attrs.get('assignees'):
error = _('Please select the Assignees')
raise serializers.ValidationError({'assignees': error})
return super().validate(attrs)
fields = ['level', 'users']
read_only_fields = ['level']
class TicketFlowSerializer(OrgResourceModelSerializerMixin):
@@ -56,15 +28,14 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin):
class Meta:
model = TicketFlow
fields_mini = ['id', ]
fields_mini = ['id', 'type']
fields_small = fields_mini + [
'type', 'approval_level', 'created_by', 'date_created', 'date_updated',
'org_id', 'org_name'
'approval_level', 'created_by', 'date_created',
'date_updated', 'org_id', 'org_name'
]
fields = fields_small + ['rules', ]
read_only_fields = ['created_by', 'org_id', 'date_created', 'date_updated']
fields = fields_small + ['rules']
read_only_fields = ['created_by', 'date_created', 'date_updated']
extra_kwargs = {
'type': {'required': True},
'approval_level': {'required': True}
}
@@ -76,31 +47,23 @@ class TicketFlowSerializer(OrgResourceModelSerializerMixin):
return value
def create_or_update(self, action, validated_data, instance=None):
related = 'rules'
assignees = 'assignees'
childs = validated_data.pop(related, [])
if not instance:
children = validated_data.pop('rules', [])
if instance is None:
instance = getattr(super(), action)(validated_data)
else:
instance = getattr(super(), action)(instance, validated_data)
getattr(instance, related).all().delete()
instance_related = getattr(instance, related)
child_instances = []
related_model = instance_related.model
# Todo: 这个权限的判断
for level, data in enumerate(childs, 1):
data_m2m = data.pop(assignees, None)
child_instance = related_model.objects.create(**data, level=level)
getattr(child_instance, assignees).set(data_m2m)
child_instances.append(child_instance)
instance_related.set(child_instances)
instance.rules.all().delete()
child_instances = [
instance.rules.model.objects.create(**data, level=level)
for level, data in enumerate(children, 1)
]
instance.rules.set(child_instances)
return instance
@atomic
def create(self, validated_data):
return self.create_or_update('create', validated_data)
@atomic
def update(self, instance, validated_data):
current_org_id = get_current_org_id()
root_org_id = Organization.ROOT_ID