diff --git a/boranga/components/occurrence/api.py b/boranga/components/occurrence/api.py
index 628342e3..383f8605 100644
--- a/boranga/components/occurrence/api.py
+++ b/boranga/components/occurrence/api.py
@@ -76,6 +76,8 @@
Location,
ObserverDetail,
OccurrenceReportDocument,
+ OCRConservationThreat,
+ OccurrenceReportUserAction,
)
from boranga.components.occurrence.serializers import(
ListOccurrenceReportSerializer,
@@ -97,6 +99,8 @@
OccurrenceReportLogEntrySerializer,
OccurrenceReportDocumentSerializer,
SaveOccurrenceReportDocumentSerializer,
+ OCRConservationThreatSerializer,
+ SaveOCRConservationThreatSerializer,
)
from boranga.components.occurrence.utils import (
@@ -1076,6 +1080,25 @@ def documents(self, request, *args, **kwargs):
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))
+
+ @detail_route(methods=['GET',], detail=True)
+ def threats(self, request, *args, **kwargs):
+ try:
+ instance = self.get_object()
+ # TODO Do we need to sort the threats for external user (similar like documents)
+ qs = instance.ocr_threats.all()
+ qs = qs.order_by('-date_observed')
+ serializer = OCRConservationThreatSerializer(qs,many=True, context={'request':request})
+ return Response(serializer.data)
+ except serializers.ValidationError:
+ print(traceback.print_exc())
+ raise
+ except ValidationError as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(repr(e.error_dict))
+ except Exception as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(str(e))
class ObserverDetailViewSet(viewsets.ModelViewSet):
@@ -1157,32 +1180,118 @@ def reinstate(self, request, *args, **kwargs):
raise serializers.ValidationError(str(e))
def update(self, request, *args, **kwargs):
+ try:
+ with transaction.atomic():
+ instance = self.get_object()
+ serializer = SaveOccurrenceReportDocumentSerializer(instance, data=json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ instance.add_documents(request)
+ instance.uploaded_by = request.user.id
+ instance.save()
+ return Response(serializer.data)
+ except Exception as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(str(e))
+
+
+ def create(self, request, *args, **kwargs):
+ try:
+ with transaction.atomic():
+ serializer = SaveOccurrenceReportDocumentSerializer(data= json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception = True)
+ instance = serializer.save()
+ instance.add_documents(request)
+ instance.uploaded_by = request.user.id
+ instance.save()
+ return Response(serializer.data)
+ except serializers.ValidationError:
+ print(traceback.print_exc())
+ raise
+ except ValidationError as e:
+ if hasattr(e,'error_dict'):
+ raise serializers.ValidationError(repr(e.error_dict))
+ else:
+ if hasattr(e,'message'):
+ raise serializers.ValidationError(e.message)
+ except Exception as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(str(e))
+
+
+class OCRConservationThreatViewSet(viewsets.ModelViewSet):
+ queryset = OCRConservationThreat.objects.all().order_by('id')
+ serializer_class = OCRConservationThreatSerializer
+
+ @detail_route(methods=['GET',], detail=True)
+ def discard(self, request, *args, **kwargs):
try:
instance = self.get_object()
- serializer = SaveOccurrenceReportDocumentSerializer(instance, data=json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception=True)
- serializer.save()
- instance.add_documents(request)
- instance.uploaded_by = request.user.id
+ instance.visible = False
instance.save()
+ if instance.occurrence_report:
+ instance.occurrence_report.log_user_action(OccurrenceReportUserAction.ACTION_DISCARD_THREAT.format(instance.threat_number,instance.occurrence_report.occurrence_report_number),request)
+ serializer = self.get_serializer(instance)
return Response(serializer.data)
+ except serializers.ValidationError:
+ print(traceback.print_exc())
+ raise
+ except ValidationError as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(repr(e.error_dict))
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))
-
- def create(self, request, *args, **kwargs):
+ @detail_route(methods=['GET',], detail=True)
+ def reinstate(self, request, *args, **kwargs):
try:
- serializer = SaveOccurrenceReportDocumentSerializer(data= json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception = True)
- instance = serializer.save()
- instance.add_documents(request)
- instance.uploaded_by = request.user.id
+ instance = self.get_object()
+ instance.visible = True
instance.save()
+ if instance.occurrence_report:
+ instance.occurrence_report.log_user_action(OccurrenceReportUserAction.ACTION_REINSTATE_THREAT.format(instance.threat_number,instance.occurrence_report.occurrence_report_number),request)
+ serializer = self.get_serializer(instance)
return Response(serializer.data)
except serializers.ValidationError:
print(traceback.print_exc())
raise
+ except ValidationError as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(repr(e.error_dict))
+ except Exception as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(str(e))
+
+ def update(self, request, *args, **kwargs):
+ try:
+ with transaction.atomic():
+ instance = self.get_object()
+ serializer = SaveOCRConservationThreatSerializer(instance, data=json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ if instance.occurrence_report:
+ instance.occurrence_report.log_user_action(OccurrenceReportUserAction.ACTION_UPDATE_THREAT.format(instance.threat_number,instance.occurrence_report.occurrence_report_number),request)
+ serializer = self.get_serializer(instance)
+ return Response(serializer.data)
+ except Exception as e:
+ print(traceback.print_exc())
+ raise serializers.ValidationError(str(e))
+
+
+ def create(self, request, *args, **kwargs):
+ try:
+ with transaction.atomic():
+ serializer = SaveOCRConservationThreatSerializer(data= json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception = True)
+ instance = serializer.save()
+ if instance.occurrence_report:
+ instance.occurrence_report.log_user_action(OccurrenceReportUserAction.ACTION_ADD_THREAT.format(instance.threat_number,instance.occurrence_report.occurrence_report_number),request)
+ serializer = self.get_serializer(instance)
+ return Response(serializer.data)
+ except serializers.ValidationError:
+ print(traceback.print_exc())
+ raise
except ValidationError as e:
if hasattr(e,'error_dict'):
raise serializers.ValidationError(repr(e.error_dict))
diff --git a/boranga/components/occurrence/models.py b/boranga/components/occurrence/models.py
index cd3c9e9f..08d49a03 100644
--- a/boranga/components/occurrence/models.py
+++ b/boranga/components/occurrence/models.py
@@ -38,6 +38,11 @@
GroupType,
Species,
Community,
+ ThreatCategory,
+ ThreatAgent,
+ PotentialImpact,
+ PotentialThreatOnset,
+ CurrentImpact,
)
from boranga.components.conservation_status.models import ConservationStatus
from boranga.ordered_model import OrderedModel
@@ -423,6 +428,18 @@ class OccurrenceReportUserAction(UserAction):
COMMENT_REFERRAL = "Referral {} for occurrence report proposal {} has been commented by {}"
CONCLUDE_REFERRAL = "Referral {} for occurrence report proposal {} has been concluded by {}"
+ # Document
+ ACTION_ADD_DOCUMENT= "Document {} added for occurrence report {}"
+ ACTION_UPDATE_DOCUMENT= "Document {} updated for occurrence report {}"
+ ACTION_DISCARD_DOCUMENT= "Document {} discarded for occurrence report {}"
+ ACTION_REINSTATE_DOCUMENT= "Document {} reinstated for occurrence report {}"
+
+ # Threat
+ ACTION_ADD_THREAT= "Threat {} added for occurrence report {}"
+ ACTION_UPDATE_THREAT= "Threat {} updated for occurrence report {}"
+ ACTION_DISCARD_THREAT= "Threat {} discarded for occurrence report {}"
+ ACTION_REINSTATE_THREAT= "Threat {} reinstated for occurrence report {}"
+
class Meta:
app_label = 'boranga'
@@ -1280,3 +1297,46 @@ def add_documents(self, request):
except:
raise
return
+
+class OCRConservationThreat(models.Model):
+ """
+ Threat for a occurrence_report in a particular location.
+
+ NB: Maybe make many to many
+
+ Has a:
+ - occurrence_report
+ Used for:
+ - OccurrenceReport
+ Is:
+ - Table
+ """
+ occurrence_report = models.ForeignKey(OccurrenceReport, on_delete=models.CASCADE, null=True, blank=True , related_name="ocr_threats")
+ threat_number = models.CharField(max_length=9, blank=True, default='')
+ threat_category = models.ForeignKey(ThreatCategory, on_delete=models.CASCADE, default=None, null=True, blank=True)
+ threat_agent = models.ForeignKey(ThreatAgent, on_delete=models.SET_NULL, default=None, null=True, blank=True)
+ current_impact = models.ForeignKey(CurrentImpact, on_delete=models.SET_NULL, default=None, null=True, blank=True)
+ potential_impact = models.ForeignKey(PotentialImpact, on_delete=models.SET_NULL, default=None, null=True, blank=True)
+ potential_threat_onset = models.ForeignKey(PotentialThreatOnset, on_delete=models.SET_NULL, default=None, null=True, blank=True)
+ comment = models.CharField(max_length=512,
+ default="None")
+ date_observed = models.DateField(blank =True, null=True)
+ visible = models.BooleanField(default=True) # to prevent deletion, hidden and still be available in history
+
+
+ class Meta:
+ app_label = 'boranga'
+
+ def __str__(self):
+ return str(self.id) # TODO: is the most appropriate?
+
+ def save(self, *args, **kwargs):
+ super(OCRConservationThreat, self).save(*args,**kwargs)
+ if self.threat_number == '':
+ new_threat_id = 'T{}'.format(str(self.pk))
+ self.threat_number = new_threat_id
+ self.save()
+
+ @property
+ def source(self):
+ return self.occurrence_report.id
diff --git a/boranga/components/occurrence/serializers.py b/boranga/components/occurrence/serializers.py
index d4383e6d..11acd886 100644
--- a/boranga/components/occurrence/serializers.py
+++ b/boranga/components/occurrence/serializers.py
@@ -29,6 +29,7 @@
OccurrenceReportLogEntry,
OccurrenceReportUserAction,
OccurrenceReportDocument,
+ OCRConservationThreat,
)
from boranga.components.users.serializers import UserSerializer
@@ -941,3 +942,74 @@ class Meta:
'document_sub_category',
)
+
+class OCRConservationThreatSerializer(serializers.ModelSerializer):
+ threat_category = serializers.SerializerMethodField()
+ threat_agent = serializers.SerializerMethodField()
+ current_impact_name = serializers.SerializerMethodField()
+ potential_impact_name = serializers.SerializerMethodField()
+ potential_threat_onset_name = serializers.SerializerMethodField()
+ class Meta:
+ model = OCRConservationThreat
+ fields = (
+ 'id',
+ 'threat_number',
+ 'threat_category_id',
+ 'threat_category',
+ 'threat_agent',
+ 'threat_agent_id',
+ 'current_impact',
+ 'current_impact_name',
+ 'potential_impact',
+ 'potential_impact_name',
+ 'potential_threat_onset',
+ 'potential_threat_onset_name',
+ 'comment',
+ 'date_observed',
+ 'source',
+ 'occurrence_report',
+ 'visible',
+ )
+ read_only_fields = ('id','threat_number',)
+
+ def get_threat_category(self,obj):
+ if obj.threat_category:
+ return obj.threat_category.name
+
+ def get_threat_agent(self,obj):
+ if obj.threat_agent:
+ return obj.threat_agent.name
+
+ def get_current_impact_name(self,obj):
+ if obj.current_impact:
+ return obj.current_impact.name
+
+ def get_potential_impact_name(self,obj):
+ if obj.potential_impact:
+ return obj.potential_impact.name
+
+ def get_potential_threat_onset_name(self,obj):
+ if obj.potential_threat_onset:
+ return obj.potential_threat_onset.name
+
+
+class SaveOCRConservationThreatSerializer(serializers.ModelSerializer):
+
+ threat_category_id = serializers.IntegerField(required=False, allow_null=True, write_only= True)
+ threat_agent_id = serializers.IntegerField(required=False, allow_null=True, write_only= True)
+ date_observed = serializers.DateField(format='%Y-%m-%d', required=False, allow_null = True)
+
+ class Meta:
+ model = OCRConservationThreat
+ fields = (
+ 'id',
+ 'occurrence_report',
+ 'threat_category_id',
+ 'threat_agent_id',
+ 'comment',
+ 'current_impact',
+ 'potential_impact',
+ 'potential_threat_onset',
+ 'date_observed',
+ )
+
diff --git a/boranga/components/species_and_communities/api.py b/boranga/components/species_and_communities/api.py
index fdf90248..f984c50f 100755
--- a/boranga/components/species_and_communities/api.py
+++ b/boranga/components/species_and_communities/api.py
@@ -1910,13 +1910,14 @@ def reinstate(self, request, *args, **kwargs):
def update(self, request, *args, **kwargs):
try:
- instance = self.get_object()
- serializer = SaveSpeciesDocumentSerializer(instance, data=json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception=True)
- serializer.save()
- instance.add_documents(request)
- instance.species.log_user_action(SpeciesUserAction.ACTION_UPDATE_DOCUMENT.format(instance.document_number,instance.species.species_number),request)
- return Response(serializer.data)
+ with transaction.atomic():
+ instance = self.get_object()
+ serializer = SaveSpeciesDocumentSerializer(instance, data=json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ instance.add_documents(request)
+ instance.species.log_user_action(SpeciesUserAction.ACTION_UPDATE_DOCUMENT.format(instance.document_number,instance.species.species_number),request)
+ return Response(serializer.data)
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))
@@ -1924,12 +1925,13 @@ def update(self, request, *args, **kwargs):
def create(self, request, *args, **kwargs):
try:
- serializer = SaveSpeciesDocumentSerializer(data= json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception = True)
- instance = serializer.save()
- instance.add_documents(request)
- instance.species.log_user_action(SpeciesUserAction.ACTION_ADD_DOCUMENT.format(instance.document_number,instance.species.species_number),request)
- return Response(serializer.data)
+ with transaction.atomic():
+ serializer = SaveSpeciesDocumentSerializer(data= json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception = True)
+ instance = serializer.save()
+ instance.add_documents(request)
+ instance.species.log_user_action(SpeciesUserAction.ACTION_ADD_DOCUMENT.format(instance.document_number,instance.species.species_number),request)
+ return Response(serializer.data)
except serializers.ValidationError:
print(traceback.print_exc())
raise
@@ -2005,13 +2007,14 @@ def reinstate(self, request, *args, **kwargs):
def update(self, request, *args, **kwargs):
try:
- instance = self.get_object()
- serializer = SaveCommunityDocumentSerializer(instance, data=json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception=True)
- serializer.save()
- instance.add_documents(request)
- instance.community.log_user_action(CommunityUserAction.ACTION_UPDATE_DOCUMENT.format(instance.document_number,instance.community.community_number),request)
- return Response(serializer.data)
+ with transaction.atomic():
+ instance = self.get_object()
+ serializer = SaveCommunityDocumentSerializer(instance, data=json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ instance.add_documents(request)
+ instance.community.log_user_action(CommunityUserAction.ACTION_UPDATE_DOCUMENT.format(instance.document_number,instance.community.community_number),request)
+ return Response(serializer.data)
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))
@@ -2019,12 +2022,13 @@ def update(self, request, *args, **kwargs):
def create(self, request, *args, **kwargs):
try:
- serializer = SaveCommunityDocumentSerializer(data= json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception = True)
- instance = serializer.save()
- instance.add_documents(request)
- instance.community.log_user_action(CommunityUserAction.ACTION_ADD_DOCUMENT.format(instance.document_number,instance.community.community_number),request)
- return Response(serializer.data)
+ with transaction.atomic():
+ serializer = SaveCommunityDocumentSerializer(data= json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception = True)
+ instance = serializer.save()
+ instance.add_documents(request)
+ instance.community.log_user_action(CommunityUserAction.ACTION_ADD_DOCUMENT.format(instance.document_number,instance.community.community_number),request)
+ return Response(serializer.data)
except serializers.ValidationError:
print(traceback.print_exc())
raise
@@ -2127,7 +2131,6 @@ def reinstate(self, request, *args, **kwargs):
elif instance.community:
instance.community.log_user_action(CommunityUserAction.ACTION_REINSTATE_THREAT.format(instance.threat_number,instance.community.community_number),request)
serializer = self.get_serializer(instance)
- serializer = self.get_serializer(instance)
return Response(serializer.data)
except serializers.ValidationError:
print(traceback.print_exc())
@@ -2141,16 +2144,17 @@ def reinstate(self, request, *args, **kwargs):
def update(self, request, *args, **kwargs):
try:
- instance = self.get_object()
- serializer = SaveConservationThreatSerializer(instance, data=json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception=True)
- serializer.save()
- if instance.species:
- instance.species.log_user_action(SpeciesUserAction.ACTION_UPDATE_THREAT.format(instance.threat_number,instance.species.species_number),request)
- elif instance.community:
- instance.community.log_user_action(CommunityUserAction.ACTION_UPDATE_THREAT.format(instance.threat_number,instance.community.community_number),request)
- serializer = self.get_serializer(instance)
- return Response(serializer.data)
+ with transaction.atomic():
+ instance = self.get_object()
+ serializer = SaveConservationThreatSerializer(instance, data=json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception=True)
+ serializer.save()
+ if instance.species:
+ instance.species.log_user_action(SpeciesUserAction.ACTION_UPDATE_THREAT.format(instance.threat_number,instance.species.species_number),request)
+ elif instance.community:
+ instance.community.log_user_action(CommunityUserAction.ACTION_UPDATE_THREAT.format(instance.threat_number,instance.community.community_number),request)
+ serializer = self.get_serializer(instance)
+ return Response(serializer.data)
except Exception as e:
print(traceback.print_exc())
raise serializers.ValidationError(str(e))
@@ -2158,15 +2162,16 @@ def update(self, request, *args, **kwargs):
def create(self, request, *args, **kwargs):
try:
- serializer = SaveConservationThreatSerializer(data= json.loads(request.data.get('data')))
- serializer.is_valid(raise_exception = True)
- instance = serializer.save()
- if instance.species:
- instance.species.log_user_action(SpeciesUserAction.ACTION_ADD_THREAT.format(instance.threat_number,instance.species.species_number),request)
- elif instance.community:
- instance.community.log_user_action(CommunityUserAction.ACTION_ADD_THREAT.format(instance.threat_number,instance.community.community_number),request)
- serializer = self.get_serializer(instance)
- return Response(serializer.data)
+ with transaction.atomic():
+ serializer = SaveConservationThreatSerializer(data= json.loads(request.data.get('data')))
+ serializer.is_valid(raise_exception = True)
+ instance = serializer.save()
+ if instance.species:
+ instance.species.log_user_action(SpeciesUserAction.ACTION_ADD_THREAT.format(instance.threat_number,instance.species.species_number),request)
+ elif instance.community:
+ instance.community.log_user_action(CommunityUserAction.ACTION_ADD_THREAT.format(instance.threat_number,instance.community.community_number),request)
+ serializer = self.get_serializer(instance)
+ return Response(serializer.data)
except serializers.ValidationError:
print(traceback.print_exc())
raise
diff --git a/boranga/frontend/boranga/src/api.js b/boranga/frontend/boranga/src/api.js
index c9c9510f..a6fcb043 100644
--- a/boranga/frontend/boranga/src/api.js
+++ b/boranga/frontend/boranga/src/api.js
@@ -142,6 +142,7 @@ module.exports = {
occurrence_report:"/api/occurrence_report",
observer_detail:"/api/observer_detail.json",
occurrence_report_documents:"/api/occurrence_report_documents.json",
+ ocr_threat:"/api/ocr_threat.json",
//approvals_paginated:"/api/approvals/user_list_paginated/?format=datatables",
//compliances_paginated:"/api/compliances/user_list_paginated/?format=datatables",
diff --git a/boranga/frontend/boranga/src/components/common/occurrence/ocr_documents.vue b/boranga/frontend/boranga/src/components/common/occurrence/ocr_documents.vue
index 950ab794..733b2dc4 100644
--- a/boranga/frontend/boranga/src/components/common/occurrence/ocr_documents.vue
+++ b/boranga/frontend/boranga/src/components/common/occurrence/ocr_documents.vue
@@ -4,7 +4,7 @@
(Do not upload Management or Recovery Plans here)