Skip to content
Snippets Groups Projects
views.py 10.71 KiB
from xml.etree import ElementTree

import requests
from django.conf import settings
from django.core.paginator import Paginator
from django.db import models
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django_downloadview import ObjectDownloadView
from django_http_exceptions import HTTPExceptions
from guardian.shortcuts import get_objects_for_user

from .models import Contract, ContractFile


class ContractFileDownloadView(ObjectDownloadView):
    model = ContractFile
    file_field = "file"
    attachment = False

    def get_queryset(self, *args, **kwargs):
        queryset = super().get_queryset(*args, **kwargs)

        if not self.current_user.has_perm("contracts.view_confidential"):
            queryset = queryset.filter(is_public=True)

        return queryset

    def get(self, request, *args, **kwargs):
        self.current_user = request.user

        return super().get(request, *args, **kwargs)


def get_base_context(request) -> dict:
    return {
        "site_url": settings.SITE_URL,
        "user": request.user,
    }


def get_pagination(request, objects) -> tuple:
    paginator = Paginator(objects, 25)

    page = paginator.get_page(request.GET.get("page"))

    return page, paginator


def get_paginated_contracts(request, filter=None) -> tuple:
    if filter is None:
        filter = models.Q()

    filter = models.Q(is_approved=True)

    if not request.user.has_perm("contracts.view_confidential"):
        additional_filter = models.Q(is_public=True)

        if not request.user.is_anonymous:
            additional_filter = additional_filter | models.Q(created_by=request.user)

        filter = filter & additional_filter

    contracts = (
        get_objects_for_user(request.user, "contracts.view_contract")
        .filter(filter)
        .order_by("valid_start_date")
        .all()
    )

    page, paginator = get_pagination(request, contracts)

    return page, paginator


def index(request):
    page, paginator = get_paginated_contracts(request)

    return render(
        request,
        "contracts/index.html",
        {
            **get_base_context(request),
            "title": "Seznam smluv",
            "description": "Description",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract(request, id: int):
    filter = models.Q(is_approved=True)

    if not request.user.has_perm("contracts.view_confidential"):
        filter = filter & (
            models.Q(is_public=True)
            | (
                models.Q(created_by=request.user)
                if not request.user.is_anonymous
                else models.Value(True)
            )
        )

    contract = get_object_or_404(
        (get_objects_for_user(request.user, "contracts.view_contract").filter(filter)),
        id=id,
    )

    return render(
        request,
        "contracts/view_contract.html",
        {
            **get_base_context(request),
            "title": contract.name,
            "description": contract.summary,
            "contract": contract,
        },
    )


def search(request):
    query = request.GET.get("q")
    page = paginator = None
    title = "Vyhledávání"

    if query is not None:
        title = f"Vyhledávání - {query}"

        # WARNING: PostgreSQL-dependent
        page, paginator = get_paginated_contracts(
            request,
            models.Q(name__search=query)
        )

    return render(
        "contracts/search.html",
        {
            **get_base_context(request),
            "title": title,
            "description": "Vyhledávání smluv v registru České Pirátské Strany.",
            "page": page,
            "paginator": paginator,
            "query": query,
        }
    )


# BEGIN Filtered contract + submodel views


def view_contract_filing_area(request, id: int):
    filing_area = get_object_or_404(
        get_objects_for_user(request.user, "contracts.view_contractfilingarea"), id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, models.Q(filing_area=filing_area)
    )

    return render(
        request,
        "contracts/view_contract_filing_area.html",
        {
            **get_base_context(request),
            "title": filing_area.name,
            "description": (
                f"Spisovna smluv - {filing_area.name}, "
                f"zodpovědná osoba {filing_area.person_responsible}"
            ),
            "filing_area": filing_area,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contract_issue(request, id: int):
    issue = get_object_or_404(
        get_objects_for_user(request.user, "contracts.view_contractissue"), id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, models.Q(issues=issue)
    )

    return render(
        request,
        "contracts/view_contract_issue.html",
        {
            **get_base_context(request),
            "title": issue.name,
            "description": f"Problém se smlouvami - {issue.name}",
            "issue": issue,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contract_type(request, id: int):
    type_ = get_object_or_404(
        get_objects_for_user(request.user, "contracts.view_contracttype"), id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, models.Q(types=type_)
    )

    return render(
        request,
        "contracts/view_contract_type.html",
        {
            **get_base_context(request),
            "title": type_.name,
            "description": f"Typ smluv - {type_.name}",
            "type": type_,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contractee(request, id: int):
    contractee = get_object_or_404(
        get_objects_for_user(request.user, "contracts.view_contractee"), id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, models.Q(contractee_signatures__contractee=contractee)
    )

    return render(
        request,
        "contracts/view_contractee.html",
        {
            **get_base_context(request),
            "title": contractee.name,
            "description": f"Naše smluvní strana - {contractee.name}",
            "contractee": contractee,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_signee(request, id: int):
    signee = get_object_or_404(
        get_objects_for_user(request.user, "contracts.view_signee"), id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, models.Q(signee_signatures__signee=signee)
    )

    return render(
        request,
        "contracts/view_signee.html",
        {
            **get_base_context(request),
            "title": signee.name,
            "description": f"Jiná smluvní strana - {signee.name}",
            "signee": signee,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


# END Filtered contract + submodel views

# BEGIN Submodel listing views


def view_contract_filing_areas(request):
    filing_areas = get_objects_for_user(
        request.user,
        "contracts.view_contractfilingarea",
    ).order_by("name")

    page, paginator = get_pagination(request, filing_areas)

    return render(
        request,
        "contracts/view_contract_filing_areas.html",
        {
            **get_base_context(request),
            "title": "Spisovny",
            "description": "Seznam fyzických spisoven, kde jsou ukládány smlouvy.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract_issues(request):
    issues = get_objects_for_user(
        request.user,
        "contracts.view_contractissue",
    ).order_by("name")

    page, paginator = get_pagination(request, issues)

    return render(
        request,
        "contracts/view_contract_issues.html",
        {
            **get_base_context(request),
            "title": (
                "Poznámky"
                if (request.user.is_anonymous or not request.user.can_view_confidential)
                else "Problémy"
            ),
            "description": (
                "Poznámky ke smlouvám."
                if (request.user.is_anonymous or not request.user.can_view_confidential)
                else "Problémy se smlouvami."
            ),
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract_types(request):
    types = get_objects_for_user(
        request.user,
        "contracts.view_contracttype",
    ).order_by("name")

    page, paginator = get_pagination(request, types)

    return render(
        request,
        "contracts/view_contract_types.html",
        {
            **get_base_context(request),
            "title": "Typy",
            "description": "Typy smluv.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contractees(request):
    contractees = get_objects_for_user(
        request.user,
        "contracts.view_contractee",
    ).order_by("name")

    page, paginator = get_pagination(request, contractees)

    return render(
        request,
        "contracts/view_contractees.html",
        {
            **get_base_context(request),
            "title": "Naše smluvní strany",
            "description": "Naše smluvní strany.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_signees(request):
    contractees = get_objects_for_user(
        request.user,
        "contracts.view_signee",
    ).order_by("name")

    page, paginator = get_pagination(request, contractees)

    return render(
        request,
        "contracts/view_signees.html",
        {
            **get_base_context(request),
            "title": "Jiné smluvní strany",
            "description": "Jiné smluvní strany.",
            "page": page,
            "paginator": paginator,
        },
    )


# END Submodel listing views


# ARES CORS proxy
def get_ares_info(request, ico: int):
    if not request.user.is_staff:
        raise HTTPExceptions.FORBIDDEN

    ares_info = requests.get(
        f"https://wwwinfo.mfcr.cz/cgi-bin/ares/darv_std.cgi?ico={ico}"
    )

    tree = ElementTree.fromstring(ares_info.content)

    for result_count in tree.iter("are:Pocet_zaznamu"):
        if result_count.text == "0":
            raise HTTPExceptions.NOT_FOUND

    return HttpResponse(
        content=ares_info.content,
        status=ares_info.status_code,
        content_type=ares_info.headers.get("Content-Type"),
    )