def update_status_and_send_notifications(attachment): """Update document status and send notifications is it is required""" not_run_files = DocumentFileAttachment.objects.filter( document=attachment.document, security_scan_status='NOT RUN', is_removed=False) in_progress_files = DocumentFileAttachment.objects.filter( document=attachment.document, security_scan_status='IN PROGRESS', is_removed=False) failed_files = DocumentFileAttachment.objects.filter( document=attachment.document, security_scan_status='FAIL', is_removed=False) if len(not_run_files) > 0 or len(in_progress_files) > 0: # The verdict is not in yet return user = attachment.document.update_user if user is None: user = attachment.document.create_user if len(failed_files) > 0: attachment.document.status = DocumentStatus.objects.get( status="Security Scan Failed") attachment.document.save() elif attachment.document.status.status == "Pending Submission": submitted_status = DocumentStatus.objects.get(status="Submitted") attachment.document.status = submitted_status attachment.document.save() DocumentService.send_notification(attachment.document, user)
def perform_update(self, serializer): user = self.request.user document = serializer.save() DocumentService.create_history(document) DocumentService.send_notification(document, user)
def save(self, **kwargs): super().save(**kwargs) document = Document.objects.get(id=self.instance.id) request = self.context['request'] attachments_to_be_removed = request.data.get( 'attachments_to_be_removed') if attachments_to_be_removed: DocumentService.delete_attachments( document_id=document.id, attachment_ids=attachments_to_be_removed) files = request.data.get('attachments') if files: for file in files: DocumentFileAttachment.objects.create( document=document, create_user=document.create_user, **file) if 'record_numbers' in request.data: record_numbers_dict = { record_number.get('id'): record_number for record_number in request.data.get('record_numbers') if record_number } for attachment in document.attachments: attachment.record_number = \ record_numbers_dict[attachment.id].get('value') attachment.save() if document.status.status in ['Draft', 'Submitted']: comment = request.data.get('comment') if comment and comment.strip(): document_comment = DocumentComment.objects.filter( document=document).first() if document_comment: document_comment.comment = comment document_comment.update_timestamp = datetime.now() document_comment.update_user = request.user document_comment.save() else: DocumentComment.objects.create( document=document, comment=comment, create_user=request.user, create_timestamp=datetime.now(), privileged_access=False) return document
def perform_create(self, serializer): user = self.request.user document = serializer.save() DocumentService.create_history(document) if document.status.status != 'Draft': document.status = DocumentStatus.objects.get( status='Pending Submission') document.save() DocumentService.send_notification(document, user)
def perform_update(self, serializer): user = self.request.user document = serializer.save() DocumentService.create_history(document) files = document.attachments.filter(security_scan_status='NOT RUN') if files and document.status.status == 'Submitted': document.status = DocumentStatus.objects.get( status='Pending Submission') document.save() for file in files: SecurityScan.send_scan_request(file) DocumentService.send_notification(document, user)
def destroy(self): """ Delete function to mark the document as cancelled. Also, sets the file attachments as removed (including sending a request to minio to delete the actual files) """ document = self.instance if document.status not in DocumentStatus.objects.filter( status__in=["Draft", "Security Scan Failed"]): raise serializers.ValidationError( {'readOnly': "Cannot delete a submission that's not a draft."}) attachments_to_be_removed = DocumentFileAttachment.objects.filter( document=document, is_removed=False).values_list('id') if attachments_to_be_removed: DocumentService.delete_attachments( document_id=document.id, attachment_ids=attachments_to_be_removed) document.status = DocumentStatus.objects.get(status="Cancelled") document.save()
def validate(self, data): request = self.context['request'] document = self.instance status = data.get('status') if status.status in ["Received", "Archived"] and \ not request.user.has_perm('DOCUMENTS_GOVERNMENT_REVIEW'): raise serializers.ValidationError({ 'invalidStatus': "You do not have permission to set " "the status to `{}`.".format(status.status) }) if not DocumentService.validate_status(document.status, status): if status.status == 'Draft': raise serializers.ValidationError({ 'invalidStatus': "The submission cannot be rescinded " "because it has been marked as received " "by a Government user. " "Please refresh your browser." }) raise serializers.ValidationError({ 'invalidStatus': "Submission cannot be set to {} as it " "currently has a status of {}.".format(status.status, document.status.status) }) if document.status.status != "Draft" and \ document.status.status != "Security Scan Failed": # if there's a key that's not about updating the status or user # invalidate the request as we're not allowing modifications # to other fields for key in data: if key not in ('status', 'update_user'): raise serializers.ValidationError({ 'readOnly': "Cannot update other fields unless the " "document is in draft." }) attachments = request.data.get('attachments') if attachments: for attachment in attachments: if '?' in attachment['url']: raise serializers.ValidationError( {'attachments': 'should not contain query string'}) if status.status == "Submitted": if document.type.the_type == "Evidence": if 'milestone' in request.data and \ not request.data.get('milestone'): raise serializers.ValidationError({ 'milestone': "Please indicate the Milestone(s) to " "which the submission relates." }) current_attachments = document.attachments attachments = request.data.get('attachments') if not attachments and not current_attachments: raise serializers.ValidationError({ 'attachments': "Please attach at least one file" " before submitting." }) attachments_to_be_removed = request.data.get( 'attachments_to_be_removed') for attachment in current_attachments: if attachment.security_scan_status == 'FAIL' and \ not attachment.is_removed and \ attachment.id not in attachments_to_be_removed: raise serializers.ValidationError({ 'attachments': "An attachment failing security scan " "is preventing this {} from being " "submitted".format(document.type.description) }) if attachment.security_scan_status == 'IN PROGRESS' and \ not attachment.is_removed and \ attachment.id not in attachments_to_be_removed: raise serializers.ValidationError({ 'attachments': "Please wait until the attachments " "completed security scan before " "submitting." }) if status.status == "Archived": record_numbers = request.data.get('record_numbers', []) record_numbers_dict = { record_number.get('id'): record_number for record_number in record_numbers if record_number } errors = {} # go through each file attached to the document and make sure # that trim numbers are provided for attachment in document.attachments: if not record_numbers_dict.get(attachment.id): filename = (attachment.filename[:50] + '...') \ if len(attachment.filename) > 50 \ else attachment.filename errors[attachment.filename] = \ "Please provide a TRIM Record # for {}".format( filename ) if errors: raise serializers.ValidationError(errors) return data
def remove_orphans(): print('starting orphan removal') DocumentService.remove_orphans()