<reponame>PhaseDMS/phase
from django import forms
from django.urls import reverse

from documents.forms.utils import DocumentDownloadForm
from django.utils.translation import ugettext_lazy as _
from crispy_forms.layout import Layout, Field

from default_documents.layout import DocumentFieldset, DateField, PropertyLayout

from documents.forms.models import GenericBaseDocumentForm
from reviews.forms import ReviewFormMixin
from transmittals.layout import RelatedRevisionsLayout, OutgoingTrsLayout
from transmittals.models import (
    Transmittal,
    TransmittalRevision,
    OutgoingTransmittal,
    OutgoingTransmittalRevision,
)


class TransmittalForm(GenericBaseDocumentForm):
    def build_layout(self):
        return Layout(
            Field("tobechecked_dir", type="hidden"),
            Field("accepted_dir", type="hidden"),
            Field("rejected_dir", type="hidden"),
            DocumentFieldset(
                _("General information"),
                Field("document_key", type="hidden"),
                "document_number",
                DateField("transmittal_date"),
                DateField("ack_of_receipt_date"),
                "contract_number",
                "originator",
                "recipient",
                "sequential_number",
                self.get_related_documents_layout(),
            ),
        )

    class Meta:
        model = Transmittal
        exclude = (
            "document",
            "latest_revision",
            "status",
            "transmittal_key",
            "document_type",
            "contractor",
        )


class TransmittalRevisionForm(GenericBaseDocumentForm):
    def build_layout(self):
        fields = (
            _("Revision"),
            DateField("revision_date"),
            DateField("received_date"),
            Field("created_on", readonly="readonly"),
        )

        # native / pdf will be autogenerated
        if self.read_only:
            fields += ("native_file", "pdf_file")

        return Layout(DocumentFieldset(*fields))

    class Meta:
        model = TransmittalRevision
        exclude = ("metadata", "revision", "trs_status", "updated_on")


class OutgoingTransmittalForm(GenericBaseDocumentForm):
    """Form for outgoing transmittal (duh).

    Since transmittals are not created through this form and sequential numbers
    are auto-generated, some fields MUST not be edited. Hence, we just
    display them as properties.

    """

    def get_related_documents_layout(self):
        related_documents = DocumentFieldset(
            _("Related documents"), RelatedRevisionsLayout("related_documents")
        )
        return related_documents

    def build_layout(self):
        return Layout(
            DocumentFieldset(
                _("General information"),
                Field("document_key", type="hidden"),
                PropertyLayout("document_number"),
                PropertyLayout("contract_number"),
                PropertyLayout("originator"),
                PropertyLayout("recipient"),
                Field("sequential_number", type="hidden"),
                PropertyLayout("purpose_of_issue_display"),
                PropertyLayout("external_review_due_date_display"),
                PropertyLayout("get_ack_of_receipt_display"),
                PropertyLayout("ack_of_receipt_date"),
                PropertyLayout("ack_of_receipt_author"),
                Field("archived_pdf"),
                self.get_related_documents_layout(),
            )
        )

    def prepare_field_archived_pdf(self):
        if self.instance.archived_pdf:
            url = reverse(
                "document_file_download",
                args=[
                    self.category.organisation.slug,
                    self.category.slug,
                    self.instance.document.document_key,
                    "archived_pdf",
                ],
            )
            self.fields["archived_pdf"].widget.value_url = url

    def clean_archived_pdf(self):
        """Do not allow a non PDF file to be uploaded as an archived pdf."""
        archived_pdf = self.cleaned_data["archived_pdf"]
        if archived_pdf not in (None, False):
            if not archived_pdf.name.endswith(".pdf"):
                raise forms.ValidationError("This field only accepts PDF files.")
        return archived_pdf

    class Meta:
        model = OutgoingTransmittal
        exclude = (
            "document",
            "latest_revision",
            "related_documents",
            "document_number",
            "contract_number",
            "originator",
            "recipient",
            "ack_of_receipt_date",
            "ack_of_receipt_author",
            "revisions_category",
            "purpose_of_issue",
            "external_review_due_date",
        )


class OutgoingTransmittalRevisionForm(GenericBaseDocumentForm):
    def build_layout(self):
        fields = (
            _("Revision"),
            Field("created_on", readonly="readonly"),
            Field("error_msg", rows=2),
        )

        # native / pdf will be autogenerated
        if self.read_only:
            fields += ("pdf_file",)

        return Layout(DocumentFieldset(*fields))

    class Meta:
        model = OutgoingTransmittalRevision
        exclude = (
            "metadata",
            "revision",
            "error_notified",
            "revision_date",
            "updated_on",
        )


class TransmittalDownloadForm(DocumentDownloadForm):
    content = forms.ChoiceField(
        choices=(
            ("transmittal", "Transmittal"),
            ("revisions", "Revisions"),
            ("both", "Both"),
        ),
        required=False,
    )


class TransmittableFormMixin(ReviewFormMixin):
    internal_review = forms.ChoiceField(
        label=_("Internal review only?"),
        choices=((False, "No"), (True, "Yes")),
        required=False)

    def get_trs_layout(self):
        if self.read_only:
            layout = (
                DocumentFieldset(
                    _("Outgoing Transmittal"),
                    "internal_review",
                    OutgoingTrsLayout(),
                    Field("client_comments"),
                    Field("client_comments_detail", rows=2),
                ),
            )
        else:
            layout = (
                DocumentFieldset(
                    _("Outgoing Transmittal"),
                    "internal_review",
                    Field("client_comments"),
                    Field("client_comments_detail", rows=2),
                ),
            )
        return layout

from django import forms
from django.urls import reverse

from documents.forms.utils import DocumentDownloadForm
from django.utils.translation import ugettext_lazy as _
from crispy_forms.layout import Layout, Field

from default_documents.layout import DocumentFieldset, DateField, PropertyLayout

from documents.forms.models import GenericBaseDocumentForm
from reviews.forms import ReviewFormMixin
from transmittals.layout import RelatedRevisionsLayout, OutgoingTrsLayout
from transmittals.models import (
    Transmittal,
    TransmittalRevision,
    OutgoingTransmittal,
    OutgoingTransmittalRevision,
)


class TransmittalForm(GenericBaseDocumentForm):
    def build_layout(self):
        return Layout(
            Field("tobechecked_dir", type="hidden"),
            Field("accepted_dir", type="hidden"),
            Field("rejected_dir", type="hidden"),
            DocumentFieldset(
                _("General information"),
                Field("document_key", type="hidden"),
                "document_number",
                DateField("transmittal_date"),
                DateField("ack_of_receipt_date"),
                "contract_number",
                "originator",
                "recipient",
                "sequential_number",
                self.get_related_documents_layout(),
            ),
        )

    class Meta:
        model = Transmittal
        exclude = (
            "document",
            "latest_revision",
            "status",
            "transmittal_key",
            "document_type",
            "contractor",
        )


class TransmittalRevisionForm(GenericBaseDocumentForm):
    def build_layout(self):
        fields = (
            _("Revision"),
            DateField("revision_date"),
            DateField("received_date"),
            Field("created_on", readonly="readonly"),
        )

        # native / pdf will be autogenerated
        if self.read_only:
            fields += ("native_file", "pdf_file")

        return Layout(DocumentFieldset(*fields))

    class Meta:
        model = TransmittalRevision
        exclude = ("metadata", "revision", "trs_status", "updated_on")


class OutgoingTransmittalForm(GenericBaseDocumentForm):
    """Form for outgoing transmittal (duh).

    Since transmittals are not created through this form and sequential numbers
    are auto-generated, some fields MUST not be edited. Hence, we just
    display them as properties.

    """

    def get_related_documents_layout(self):
        related_documents = DocumentFieldset(
            _("Related documents"), RelatedRevisionsLayout("related_documents")
        )
        return related_documents

    def build_layout(self):
        return Layout(
            DocumentFieldset(
                _("General information"),
                Field("document_key", type="hidden"),
                PropertyLayout("document_number"),
                PropertyLayout("contract_number"),
                PropertyLayout("originator"),
                PropertyLayout("recipient"),
                Field("sequential_number", type="hidden"),
                PropertyLayout("purpose_of_issue_display"),
                PropertyLayout("external_review_due_date_display"),
                PropertyLayout("get_ack_of_receipt_display"),
                PropertyLayout("ack_of_receipt_date"),
                PropertyLayout("ack_of_receipt_author"),
                Field("archived_pdf"),
                self.get_related_documents_layout(),
            )
        )

    def prepare_field_archived_pdf(self):
        if self.instance.archived_pdf:
            url = reverse(
                "document_file_download",
                args=[
                    self.category.organisation.slug,
                    self.category.slug,
                    self.instance.document.document_key,
                    "archived_pdf",
                ],
            )
            self.fields["archived_pdf"].widget.value_url = url

    def clean_archived_pdf(self):
        """Do not allow a non PDF file to be uploaded as an archived pdf."""
        archived_pdf = self.cleaned_data["archived_pdf"]
        if archived_pdf not in (None, False):
            if not archived_pdf.name.endswith(".pdf"):
                raise forms.ValidationError("This field only accepts PDF files.")
        return archived_pdf

    class Meta:
        model = OutgoingTransmittal
        exclude = (
            "document",
            "latest_revision",
            "related_documents",
            "document_number",
            "contract_number",
            "originator",
            "recipient",
            "ack_of_receipt_date",
            "ack_of_receipt_author",
            "revisions_category",
            "purpose_of_issue",
            "external_review_due_date",
        )


class OutgoingTransmittalRevisionForm(GenericBaseDocumentForm):
    def build_layout(self):
        fields = (
            _("Revision"),
            Field("created_on", readonly="readonly"),
            Field("error_msg", rows=2),
        )

        # native / pdf will be autogenerated
        if self.read_only:
            fields += ("pdf_file",)

        return Layout(DocumentFieldset(*fields))

    class Meta:
        model = OutgoingTransmittalRevision
        exclude = (
            "metadata",
            "revision",
            "error_notified",
            "revision_date",
            "updated_on",
        )


class TransmittalDownloadForm(DocumentDownloadForm):
    content = forms.ChoiceField(
        choices=(
            ("transmittal", "Transmittal"),
            ("revisions", "Revisions"),
            ("both", "Both"),
        ),
        required=False,
    )


class TransmittableFormMixin(ReviewFormMixin):
    internal_review = forms.ChoiceField(
        label=_("Internal review only?"),
        choices=((False, "No"), (True, "Yes")),
        required=False)

    def get_trs_layout(self):
        if self.read_only:
            layout = (
                DocumentFieldset(
                    _("Outgoing Transmittal"),
                    "internal_review",
                    OutgoingTrsLayout(),
                    Field("client_comments"),
                    Field("client_comments_detail", rows=2),
                ),
            )
        else:
            layout = (
                DocumentFieldset(
                    _("Outgoing Transmittal"),
                    "internal_review",
                    Field("client_comments"),
                    Field("client_comments_detail", rows=2),
                ),
            )
        return layout
# native / pdf will be autogenerated Form for outgoing transmittal (duh).      Since transmittals are not created through this form and sequential numbers     are auto-generated, some fields MUST not be edited. Hence, we just     display them as properties. Do not allow a non PDF file to be uploaded as an archived pdf. # native / pdf will be autogenerated