Skip to content

Commit e1c5c81

Browse files
sauravsapkotasudan45
authored andcommitted
Add Graphql mutation for Analysis CRUD
Rename analyis field into analysis_id Add test cases for Analysis Mutation Change filter genericscalartype into filtertype Change filter genericscalartype into filtertype Remove required False in analyisis pillar analyis Add analysis pillar delete mutation Refactor add return when pillar is not None
1 parent 44262bb commit e1c5c81

File tree

6 files changed

+520
-10
lines changed

6 files changed

+520
-10
lines changed

apps/analysis/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ def annotate_for_analysis_pillar_summary(cls, qs):
349349
analyzed_entries=models.F('dragged_entries') + models.F('discarded_entries'),
350350
)
351351

352+
def can_delete(self, user):
353+
return self.can_modify(user)
354+
352355

353356
class DiscardedEntry(models.Model):
354357
"""

apps/analysis/mutation.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
AnalysisReport,
1818
AnalysisReportUpload,
1919
AnalysisReportSnapshot,
20+
Analysis,
2021
)
2122
from .schema import (
2223
get_analysis_pillar_qs,
@@ -31,6 +32,7 @@
3132
AnalysisReportType,
3233
AnalysisReportUploadType,
3334
AnalysisReportSnapshotType,
35+
AnalysisType,
3436
)
3537
from .serializers import (
3638
AnalysisPillarGqlSerializer,
@@ -42,6 +44,7 @@
4244
AnalysisReportSerializer,
4345
AnalysisReportSnapshotSerializer,
4446
AnalysisReportUploadSerializer,
47+
AnalysisGqlSerializer,
4548
)
4649

4750

@@ -84,7 +87,7 @@
8487
)
8588

8689

87-
# Analysi Report
90+
# Analysis Report
8891
AnalysisReportInputType = generate_input_type_for_serializer(
8992
'AnalysisReportInputType',
9093
serializer_class=AnalysisReportSerializer,
@@ -105,6 +108,11 @@
105108
serializer_class=AnalysisReportUploadSerializer,
106109
)
107110

111+
AnalysisInputType = generate_input_type_for_serializer(
112+
'AnalysisInputType',
113+
serializer_class=AnalysisGqlSerializer,
114+
)
115+
108116

109117
class RequiredPermissionMixin():
110118
permissions = [
@@ -269,9 +277,47 @@ class Arguments:
269277
result = graphene.Field(AnalysisReportUploadType)
270278

271279

280+
class AnalysisMutationMixin(RequiredPermissionMixin):
281+
@classmethod
282+
def filter_queryset(cls, qs, info):
283+
return qs.filter(project=info.context.active_project)
284+
285+
286+
class CreateAnalysis(AnalysisMutationMixin, PsGrapheneMutation):
287+
class Arguments:
288+
data = AnalysisInputType(required=True)
289+
model = Analysis
290+
serializer_class = AnalysisGqlSerializer
291+
result = graphene.Field(AnalysisType)
292+
293+
294+
class UpdateAnalysis(AnalysisMutationMixin, PsGrapheneMutation):
295+
class Arguments:
296+
data = AnalysisInputType(required=True)
297+
id = graphene.ID(required=True)
298+
model = Analysis
299+
serializer_class = AnalysisGqlSerializer
300+
result = graphene.Field(AnalysisType)
301+
302+
303+
class DeleteAnalysis(AnalysisMutationMixin, PsDeleteMutation):
304+
class Arguments:
305+
id = graphene.ID(required=True)
306+
model = Analysis
307+
result = graphene.Field(AnalysisType)
308+
309+
310+
class DeleteAnalysisPillar(AnalysisPillarMutationMixin, PsDeleteMutation):
311+
class Arguments:
312+
id = graphene.ID(required=True)
313+
model = AnalysisPillar
314+
result = graphene.Field(AnalysisPillarType)
315+
316+
272317
class Mutation():
273318
# Analysis Pillar
274319
analysis_pillar_update = UpdateAnalysisPillar.Field()
320+
analysis_pillar_delete = DeleteAnalysisPillar.Field()
275321
# Discarded Entry
276322
discarded_entry_create = CreateAnalysisPillarDiscardedEntry.Field()
277323
discarded_entry_update = UpdateAnalysisPillarDiscardedEntry.Field()
@@ -289,3 +335,7 @@ class Mutation():
289335
# -- Uploads
290336
analysis_report_upload_create = CreateAnalysisReportUpload.Field()
291337
analysis_report_upload_delete = DeleteAnalysisReportUpload.Field()
338+
# Analysis
339+
analysis_create = CreateAnalysis.Field()
340+
analysis_update = UpdateAnalysis.Field()
341+
analysis_delete = DeleteAnalysis.Field()

apps/analysis/schema.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,18 @@ class Meta:
196196
'title',
197197
'main_statement',
198198
'information_gap',
199-
'filters',
200199
)
201200

202201
assignee = graphene.Field(UserType, required=True)
203-
analysis = graphene.ID(source='analysis_id', required=True)
202+
analysis_id = graphene.ID(source='analysis_id', required=True)
204203
cloned_from = graphene.ID(source='cloned_from_id')
205204
analyzed_entries_count = graphene.Int(required=True)
205+
filters = graphene.List(graphene.NonNull(
206+
type('FilterDataType', (graphene.ObjectType,), {
207+
'id': graphene.String(),
208+
'key': graphene.String(),
209+
'uniqueId': graphene.String()
210+
})))
206211

207212
# XXX: N+1 and No pagination
208213
statements = graphene.List(graphene.NonNull(AnalyticalStatementType))

apps/analysis/serializers.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,14 @@ def validate(self, data):
331331

332332

333333
class AnalysisPillarGqlSerializer(TempClientIdMixin, UserResourceSerializer):
334+
id = IntegerIDField(required=False)
334335
statements = AnalyticalStatementGqlSerializer(many=True, source='analyticalstatement_set', required=False)
336+
analysis = serializers.PrimaryKeyRelatedField(queryset=Analysis.objects.all(), required=False)
335337

336338
class Meta:
337339
model = AnalysisPillar
338340
fields = (
341+
'id',
339342
'title',
340343
'main_statement',
341344
'information_gap',
@@ -409,21 +412,18 @@ def validate(self, data):
409412
return data
410413

411414

412-
class AnalysisGqlSerializer(UserResourceSerializer):
413-
id = IntegerIDField(required=False)
415+
class AnalysisGqlSerializer(UserResourceSerializer, ProjectPropertySerializerMixin):
414416
analysis_pillar = AnalysisPillarGqlSerializer(many=True, source='analysispillar_set', required=False)
415417
start_date = serializers.DateField(required=False, allow_null=True)
416418

417419
class Meta:
418420
model = Analysis
419421
fields = (
420-
'id',
421422
'title',
422423
'team_lead',
423-
'project',
424424
'start_date',
425425
'end_date',
426-
'cloned_from',
426+
'analysis_pillar',
427427
)
428428

429429
def validate_project(self, project):
@@ -432,6 +432,7 @@ def validate_project(self, project):
432432
return project
433433

434434
def validate(self, data):
435+
data['project'] = self.project
435436
start_date = data.get('start_date')
436437
end_date = data.get('end_date')
437438
if start_date and start_date > end_date:
@@ -440,6 +441,43 @@ def validate(self, data):
440441
)
441442
return data
442443

444+
def create_or_update_pillar(self, pillar_data, instance):
445+
data = {
446+
"title": pillar_data.get('title'),
447+
"assignee": pillar_data.get('assignee').id,
448+
"analysis": instance.id,
449+
"filters": pillar_data.get('filters'),
450+
}
451+
pillar_id = pillar_data.get('id', None)
452+
if pillar_id:
453+
data["id"] = pillar_id
454+
analysis_pillar = get_object_or_404(AnalysisPillar, pk=pillar_id)
455+
analysis_pillar_serializer = AnalysisPillarGqlSerializer(
456+
analysis_pillar,
457+
data=data,
458+
context=self.context
459+
)
460+
return analysis_pillar_serializer
461+
analysis_pillar_serializer = AnalysisPillarGqlSerializer(data=data, context=self.context)
462+
return analysis_pillar_serializer
463+
464+
def update(self, instance, validated_data):
465+
with transaction.atomic():
466+
if 'analysispillar_set' in validated_data:
467+
pillars = validated_data.pop('analysispillar_set')
468+
errors = {}
469+
for pillar in pillars:
470+
analysis_pillar_serializer = self.create_or_update_pillar(pillar, instance)
471+
if analysis_pillar_serializer.is_valid():
472+
analysis_pillar_serializer.save()
473+
else:
474+
errors[pillar.get('id', 'new')] = analysis_pillar_serializer.errors
475+
476+
if errors:
477+
raise serializers.ValidationError(errors)
478+
479+
return super().update(instance, validated_data)
480+
443481

444482
AnalysisCloneGqlSerializer = AnalysisCloneInputSerializer
445483

0 commit comments

Comments
 (0)