22from django .db import models
33from django .contrib .postgres .aggregates import ArrayAgg
44from django .contrib .postgres .fields import ArrayField
5- from django .db .models import OuterRef , Subquery , Q , Count , Prefetch , Func , F , UUIDField , Value
5+ from django .db .models import (
6+ OuterRef ,
7+ Subquery ,
8+ Q ,
9+ Count ,
10+ Prefetch ,
11+ Func ,
12+ F ,
13+ UUIDField ,
14+ Value ,
15+ )
616from django .db .models .functions import Coalesce
717
818# Third party imports
@@ -25,16 +35,16 @@ class InitiativeEpicViewSet(BaseViewSet):
2535 model = InitiativeEpic
2636
2737 @check_feature_flag (FeatureFlag .INITIATIVES )
28- @allow_permission ([ROLE .ADMIN , ROLE .MEMBER , ], level = "WORKSPACE" )
38+ @allow_permission ([ROLE .ADMIN , ROLE .MEMBER ], level = "WORKSPACE" )
2939 def create (self , request , slug , initiative_id ):
3040 # Get the epic_ids from the request
3141 epic_ids = request .data .get ("epic_ids" , [])
3242
3343 # Get the workspace
3444 workspace = Workspace .objects .get (slug = slug )
35- largest_sort_order = InitiativeEpic .objects .filter (workspace = workspace , initiative_id = initiative_id ). aggregate (
36- largest = models . Max ( "sort_order" )
37- )["largest" ]
45+ largest_sort_order = InitiativeEpic .objects .filter (
46+ workspace = workspace , initiative_id = initiative_id
47+ ). aggregate ( largest = models . Max ( "sort_order" )) ["largest" ]
3848
3949 # If largest_sort_order is None, set it to 10000
4050 if largest_sort_order is None :
@@ -45,59 +55,66 @@ def create(self, request, slug, initiative_id):
4555 # Create the initiative_epics
4656 initiative_epics = []
4757 for epic_id in epic_ids :
48- initiative_epics .append (InitiativeEpic (
49- workspace = workspace ,
50- initiative_id = initiative_id ,
51- epic_id = epic_id ,
52- sort_order = largest_sort_order ,
53- ))
58+ initiative_epics .append (
59+ InitiativeEpic (
60+ workspace = workspace ,
61+ initiative_id = initiative_id ,
62+ epic_id = epic_id ,
63+ sort_order = largest_sort_order ,
64+ )
65+ )
5466 largest_sort_order += 1000
5567
5668 # Bulk create the initiative_epics
57- initiative_epics = InitiativeEpic .objects .bulk_create (initiative_epics , batch_size = 1000 )
69+ initiative_epics = InitiativeEpic .objects .bulk_create (
70+ initiative_epics , batch_size = 1000
71+ )
5872
59- epics = Issue .objects .filter (
60- workspace__slug = slug , id__in = epic_ids
61- ).filter (Q (type__isnull = False ) & Q (type__is_epic = True )).annotate (
62- label_ids = Coalesce (
63- ArrayAgg (
64- "labels__id" ,
65- distinct = True ,
66- filter = Q (
67- ~ Q (labels__id__isnull = True )
68- & Q (label_issue__deleted_at__isnull = True )
73+ epics = (
74+ Issue .objects .filter (workspace__slug = slug , id__in = epic_ids )
75+ .filter (Q (type__isnull = False ) & Q (type__is_epic = True ))
76+ .annotate (
77+ label_ids = Coalesce (
78+ ArrayAgg (
79+ "labels__id" ,
80+ distinct = True ,
81+ filter = Q (
82+ ~ Q (labels__id__isnull = True )
83+ & Q (label_issue__deleted_at__isnull = True )
84+ ),
6985 ),
86+ Value ([], output_field = ArrayField (UUIDField ())),
7087 ),
71- Value ([], output_field = ArrayField (UUIDField ())),
72- ),
73- assignee_ids = Coalesce (
74- ArrayAgg (
75- "assignees__id" ,
76- distinct = True ,
77- filter = Q (
78- ~ Q (assignees__id__isnull = True )
79- & Q (assignees__member_project__is_active = True )
80- & Q (issue_assignee__deleted_at__isnull = True )
88+ assignee_ids = Coalesce (
89+ ArrayAgg (
90+ "assignees__id" ,
91+ distinct = True ,
92+ filter = Q (
93+ ~ Q (assignees__id__isnull = True )
94+ & Q (assignees__member_project__is_active = True )
95+ & Q (issue_assignee__deleted_at__isnull = True )
96+ ),
8197 ),
98+ Value ([], output_field = ArrayField (UUIDField ())),
8299 ),
83- Value ([], output_field = ArrayField ( UUIDField ())),
84- ),
85- ). values (
86- "id " ,
87- "name " ,
88- "state_id " ,
89- "sort_order " ,
90- "estimate_point " ,
91- "priority " ,
92- "start_date " ,
93- "target_date " ,
94- "sequence_id " ,
95- "project_id " ,
96- "archived_at " ,
97- "state__group " ,
98- "label_ids " ,
99- "assignee_ids " ,
100- "type_id" ,
100+ )
101+ . values (
102+ "id" ,
103+ "name " ,
104+ "state_id " ,
105+ "sort_order " ,
106+ "estimate_point " ,
107+ "priority " ,
108+ "start_date " ,
109+ "target_date " ,
110+ "sequence_id " ,
111+ "project_id " ,
112+ "archived_at " ,
113+ "state__group " ,
114+ "label_ids " ,
115+ "assignee_ids " ,
116+ "type_id " ,
117+ )
101118 )
102119
103120 return Response (epics , status = status .HTTP_200_OK )
@@ -108,57 +125,65 @@ def list(self, request, slug, initiative_id):
108125 workspace__slug = slug , initiative_id = initiative_id
109126 ).values_list ("epic_id" , flat = True )
110127
111- epics = Issue .objects .filter (
112- workspace__slug = slug , id__in = initiative_epics
113- ).filter (Q (type__isnull = False ) & Q (type__is_epic = True )).annotate (
114- label_ids = Coalesce (
115- ArrayAgg (
116- "labels__id" ,
117- distinct = True ,
118- filter = Q (
119- ~ Q (labels__id__isnull = True )
120- & Q (label_issue__deleted_at__isnull = True )
128+ epics = (
129+ Issue .objects .filter (
130+ workspace__slug = slug ,
131+ id__in = initiative_epics ,
132+ project__project_projectmember__member = self .request .user ,
133+ project__project_projectmember__is_active = True ,
134+ )
135+ .filter (Q (project__deleted_at__isnull = True ))
136+ .filter (Q (type__isnull = False ) & Q (type__is_epic = True ))
137+ .annotate (
138+ label_ids = Coalesce (
139+ ArrayAgg (
140+ "labels__id" ,
141+ distinct = True ,
142+ filter = Q (
143+ ~ Q (labels__id__isnull = True )
144+ & Q (label_issue__deleted_at__isnull = True )
145+ ),
121146 ),
147+ Value ([], output_field = ArrayField (UUIDField ())),
122148 ),
123- Value ([], output_field = ArrayField (UUIDField ())),
124- ),
125- assignee_ids = Coalesce (
126- ArrayAgg (
127- "assignees__id" ,
128- distinct = True ,
129- filter = Q (
130- ~ Q (assignees__id__isnull = True )
131- & Q (assignees__member_project__is_active = True )
132- & Q (issue_assignee__deleted_at__isnull = True )
149+ assignee_ids = Coalesce (
150+ ArrayAgg (
151+ "assignees__id" ,
152+ distinct = True ,
153+ filter = Q (
154+ ~ Q (assignees__id__isnull = True )
155+ & Q (assignees__member_project__is_active = True )
156+ & Q (issue_assignee__deleted_at__isnull = True )
157+ ),
133158 ),
159+ Value ([], output_field = ArrayField (UUIDField ())),
134160 ),
135- Value ([], output_field = ArrayField ( UUIDField ())),
136- ),
137- ). values (
138- "id " ,
139- "name " ,
140- "state_id " ,
141- "sort_order " ,
142- "estimate_point " ,
143- "priority " ,
144- "start_date " ,
145- "target_date " ,
146- "sequence_id " ,
147- "project_id " ,
148- "archived_at " ,
149- "state__group " ,
150- "label_ids " ,
151- "assignee_ids " ,
152- "type_id" ,
161+ )
162+ . values (
163+ "id" ,
164+ "name " ,
165+ "state_id " ,
166+ "sort_order " ,
167+ "estimate_point " ,
168+ "priority " ,
169+ "start_date " ,
170+ "target_date " ,
171+ "sequence_id " ,
172+ "project_id " ,
173+ "archived_at " ,
174+ "state__group " ,
175+ "label_ids " ,
176+ "assignee_ids " ,
177+ "type_id " ,
178+ )
153179 )
180+
154181 return Response (epics , status = status .HTTP_200_OK )
155182
156- @allow_permission ([ROLE .ADMIN , ROLE .MEMBER , ], level = "WORKSPACE" )
183+ @allow_permission ([ROLE .ADMIN , ROLE .MEMBER ], level = "WORKSPACE" )
157184 def destroy (self , request , slug , initiative_id , epic_id ):
158185 initiative_epics = InitiativeEpic .objects .filter (
159- workspace__slug = slug ,
160- epic_id = epic_id ,
161- initiative_id = initiative_id
186+ workspace__slug = slug , epic_id = epic_id , initiative_id = initiative_id
162187 )
163188 initiative_epics .delete ()
164189 return Response (status = status .HTTP_204_NO_CONTENT )
0 commit comments