Add organization stats endpoint
This commit is contained in:
@@ -69,7 +69,7 @@ from apps.registers.models import RegistryMembershipPeriod
|
||||
from django.core.files.storage import default_storage
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import CharField, Count, Q
|
||||
from django.db.models.functions import Cast
|
||||
from django.db.models.functions import Cast, Lower
|
||||
from django.http import HttpResponse
|
||||
from django.utils.text import get_valid_filename
|
||||
from django.views.generic import TemplateView
|
||||
@@ -1452,7 +1452,10 @@ def _save_uploaded_parser_file(uploaded_file) -> str:
|
||||
def _model_payload(record) -> dict:
|
||||
payload = {}
|
||||
for field in record._meta.fields:
|
||||
value = getattr(record, field.name)
|
||||
if getattr(field, "many_to_one", False):
|
||||
value = getattr(record, field.attname)
|
||||
else:
|
||||
value = getattr(record, field.name)
|
||||
if hasattr(value, "isoformat"):
|
||||
value = value.isoformat()
|
||||
payload[field.name] = value
|
||||
@@ -1502,13 +1505,20 @@ def _native_record_to_result(
|
||||
inn = record.customer_inn
|
||||
ogrn = record.customer_ogrn
|
||||
elif source == ParserLoadLog.Source.FNS_REPORTS:
|
||||
registry_organization = record.registry_organization
|
||||
external_id = record.external_id
|
||||
organisation_name = ""
|
||||
organisation_name = (
|
||||
registry_organization.pn_name if registry_organization else ""
|
||||
)
|
||||
title = record.file_name
|
||||
record_date = ""
|
||||
status_value = record.status
|
||||
url = ""
|
||||
inn = ""
|
||||
inn = (
|
||||
str(registry_organization.mn_inn)
|
||||
if registry_organization and registry_organization.mn_inn
|
||||
else ""
|
||||
)
|
||||
ogrn = record.ogrn
|
||||
else:
|
||||
external_id = record.registration_number
|
||||
@@ -2027,14 +2037,34 @@ def source_result_swagger_tag(source_key: str) -> str:
|
||||
return SOURCE_RESULT_TAGS.get(source_key, PARSERS_TAG)
|
||||
|
||||
|
||||
def _safe_ordering(ordering: str, field_map: dict[str, str]) -> list[str]:
|
||||
CASE_INSENSITIVE_RESULT_ORDERING_FIELDS = {
|
||||
"external_id",
|
||||
"organisation_name",
|
||||
"title",
|
||||
"record_date",
|
||||
"status",
|
||||
"url",
|
||||
}
|
||||
|
||||
|
||||
def _safe_ordering(
|
||||
ordering: str,
|
||||
field_map: dict[str, str],
|
||||
*,
|
||||
case_insensitive_fields: set[str] | None = None,
|
||||
) -> list:
|
||||
case_insensitive_fields = case_insensitive_fields or set()
|
||||
result = []
|
||||
for raw_field in (item.strip() for item in ordering.split(",") if item.strip()):
|
||||
desc = raw_field.startswith("-")
|
||||
api_field = raw_field[1:] if desc else raw_field
|
||||
model_field = field_map.get(api_field)
|
||||
if model_field:
|
||||
result.append(f"-{model_field}" if desc else model_field)
|
||||
if api_field in case_insensitive_fields:
|
||||
expression = Lower(model_field)
|
||||
result.append(expression.desc() if desc else expression.asc())
|
||||
else:
|
||||
result.append(f"-{model_field}" if desc else model_field)
|
||||
return result
|
||||
|
||||
|
||||
@@ -2076,15 +2106,21 @@ def _native_field_map(source: str) -> dict[str, str]:
|
||||
"organisation_name": "customer_name",
|
||||
"title": "purchase_name",
|
||||
"record_date": "publish_date",
|
||||
"amount": "max_price_amount",
|
||||
"status": "status",
|
||||
}
|
||||
if source == ParserLoadLog.Source.FNS_REPORTS:
|
||||
return {
|
||||
**common,
|
||||
"id": "id",
|
||||
"load_batch": "load_batch",
|
||||
"external_id": "external_id",
|
||||
"inn": "registry_organization__mn_inn",
|
||||
"ogrn": "ogrn",
|
||||
"organisation_name": "registry_organization__pn_name",
|
||||
"title": "file_name",
|
||||
"status": "status",
|
||||
"created_at": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
}
|
||||
return {
|
||||
**common,
|
||||
@@ -2131,6 +2167,7 @@ def _native_search_q(source: str, search: str) -> Q:
|
||||
Q(file_name__icontains=search)
|
||||
| Q(external_id__icontains=search)
|
||||
| Q(ogrn__icontains=search)
|
||||
| Q(registry_organization__pn_name__icontains=search)
|
||||
| Q(status__icontains=search)
|
||||
)
|
||||
return (
|
||||
@@ -2155,6 +2192,21 @@ def _generic_search_q(search: str) -> Q:
|
||||
)
|
||||
|
||||
|
||||
def _apply_native_search(queryset, source: str, search: str):
|
||||
if source != ParserLoadLog.Source.FNS_REPORTS:
|
||||
return queryset.filter(_native_search_q(source, search))
|
||||
|
||||
return queryset.annotate(
|
||||
registry_organization_inn_text=Cast(
|
||||
"registry_organization__mn_inn",
|
||||
output_field=CharField(),
|
||||
),
|
||||
).filter(
|
||||
_native_search_q(source, search)
|
||||
| Q(registry_organization_inn_text__icontains=search)
|
||||
)
|
||||
|
||||
|
||||
def _route_model_sources(descriptor) -> set[str]:
|
||||
return {
|
||||
item.source
|
||||
@@ -2178,6 +2230,8 @@ def _result_sources_for_request(descriptor, params: dict) -> set[str]:
|
||||
|
||||
def _filter_native_result_queryset(source: str, params: dict, sources: set[str]):
|
||||
queryset = NATIVE_RECORD_MODELS[source].objects.all()
|
||||
if source == ParserLoadLog.Source.FNS_REPORTS:
|
||||
queryset = queryset.select_related("registry_organization")
|
||||
if not sources:
|
||||
queryset = queryset.none()
|
||||
field_map = _native_field_map(source)
|
||||
@@ -2189,8 +2243,12 @@ def _filter_native_result_queryset(source: str, params: dict, sources: set[str])
|
||||
if params.get("record_date") and field_map.get("record_date"):
|
||||
queryset = queryset.filter(**{field_map["record_date"]: params["record_date"]})
|
||||
if params.get("search"):
|
||||
queryset = queryset.filter(_native_search_q(source, params["search"]))
|
||||
ordering = _safe_ordering(params.get("ordering") or "-created_at", field_map)
|
||||
queryset = _apply_native_search(queryset, source, params["search"])
|
||||
ordering = _safe_ordering(
|
||||
params.get("ordering") or "-created_at",
|
||||
field_map,
|
||||
case_insensitive_fields=CASE_INSENSITIVE_RESULT_ORDERING_FIELDS,
|
||||
)
|
||||
return queryset.order_by(*(ordering or ["-created_at"]))
|
||||
|
||||
|
||||
@@ -2215,11 +2273,17 @@ def _filter_generic_result_queryset(sources: set[str], params: dict):
|
||||
"organisation_name": "organisation_name",
|
||||
"title": "title",
|
||||
"record_date": "record_date",
|
||||
"amount": "amount",
|
||||
"status": "status",
|
||||
"url": "url",
|
||||
"created_at": "created_at",
|
||||
"updated_at": "updated_at",
|
||||
}
|
||||
ordering = _safe_ordering(params.get("ordering") or "-created_at", field_map)
|
||||
ordering = _safe_ordering(
|
||||
params.get("ordering") or "-created_at",
|
||||
field_map,
|
||||
case_insensitive_fields=CASE_INSENSITIVE_RESULT_ORDERING_FIELDS,
|
||||
)
|
||||
return queryset.order_by(*(ordering or ["-created_at"]))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user