Esempio n. 1
0
 def test_created_document_is_indexed(self, index_mock):
     form = DemoMetadataForm({
         'title': 'Title',
     }, category=self.category)
     rev_form = DemoMetadataRevisionForm({
         'docclass': '1',
         'received_date': '2015-01-01',
         'created_on': '2015-01-01',
     }, category=self.category)
     save_document_forms(form, rev_form, self.category)
     self.assertEqual(index_mock.call_count, 1)
Esempio n. 2
0
 def test_created_document_is_indexed(self, index_mock):
     form = DemoMetadataForm({
         'title': 'Title',
     }, category=self.category)
     rev_form = DemoMetadataRevisionForm(
         {
             'docclass': '1',
             'received_date': '2015-01-01',
             'created_on': '2015-01-01',
         },
         category=self.category)
     save_document_forms(form, rev_form, self.category)
     self.assertEqual(index_mock.call_count, 1)
Esempio n. 3
0
    def form_valid(self, document_form, revision_form):
        """Saves both the document and it's revision."""
        doc, metadata, revision = save_document_forms(
            document_form,
            revision_form,
            self.category,
            created_by=self.request.user)

        message_text = '''You created the document
                       <a href="%(url)s">%(key)s (%(title)s)</a>'''
        message_data = {
            'url': doc.get_absolute_url(),
            'key': doc.document_key,
            'title': doc.title
        }
        notify(self.request.user, _(message_text) % message_data)

        activity_log.send(
            verb='created',
            target=None,
            action_object=doc,
            sender=None,
            actor=self.request.user)

        return HttpResponseRedirect(self.get_success_url())
Esempio n. 4
0
    def save_to_document(self):
        """Use self data to create / update the corresponding revision."""

        fields, files = self.get_document_fields()
        kwargs = {
            'category': self.category,
            'data': fields,
            'files': files
        }

        # The document was created earlier during
        # the batch import
        if self.document is None and self.revision > 0:
            self.document = Document.objects.get(document_key=self.document_key)

        metadata = getattr(self.document, 'metadata', None)
        kwargs.update({'instance': metadata})
        Form = self.category.get_metadata_form_class()
        metadata_form = Form(**kwargs)

        # If there is no such revision, the method will return None
        # which is fine.
        revision = metadata.get_revision(self.revision) if metadata else None

        kwargs.update({'instance': revision})
        RevisionForm = self.category.get_revision_form_class()
        revision_form = RevisionForm(**kwargs)

        doc, meta, rev = save_document_forms(
            metadata_form, revision_form, self.category)

        # Performs custom import action
        rev.post_trs_import(self)
Esempio n. 5
0
    def save_to_document(self):
        """Use self data to create / update the corresponding revision."""

        fields, files = self.get_document_fields()
        kwargs = {
            'category': self.category,
            'data': fields,
            'files': files
        }

        # The document was created earlier during
        # the batch import
        if self.document is None and self.revision > 0:
            self.document = Document.objects.get(document_key=self.document_key)

        metadata = getattr(self.document, 'metadata', None)
        kwargs.update({'instance': metadata})
        Form = self.category.get_metadata_form_class()
        metadata_form = Form(**kwargs)

        # If there is no such revision, the method will return None
        # which is fine.
        revision = metadata.get_revision(self.revision) if metadata else None

        kwargs.update({'instance': revision})
        RevisionForm = self.category.get_revision_form_class()
        revision_form = RevisionForm(**kwargs)

        doc, meta, rev = save_document_forms(
            metadata_form, revision_form, self.category)

        # Performs custom import action
        rev.post_trs_import(self)
Esempio n. 6
0
    def do_import(self, line):
        assert hasattr(self, 'data')

        self.line = line

        # Checking if the document already exists
        key = self.data.get('document_key', None)
        doc = get_object_or_None(Document, document_key=key)
        metadata = doc.metadata if doc else None

        # Checking if the revision already exists
        revision_num = self.data.get('revision', None)
        revision = metadata.get_revision(revision_num) if metadata and revision_num else None

        form, revision_form = self.get_forms(metadata, revision)
        try:
            if form.is_valid() and revision_form.is_valid():
                doc, metadata, revision = save_document_forms(
                    form, revision_form, self.batch.category)
                self.document = doc
                self.status = self.STATUSES.success
            else:
                errors = dict(form.errors.items() + revision_form.errors.items())
                self.errors = json.dumps(errors)
                self.status = self.STATUSES.error
        except Exception as e:
            self.errors = json.dumps({
                'An error occurred': [str(e)]
            })
            self.status = self.STATUSES.error
Esempio n. 7
0
def create_transmittal(from_category, to_category, revisions, contract_nb,
                       recipient, **form_data):
    """Create an outgoing transmittal with the given revisions."""

    # Do we have a list of revisions?
    if not isinstance(revisions, list) or len(revisions) == 0:
        raise errors.MissingRevisionsError(
            'Please provide a valid list of transmittals')

    # The "from" category must contain transmittable documents
    from_type = from_category.revision_class()
    if not issubclass(from_type, TransmittableMixin):
        raise errors.InvalidCategoryError(
            'Source category must contain transmittable documents')

    # The "destination" category must contain transmittals
    dest_type = to_category.revision_class()
    if not issubclass(dest_type, OutgoingTransmittalRevision):
        raise errors.InvalidCategoryError(
            'Destination category must contain transmittals')

    # The recipient must be linked to the "from" category
    if from_category not in recipient.linked_categories.all():
        raise errors.InvalidRecipientError(
            'Recipient is not linked to the document category')

    # Do we have valid revisions?
    for rev in revisions:
        if not isinstance(rev, TransmittableMixin):
            raise errors.InvalidRevisionsError(
                'At least one of the revisions is invalid.')

        if not rev.can_be_transmitted:
            raise errors.InvalidRevisionsError(
                'At least one of the rivisions cannot be transmitted')

        if not rev.document.category == from_category:
            raise errors.InvalidRevisionsError(
                'Some revisions are not from the correct category')

    originator = from_category.organisation.trigram
    sequential_number = find_next_trs_number(originator, recipient, contract_nb)
    form_data.update({
        'contract_number': contract_nb,
        'originator': originator,
        'recipient': recipient.id,
        'sequential_number': sequential_number,
        'created_on': timezone.now(),
        'received_date': timezone.now(),
    })

    # Let's create the transmittal, then
    trs_form = OutgoingTransmittalForm(form_data, category=to_category)
    revision_form = OutgoingTransmittalRevisionForm(form_data, category=to_category)

    with transaction.atomic():
        doc, trs, revision = save_document_forms(trs_form, revision_form, to_category)
        trs.link_to_revisions(revisions)
    return doc, trs, revision
Esempio n. 8
0
    def form_valid(self, document_form, revision_form):
        """Saves both the document and it's revision."""
        doc, metadata, revision = save_document_forms(document_form, revision_form, self.category)

        message_text = """You created the document
                       <a href="%(url)s">%(key)s (%(title)s)</a>"""
        message_data = {"url": doc.get_absolute_url(), "key": doc.document_key, "title": doc.title}
        notify(self.request.user, _(message_text) % message_data)

        return HttpResponseRedirect(self.get_success_url())
Esempio n. 9
0
 def test_revised_document_is_indexed(self, index_mock):
     form = DemoMetadataForm({
         'title': 'Title',
     }, category=self.category)
     rev_form = DemoMetadataRevisionForm({
         'docclass': '1',
         'received_date': '2015-01-01',
         'created_on': '2015-01-01',
     }, category=self.category)
     doc, meta, rev = save_document_forms(form, rev_form, self.category)
     revision = doc.latest_revision
     revision.pk = None
     revision.save()
     doc.save()
     self.assertEqual(index_mock.call_count, 2)
Esempio n. 10
0
 def test_revised_document_is_indexed(self, index_mock):
     form = DemoMetadataForm({
         'title': 'Title',
     }, category=self.category)
     rev_form = DemoMetadataRevisionForm(
         {
             'docclass': '1',
             'received_date': '2015-01-01',
             'created_on': '2015-01-01',
         },
         category=self.category)
     doc, meta, rev = save_document_forms(form, rev_form, self.category)
     revision = doc.latest_revision
     revision.pk = None
     revision.save()
     doc.save()
     self.assertEqual(index_mock.call_count, 2)
Esempio n. 11
0
    def do_import(self, line):
        assert hasattr(self, 'data')

        self.line = line

        # Checking if the document already exists
        key = self.data.get('document_key', None)
        doc = get_object_or_None(Document, document_key=key)
        metadata = doc.metadata if doc else None

        # Processing csv data to denormalize foreign keys
        self.denormalize_data(self.batch.category)
        # In case of denormalization error, we exit
        if self.status == self.STATUSES.error:
            return

        # Checking if the revision already exists
        revision_num = self.data.get('revision', None)
        revision = metadata.get_revision(
            revision_num) if metadata and revision_num else None

        form, revision_form = self.get_forms(metadata, revision)
        try:
            if form.is_valid() and revision_form.is_valid():
                # The `save_document_forms` function sends a signal triggering
                # ES indexing and schedule field rewriting. Setting
                # `rewrite_schedule` to False disables rewriting
                #  (ES indexing is still enabled)
                doc, metadata, revision = save_document_forms(
                    form,
                    revision_form,
                    self.batch.category,
                    rewrite_schedule=False)
                self.document = doc
                self.status = self.STATUSES.success
            else:
                errors = dict(
                    list(form.errors.items()) +
                    list(revision_form.errors.items()))
                self.errors = json.dumps(errors)
                self.status = self.STATUSES.error
        except Exception as e:
            self.errors = json.dumps({'An error occurred': [str(e)]})
            self.status = self.STATUSES.error
Esempio n. 12
0
    def do_import(self, line):
        assert hasattr(self, 'data')

        self.line = line

        # Checking if the document already exists
        key = self.data.get('document_key', None)
        doc = get_object_or_None(Document, document_key=key)
        metadata = doc.metadata if doc else None

        # Processing csv data to denormalize foreign keys
        self.denormalize_data(self.batch.category)
        # In case of denormalization error, we exit
        if self.status == self.STATUSES.error:
            return

        # Checking if the revision already exists
        revision_num = self.data.get('revision', None)
        revision = metadata.get_revision(revision_num) if metadata and revision_num else None

        form, revision_form = self.get_forms(metadata, revision)
        try:
            if form.is_valid() and revision_form.is_valid():
                # The `save_document_forms` function sends a signal triggering
                # ES indexing and schedule field rewriting. Setting
                # `rewrite_schedule` to False disables rewriting
                #  (ES indexing is still enabled)
                doc, metadata, revision = save_document_forms(
                    form, revision_form,
                    self.batch.category,
                    rewrite_schedule=False)
                self.document = doc
                self.status = self.STATUSES.success
            else:
                errors = dict(form.errors.items() + revision_form.errors.items())
                self.errors = json.dumps(errors)
                self.status = self.STATUSES.error
        except Exception as e:
            self.errors = json.dumps({
                'An error occurred': [str(e)]
            })
            self.status = self.STATUSES.error
Esempio n. 13
0
    def form_valid(self, document_form, revision_form):
        """Saves both the document and it's revision."""
        document, self.object, self.revision = save_document_forms(
            document_form, revision_form, self.category)

        message_text = '''You created revision %(rev)s for document
                       <a href="%(url)s">%(key)s (%(title)s)</a>'''
        message_data = {
            'rev': self.revision.name,
            'url': self.object.get_absolute_url(),
            'key': self.object.document_key,
            'title': self.object.title
        }
        notify(self.request.user, _(message_text) % message_data)

        activity_log.send(verb=Activity.VERB_CREATED,
                          target=self.revision,
                          sender=None,
                          actor=self.request.user)

        return HttpResponseRedirect(self.get_success_url())
Esempio n. 14
0
    def form_valid(self, document_form, revision_form):
        """Saves both the document and it's revision."""
        document, self.object, self.revision = save_document_forms(
            document_form, revision_form, self.category)

        message_text = '''You created revision %(rev)s for document
                       <a href="%(url)s">%(key)s (%(title)s)</a>'''
        message_data = {
            'rev': self.revision.name,
            'url': self.object.get_absolute_url(),
            'key': self.object.document_key,
            'title': self.object.title
        }
        notify(self.request.user, _(message_text) % message_data)

        activity_log.send(verb=Activity.VERB_CREATED,
                          target=self.revision,
                          sender=None,
                          actor=self.request.user)

        return HttpResponseRedirect(self.get_success_url())
Esempio n. 15
0
    def form_valid(self, document_form, revision_form):
        """Saves both the document and it's revision."""
        doc, metadata, revision = save_document_forms(document_form,
                                                      revision_form,
                                                      self.category)

        message_text = '''You created the document
                       <a href="%(url)s">%(key)s (%(title)s)</a>'''
        message_data = {
            'url': doc.get_absolute_url(),
            'key': doc.document_key,
            'title': doc.title
        }
        notify(self.request.user, _(message_text) % message_data)

        activity_log.send(verb='created',
                          target=None,
                          action_object=doc,
                          sender=None,
                          actor=self.request.user)

        return HttpResponseRedirect(self.get_success_url())
Esempio n. 16
0
 def form_valid(self, document_form, revision_form):
     """Saves both the document and it's revision."""
     document, self.object, self.revision = save_document_forms(
         document_form, revision_form, self.category)
     return HttpResponseRedirect(self.get_success_url())
Esempio n. 17
0
def create_transmittal(from_category, to_category, revisions, contract_nb,
                       recipient, **form_data):
    """Create an outgoing transmittal with the given revisions."""

    # Do we have a list of revisions?
    if not isinstance(revisions, list) or len(revisions) == 0:
        raise errors.MissingRevisionsError(
            'Please provide a valid list of transmittals')

    # The "from" category must contain transmittable documents
    from_type = from_category.revision_class()
    if not issubclass(from_type, TransmittableMixin):
        raise errors.InvalidCategoryError(
            'Source category must contain transmittable documents')

    # The "destination" category must contain transmittals
    dest_type = to_category.revision_class()
    if not issubclass(dest_type, OutgoingTransmittalRevision):
        raise errors.InvalidCategoryError(
            'Destination category must contain transmittals')

    # The recipient must be linked to the "from" category
    if from_category not in recipient.linked_categories.all():
        raise errors.InvalidRecipientError(
            'Recipient is not linked to the document category')

    # The 'contract_nb' must belong to the contracts linked by the category
    cat_contracts = from_category.contracts.values_list('number', flat=True)
    if contract_nb not in cat_contracts:
        raise errors.InvalidContractNumberError(
            'Contract number is not linked to the document category')

    # Do we have valid revisions?
    for rev in revisions:
        if not isinstance(rev, TransmittableMixin):
            raise errors.InvalidRevisionsError(
                'At least one of the revisions is invalid.')

        if not rev.can_be_transmitted_to_recipient(recipient=recipient):
            raise errors.InvalidRevisionsError(
                'At least one of the revisions cannot be transmitted')

        if not rev.document.category == from_category:
            raise errors.InvalidRevisionsError(
                'Some revisions are not from the correct category')

    originator = from_category.organisation.trigram
    sequential_number = find_next_trs_number(originator, recipient,
                                             contract_nb)
    form_data.update({
        'sequential_number': sequential_number,
        'created_on': timezone.now(),
        'received_date': timezone.now(),
    })

    # Some fields are excluded from the form, so we have to
    # provide a base instance instead
    base_instance = OutgoingTransmittal(
        revisions_category=from_category,
        contract_number=contract_nb,
        originator=originator,
        recipient=recipient,
    )

    # Let's create the transmittal, then
    trs_form = OutgoingTransmittalForm(form_data,
                                       instance=base_instance,
                                       category=to_category)
    revision_form = OutgoingTransmittalRevisionForm(form_data,
                                                    category=to_category)

    with transaction.atomic():
        doc, trs, revision = save_document_forms(trs_form, revision_form,
                                                 to_category)
        trs.link_to_revisions(revisions)

    signals.transmittal_created.send(document=doc,
                                     metadata=trs,
                                     revision=revision,
                                     sender=trs.__class__)
    return doc, trs, revision
Esempio n. 18
0
    def save(self):
        """Save transmittal data in db."""

        # We import those here because we need to make sure that
        # the values_lists have already been populated
        from transmittals.models import TrsRevision
        from transmittals.forms import TransmittalForm, TransmittalRevisionForm

        # Build the list of related documents
        keys = []
        for line in self:
            key = line.csv_data['document_key']
            if key not in keys:
                keys.append(key)
        related_documents = Document.objects \
            .filter(document_key__in=keys) \
            .values_list('id', flat=True)

        data = {
            'contractor': self.contractor,
            'tobechecked_dir': self.tobechecked_dir,
            'accepted_dir': self.accepted_dir,
            'rejected_dir': self.rejected_dir,
            'contract_number': self.contract_number,
            'originator': self.originator,
            'recipient': self.recipient,
            'sequential_number': self.sequential_number,
            'status': 'tobechecked',
            'related_documents': list(related_documents),
            'revision_date': datetime.date.today(),
            'received_date': datetime.date.today(),
            'created_on': datetime.date.today(),
        }

        # The csv file is linked in the "native_file" field
        native_file = File(open(self.csv_fullname))
        files = {
            'native_file': native_file,
        }

        # Use document forms to create the Transmittal
        form = TransmittalForm(data=data, category=self.trs_category)
        revision_form = TransmittalRevisionForm(data=data,
                                                files=files,
                                                category=self.trs_category)
        doc, transmittal, revision = save_document_forms(form,
                                                         revision_form,
                                                         self.trs_category,
                                                         is_indexable=False)

        native_file.close()

        nb_line = 0
        for line in self:
            data = line.cleaned_data
            metadata = line.get_metadata()
            document = getattr(metadata, 'document', None)

            if nb_line % 100 == 0:
                logger.info('Importing line {} ({})'.format(
                    nb_line + 1, data['document_key']))

            # Is this a revision creation or are we editing an existing one?
            if metadata is None:
                is_new_revision = True
            else:
                latest_revision = metadata.latest_revision.revision
                is_new_revision = bool(int(data['revision']) > latest_revision)

            pdf_file = File(open(line.pdf_fullname, 'rb'))
            native_file = line.native_fullname
            if native_file:
                native_file = File(open(native_file, 'rb'))

            data.update({
                'transmittal': transmittal,
                'document': document,
                'is_new_revision': is_new_revision,
                'category': self.doc_category,
                'pdf_file': pdf_file,
                'native_file': native_file,
                'sequential_number': line.sequential_number,  # XXX Hack
            })
            TrsRevision.objects.create(**data)
            nb_line += 1

            pdf_file.close()
            if hasattr(native_file, 'close'):
                native_file.close()
Esempio n. 19
0
def create_transmittal(from_category, to_category, revisions, contract_nb,
                       recipient, **form_data):
    """Create an outgoing transmittal with the given revisions."""

    # Do we have a list of revisions?
    if not isinstance(revisions, list) or len(revisions) == 0:
        raise errors.MissingRevisionsError(
            'Please provide a valid list of transmittals')

    # The "from" category must contain transmittable documents
    from_type = from_category.revision_class()
    if not issubclass(from_type, TransmittableMixin):
        raise errors.InvalidCategoryError(
            'Source category must contain transmittable documents')

    # The "destination" category must contain transmittals
    dest_type = to_category.revision_class()
    if not issubclass(dest_type, OutgoingTransmittalRevision):
        raise errors.InvalidCategoryError(
            'Destination category must contain transmittals')

    # The recipient must be linked to the "from" category
    if from_category not in recipient.linked_categories.all():
        raise errors.InvalidRecipientError(
            'Recipient is not linked to the document category')

    # The 'contract_nb' must belong to the contracts linked by the category
    cat_contracts = from_category.contracts.values_list('number', flat=True)
    if contract_nb not in cat_contracts:
        raise errors.InvalidContractNumberError(
            'Contract number is not linked to the document category')

    # Do we have valid revisions?
    for rev in revisions:
        if not isinstance(rev, TransmittableMixin):
            raise errors.InvalidRevisionsError(
                'At least one of the revisions is invalid.')

        if not rev.can_be_transmitted_to_recipient(recipient=recipient):
            raise errors.InvalidRevisionsError(
                'At least one of the revisions cannot be transmitted')

        if not rev.document.category == from_category:
            raise errors.InvalidRevisionsError(
                'Some revisions are not from the correct category')

    originator = from_category.organisation.trigram
    sequential_number = find_next_trs_number(originator, recipient, contract_nb)
    form_data.update({
        'sequential_number': sequential_number,
        'created_on': timezone.now(),
        'received_date': timezone.now(),
    })

    # Some fields are excluded from the form, so we have to
    # provide a base instance instead
    base_instance = OutgoingTransmittal(
        revisions_category=from_category,
        contract_number=contract_nb,
        originator=originator,
        recipient=recipient,
    )

    # Let's create the transmittal, then
    trs_form = OutgoingTransmittalForm(
        form_data, instance=base_instance, category=to_category)
    revision_form = OutgoingTransmittalRevisionForm(
        form_data, category=to_category)

    with transaction.atomic():
        doc, trs, revision = save_document_forms(trs_form, revision_form, to_category)
        trs.link_to_revisions(revisions)

    signals.transmittal_created.send(
        document=doc,
        metadata=trs,
        revision=revision,
        sender=trs.__class__)
    return doc, trs, revision
Esempio n. 20
0
    def save(self):
        """Save transmittal data in db."""

        # We import those here because we need to make sure that
        # the values_lists have already been populated
        from transmittals.models import TrsRevision
        from transmittals.forms import TransmittalForm, TransmittalRevisionForm

        # Build the list of related documents
        keys = []
        for line in self:
            key = line.csv_data['document_key']
            if key not in keys:
                keys.append(key)
        related_documents = Document.objects \
            .filter(document_key__in=keys) \
            .values_list('id', flat=True)

        data = {
            'contractor': self.contractor,
            'tobechecked_dir': self.tobechecked_dir,
            'accepted_dir': self.accepted_dir,
            'rejected_dir': self.rejected_dir,
            'contract_number': self.contract_number,
            'originator': self.originator,
            'recipient': self.recipient,
            'sequential_number': self.sequential_number,
            'status': 'tobechecked',
            'related_documents': list(related_documents),
            'revision_date': datetime.date.today(),
            'received_date': datetime.date.today(),
            'created_on': datetime.date.today(),
        }

        # The csv file is linked in the "native_file" field
        native_file = File(open(self.csv_fullname))
        files = {
            'native_file': native_file,
        }

        # Use document forms to create the Transmittal
        form = TransmittalForm(data=data, category=self.trs_category)
        revision_form = TransmittalRevisionForm(
            data=data, files=files, category=self.trs_category)
        doc, transmittal, revision = save_document_forms(
            form, revision_form, self.trs_category, is_indexable=False)

        native_file.close()

        nb_line = 0
        for line in self:
            data = line.cleaned_data
            metadata = line.get_metadata()
            document = getattr(metadata, 'document', None)

            if nb_line % 100 == 0:
                logger.info('Importing line {} ({})'.format(
                    nb_line + 1, data['document_key']))

            # Is this a revision creation or are we editing an existing one?
            if metadata is None:
                is_new_revision = True
            else:
                latest_revision = metadata.latest_revision.revision
                is_new_revision = bool(int(data['revision']) > latest_revision)

            pdf_file = File(open(line.pdf_fullname))
            native_file = line.native_fullname
            if native_file:
                native_file = File(open(native_file))

            data.update({
                'transmittal': transmittal,
                'document': document,
                'is_new_revision': is_new_revision,
                'category': self.doc_category,
                'pdf_file': pdf_file,
                'native_file': native_file,
                'sequential_number': line.sequential_number,  # XXX Hack
            })
            TrsRevision.objects.create(**data)
            nb_line += 1

            pdf_file.close()
            if hasattr(native_file, 'close'):
                native_file.close()
Esempio n. 21
0
 def form_valid(self, document_form, revision_form):
     """Saves both the document and it's revision."""
     document, self.object, self.revision = save_document_forms(
         document_form, revision_form, self.category
     )
     return HttpResponseRedirect(self.get_success_url())