@@ -165,13 +165,28 @@ def post(self, request, slug, project_id):
165165 ]:
166166 return Response ({"error" : "Invalid priority" }, status = status .HTTP_400_BAD_REQUEST )
167167
168+ # get the triage state
169+ triage_state = State .triage_objects .filter (project_id = project_id , workspace__slug = slug ).first ()
170+
171+ if not triage_state :
172+ triage_state = State .objects .create (
173+ name = "Intake Triage" ,
174+ group = State .TRIAGE ,
175+ project_id = project_id ,
176+ workspace_id = project .workspace_id ,
177+ color = "#4E5355" ,
178+ sequence = 65000 ,
179+ default = False ,
180+ )
181+
168182 # create an issue
169183 issue = Issue .objects .create (
170184 name = request .data .get ("issue" , {}).get ("name" ),
171185 description = request .data .get ("issue" , {}).get ("description" , {}),
172186 description_html = request .data .get ("issue" , {}).get ("description_html" , "<p></p>" ),
173187 priority = request .data .get ("issue" , {}).get ("priority" , "none" ),
174188 project_id = project_id ,
189+ state_id = triage_state .id ,
175190 )
176191
177192 # create an intake issue
@@ -320,7 +335,10 @@ def patch(self, request, slug, project_id, issue_id):
320335
321336 # Get issue data
322337 issue_data = request .data .pop ("issue" , False )
338+ issue_serializer = None
339+ intake_serializer = None
323340
341+ # Validate issue data if provided
324342 if bool (issue_data ):
325343 issue = Issue .objects .annotate (
326344 label_ids = Coalesce (
@@ -344,6 +362,7 @@ def patch(self, request, slug, project_id, issue_id):
344362 Value ([], output_field = ArrayField (UUIDField ())),
345363 ),
346364 ).get (pk = issue_id , workspace__slug = slug , project_id = project_id )
365+
347366 # Only allow guests to edit name and description
348367 if project_member .role <= 5 :
349368 issue_data = {
@@ -354,71 +373,55 @@ def patch(self, request, slug, project_id, issue_id):
354373
355374 issue_serializer = IssueSerializer (issue , data = issue_data , partial = True )
356375
357- if issue_serializer .is_valid ():
358- current_instance = issue
359- # Log all the updates
360- requested_data = json .dumps (issue_data , cls = DjangoJSONEncoder )
361- if issue is not None :
362- issue_activity .delay (
363- type = "issue.activity.updated" ,
364- requested_data = requested_data ,
365- actor_id = str (request .user .id ),
366- issue_id = str (issue_id ),
367- project_id = str (project_id ),
368- current_instance = json .dumps (
369- IssueSerializer (current_instance ).data ,
370- cls = DjangoJSONEncoder ,
371- ),
372- epoch = int (timezone .now ().timestamp ()),
373- intake = (intake_issue .id ),
374- )
375- issue_serializer .save ()
376- else :
376+ if not issue_serializer .is_valid ():
377377 return Response (issue_serializer .errors , status = status .HTTP_400_BAD_REQUEST )
378378
379379 # Only project admins and members can edit intake issue attributes
380380 if project_member .role > 15 :
381- serializer = IntakeIssueUpdateSerializer (intake_issue , data = request .data , partial = True )
382- current_instance = json .dumps (IntakeIssueSerializer (intake_issue ).data , cls = DjangoJSONEncoder )
381+ intake_serializer = IntakeIssueUpdateSerializer (intake_issue , data = request .data , partial = True )
382+
383+ if not intake_serializer .is_valid ():
384+ return Response (intake_serializer .errors , status = status .HTTP_400_BAD_REQUEST )
385+
386+ # Both serializers are valid, now save them
387+ if issue_serializer :
388+ current_instance = issue
389+ # Log all the updates
390+ requested_data = json .dumps (issue_data , cls = DjangoJSONEncoder )
391+ issue_activity .delay (
392+ type = "issue.activity.updated" ,
393+ requested_data = requested_data ,
394+ actor_id = str (request .user .id ),
395+ issue_id = str (issue_id ),
396+ project_id = str (project_id ),
397+ current_instance = json .dumps (
398+ IssueSerializer (current_instance ).data ,
399+ cls = DjangoJSONEncoder ,
400+ ),
401+ epoch = int (timezone .now ().timestamp ()),
402+ intake = str (intake_issue .id ),
403+ )
404+ issue_serializer .save ()
383405
384- if serializer .is_valid ():
385- serializer .save ()
386- # Update the issue state if the issue is rejected or marked as duplicate
387- if serializer .data ["status" ] in [- 1 , 2 ]:
388- issue = Issue .objects .get (pk = issue_id , workspace__slug = slug , project_id = project_id )
389- state = State .objects .filter (group = "cancelled" , workspace__slug = slug , project_id = project_id ).first ()
390- if state is not None :
391- issue .state = state
392- issue .save ()
393-
394- # Update the issue state if it is accepted
395- if serializer .data ["status" ] in [1 ]:
396- issue = Issue .objects .get (pk = issue_id , workspace__slug = slug , project_id = project_id )
397-
398- # Update the issue state only if it is in triage state
399- if issue .state .is_triage :
400- # Move to default state
401- state = State .objects .filter (workspace__slug = slug , project_id = project_id , default = True ).first ()
402- if state is not None :
403- issue .state = state
404- issue .save ()
405-
406- # create a activity for status change
407- issue_activity .delay (
408- type = "intake.activity.created" ,
409- requested_data = json .dumps (request .data , cls = DjangoJSONEncoder ),
410- actor_id = str (request .user .id ),
411- issue_id = str (issue_id ),
412- project_id = str (project_id ),
413- current_instance = current_instance ,
414- epoch = int (timezone .now ().timestamp ()),
415- notification = False ,
416- origin = base_host (request = request , is_app = True ),
417- intake = str (intake_issue .id ),
418- )
419- serializer = IntakeIssueSerializer (intake_issue )
420- return Response (serializer .data , status = status .HTTP_200_OK )
421- return Response (serializer .errors , status = status .HTTP_400_BAD_REQUEST )
406+ # Save intake issue (state transition happens in serializer's update method)
407+ if intake_serializer :
408+ current_instance = json .dumps (IntakeIssueSerializer (intake_issue ).data , cls = DjangoJSONEncoder )
409+ intake_serializer .save ()
410+
411+ # create a activity for status change
412+ issue_activity .delay (
413+ type = "intake.activity.created" ,
414+ requested_data = json .dumps (request .data , cls = DjangoJSONEncoder ),
415+ actor_id = str (request .user .id ),
416+ issue_id = str (issue_id ),
417+ project_id = str (project_id ),
418+ current_instance = current_instance ,
419+ epoch = int (timezone .now ().timestamp ()),
420+ notification = False ,
421+ origin = base_host (request = request , is_app = True ),
422+ intake = str (intake_issue .id ),
423+ )
424+ return Response (IntakeIssueSerializer (intake_issue ).data , status = status .HTTP_200_OK )
422425 else :
423426 return Response (IntakeIssueSerializer (intake_issue ).data , status = status .HTTP_200_OK )
424427
0 commit comments