-
Alexa Valentová authoredAlexa Valentová authored
views.py 14.67 KiB
import os
import requests
from django.conf import settings
from django.core.paginator import Paginator
from django.db import models
from django.db.models.functions import Lower
from django.http import HttpResponse, JsonResponse
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, annotations=None) -> tuple:
if filter is None:
filter = models.Q()
filter = filter & models.Q(status=Contract.StatusTypes.APPROVED)
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")
if annotations is not None:
contracts = contracts.annotate(**annotations)
contracts = contracts.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": "",
"page": page,
"paginator": paginator,
"settings": Contract.settings,
},
)
def view_contract(request, id: int):
filter = models.Q(status=Contract.StatusTypes.APPROVED)
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):
original_query = request.GET.get("q", default="")
query = original_query.lower()
if query.isnumeric():
number_query = int(query)
else:
number_query = 0
page = paginator = None
title = "Vyhledávání"
if query:
filter = models.Q(
models.Q(lower_name__contains=query)
| models.Q(lower_summary__contains=query)
| models.Q(
models.Q(contractee_signatures__contractee__ico_number=number_query)
| models.Q(signee_signatures__signee__ico_number=number_query)
)
| models.Q(
models.Q(contractee_signatures__contractee__name_lower__contains=query)
| models.Q(signee_signatures__signee__name_lower__contains=query)
)
| models.Q(
models.Q(
contractee_signatures__representatives__name_lower__contains=query
)
| models.Q(
signee_signatures__representatives__name_lower__contains=query
)
)
)
annotations = {
"lower_name": Lower("name"),
"lower_summary": Lower("summary"),
"contractee_signatures__contractee__name_lower": Lower(
"contractee_signatures__contractee__name"
),
"signee_signatures__signee__name_lower": Lower(
"signee_signatures__signee__name"
),
"contractee_signatures__representatives__name_lower": Lower(
"contractee_signatures__representatives__name"
),
"signee_signatures__representatives__name_lower": Lower(
"signee_signatures__representatives__name"
),
}
# WARNING: PostgreSQL-dependent
page, paginator = get_paginated_contracts(
request,
filter,
annotations,
)
return render(
request,
"contracts/search.html",
{
**get_base_context(request),
"title": title,
"description": "",
"page": page,
"paginator": paginator,
"query": original_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",
)
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",
)
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
# Basic contract view API
def view_contract_json(request, id: int):
filter = models.Q(status=Contract.StatusTypes.APPROVED)
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 JsonResponse({
"id": contract.id,
"created_by": {
"id": contract.created_by_id,
"username": contract.created_by.username,
},
"created_on": contract.created_on,
"updated_on": contract.updated_on,
"status": contract.status,
"name": contract.name,
"id_number": contract.id_number,
"types": [
{
"id": type.id,
"name": type.name
}
for type in contract.types.all()
],
"summary": contract.summary,
"valid_start_date": contract.valid_start_date,
"valid_end_date": contract.valid_end_date,
"is_valid": contract.is_valid,
"is_public": contract.is_public,
"publishing_rejection_comment": contract.publishing_rejection_comment,
"paper_form_state": contract.paper_form_state,
"paper_form_person_responsible": contract.paper_form_person_responsible,
"tender_url": contract.tender_url,
"issues": [
{
"id": issue.id,
"name": issue.name
}
for issue in contract.issues.all()
]
})
# 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://ares.gov.cz/ekonomicke-subjekty-v-be/rest/ekonomicke-subjekty/{ico}"
)
return HttpResponse(
content=ares_info.content,
status=ares_info.status_code,
content_type=ares_info.headers.get("Content-Type"),
)
def handle_404(request, exception):
path = os.path.normpath(request.get_full_path())
archive_url = f"https://smlouvy-archiv.pirati.cz{path}"
archive_response = requests.get(archive_url)
# Quick dirty check for whether the page found is an actual contract
was_found = archive_response.ok and "Datum podpisu" in str(archive_response.content)
return render(
request,
"contracts/404.html",
{
**get_base_context(request),
"title": "Stránka nenalezena",
"description": "",
"archive_page_exists": was_found,
"archive_url": archive_url,
},
)