reportes
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from .views import ExportModelView, dashboard_summary
|
from .views import ExportModelView, dashboard_summary
|
||||||
# from .views_stats import documentos_por_fecha
|
# from .views_stats import documentos_por_fecha
|
||||||
# from .views_table import table_summary
|
from .views_table import table_summary
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('exportmodel/', ExportModelView.as_view(), name='export-model'),
|
path('exportmodel/', ExportModelView.as_view(), name='export-model'),
|
||||||
path('dashboard/summary/', dashboard_summary, name='dashboard-summary'),
|
path('dashboard/summary/', dashboard_summary, name='dashboard-summary'),
|
||||||
#path('documentos-por-fecha/', documentos_por_fecha, name='documentos-por-fecha'),
|
#path('documentos-por-fecha/', documentos_por_fecha, name='documentos-por-fecha'),
|
||||||
#path('table-summary/', table_summary, name='table-summary'),
|
path('table-summary/', table_summary, name='table-summary'),
|
||||||
|
|
||||||
]
|
]
|
||||||
@@ -15,9 +15,16 @@ class CustomPagination(PageNumberPagination):
|
|||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
def table_summary(request):
|
def table_summary(request):
|
||||||
|
# ...existing code...
|
||||||
|
|
||||||
|
# Si se solicita CSV, generar archivo y devolverlo (después de definir pedimentos_filters)
|
||||||
|
|
||||||
|
|
||||||
|
my_tags = ['Reportes']
|
||||||
"""
|
"""
|
||||||
Endpoint que devuelve un resumen tabulado de pedimentos y sus documentos asociados.
|
Endpoint que devuelve un resumen tabulado de pedimentos y sus documentos asociados.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
org_id = request.query_params.get('organizacion_id')
|
org_id = request.query_params.get('organizacion_id')
|
||||||
if not org_id:
|
if not org_id:
|
||||||
return Response({"error": "organizacion_id es requerido"}, status=400)
|
return Response({"error": "organizacion_id es requerido"}, status=400)
|
||||||
@@ -40,12 +47,12 @@ def table_summary(request):
|
|||||||
fecha_pago_gte = fecha_pago_lte - timedelta(days=30)
|
fecha_pago_gte = fecha_pago_lte - timedelta(days=30)
|
||||||
|
|
||||||
# Construir filtros base para pedimentos
|
# Construir filtros base para pedimentos
|
||||||
pedimentos_filters = Q(organizacion_id=org_id)
|
pedimentos_filters = Q()
|
||||||
|
pedimentos_filters &= Q(organizacion_id=org_id)
|
||||||
# Añadir filtros de fecha siempre para limitar el conjunto de datos
|
if fecha_pago_gte:
|
||||||
pedimentos_filters &= Q(fecha_pago__gte=fecha_pago_gte)
|
pedimentos_filters &= Q(fecha_pago__gte=fecha_pago_gte)
|
||||||
pedimentos_filters &= Q(fecha_pago__lte=fecha_pago_lte)
|
if fecha_pago_lte:
|
||||||
|
pedimentos_filters &= Q(fecha_pago__lte=fecha_pago_lte)
|
||||||
if rfc:
|
if rfc:
|
||||||
pedimentos_filters &= Q(contribuyente__rfc=rfc)
|
pedimentos_filters &= Q(contribuyente__rfc=rfc)
|
||||||
if patente:
|
if patente:
|
||||||
@@ -61,95 +68,130 @@ def table_summary(request):
|
|||||||
if tipo_operacion:
|
if tipo_operacion:
|
||||||
pedimentos_filters &= Q(tipo_operacion_id=tipo_operacion)
|
pedimentos_filters &= Q(tipo_operacion_id=tipo_operacion)
|
||||||
|
|
||||||
# Query base desde pedimentos con todas las subconsultas necesarias
|
# Si se solicita los últimos 100 registros actualizados
|
||||||
resultado = Pedimento.objects.filter(pedimentos_filters).values(
|
if request.query_params.get('ultimos') == '1':
|
||||||
'aduana',
|
pedimentos = Pedimento.objects.filter(pedimentos_filters).order_by('-updated_at')[:100]
|
||||||
'patente',
|
else:
|
||||||
'regimen',
|
pedimentos = Pedimento.objects.filter(pedimentos_filters)
|
||||||
'pedimento',
|
|
||||||
'pedimento_app',
|
|
||||||
'clave_pedimento',
|
|
||||||
'tipo_operacion_id',
|
|
||||||
'contribuyente_id'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generar queries según el tipo de documento solicitado
|
# Serializar pedimentos con documentos relacionados
|
||||||
queries = []
|
results = []
|
||||||
|
for ped in pedimentos:
|
||||||
|
ped_dict = {
|
||||||
|
'aduana': ped.aduana,
|
||||||
|
'patente': ped.patente,
|
||||||
|
'regimen': ped.regimen,
|
||||||
|
'pedimento': ped.pedimento,
|
||||||
|
'pedimento_app': ped.pedimento_app,
|
||||||
|
'clave_pedimento': ped.clave_pedimento,
|
||||||
|
'tipo_operacion_id': ped.tipo_operacion_id,
|
||||||
|
'contribuyente_id': ped.contribuyente_id,
|
||||||
|
'documentos': []
|
||||||
|
}
|
||||||
|
# COVEs
|
||||||
|
for cove in Cove.objects.filter(pedimento=ped):
|
||||||
|
ped_dict['documentos'].append({
|
||||||
|
'tipo': 'COVE',
|
||||||
|
'numero': cove.numero_cove,
|
||||||
|
'estado': cove.cove_descargado,
|
||||||
|
'acuse_estado': cove.acuse_cove_descargado
|
||||||
|
})
|
||||||
|
# EDOCs
|
||||||
|
for edoc in EDocument.objects.filter(pedimento=ped):
|
||||||
|
ped_dict['documentos'].append({
|
||||||
|
'tipo': 'EDOC',
|
||||||
|
'numero': edoc.numero_edocument,
|
||||||
|
'estado': edoc.edocument_descargado,
|
||||||
|
'acuse_estado': edoc.acuse_descargado,
|
||||||
|
})
|
||||||
|
# PARTIDAS
|
||||||
|
for partida in Partida.objects.filter(pedimento=ped):
|
||||||
|
ped_dict['documentos'].append({
|
||||||
|
'tipo': 'PARTIDA',
|
||||||
|
'numero': partida.numero_partida,
|
||||||
|
'estado': partida.descargado
|
||||||
|
})
|
||||||
|
results.append(ped_dict)
|
||||||
|
|
||||||
if not tipo_documento or tipo_documento == 'ACUSE COVE':
|
if request.query_params.get('csv') == '1':
|
||||||
coves_acuse = resultado.annotate(
|
import csv
|
||||||
identificador=Cast(Subquery(
|
from django.http import HttpResponse
|
||||||
Cove.objects.filter(pedimento_id=OuterRef('id')).values('numero_cove')[:1]
|
headers = [
|
||||||
), CharField()),
|
'aduana', 'patente', 'regimen', 'pedimento', 'pedimento_app', 'clave_pedimento',
|
||||||
documento=Value('ACUSE COVE', CharField()),
|
'tipo_operacion_id', 'contribuyente_id', 'tipo_documento', 'numero_documento', 'estado', 'acuse_estado'
|
||||||
estado=Cast(Subquery(
|
]
|
||||||
Cove.objects.filter(pedimento_id=OuterRef('id')).values('acuse_cove_descargado')[:1]
|
response = HttpResponse(content_type='text/csv')
|
||||||
), CharField())
|
response['Content-Disposition'] = 'attachment; filename=table_summary.csv'
|
||||||
).filter(identificador__isnull=False)
|
writer = csv.writer(response)
|
||||||
queries.append(coves_acuse)
|
writer.writerow(headers)
|
||||||
|
# Llenar filas
|
||||||
|
if request.query_params.get('ultimos') == '1':
|
||||||
|
pedimentos = Pedimento.objects.filter(pedimentos_filters).order_by('-updated_at')[:100]
|
||||||
|
else:
|
||||||
|
pedimentos = Pedimento.objects.filter(pedimentos_filters)
|
||||||
|
for ped in pedimentos:
|
||||||
|
# COVEs
|
||||||
|
for cove in Cove.objects.filter(pedimento=ped):
|
||||||
|
writer.writerow([
|
||||||
|
ped.aduana, ped.patente, ped.regimen, ped.pedimento, ped.pedimento_app,
|
||||||
|
ped.clave_pedimento, ped.tipo_operacion_id, ped.contribuyente_id,
|
||||||
|
'COVE', cove.numero_cove, cove.cove_descargado, cove.acuse_cove_descargado
|
||||||
|
])
|
||||||
|
# EDOCs
|
||||||
|
for edoc in EDocument.objects.filter(pedimento=ped):
|
||||||
|
writer.writerow([
|
||||||
|
ped.aduana, ped.patente, ped.regimen, ped.pedimento, ped.pedimento_app,
|
||||||
|
ped.clave_pedimento, ped.tipo_operacion_id, ped.contribuyente_id,
|
||||||
|
'EDOC', edoc.numero_edocument, edoc.edocument_descargado, edoc.acuse_descargado
|
||||||
|
])
|
||||||
|
# PARTIDAS
|
||||||
|
for partida in Partida.objects.filter(pedimento=ped):
|
||||||
|
writer.writerow([
|
||||||
|
ped.aduana, ped.patente, ped.regimen, ped.pedimento, ped.pedimento_app,
|
||||||
|
ped.clave_pedimento, ped.tipo_operacion_id, ped.contribuyente_id,
|
||||||
|
'PARTIDA', partida.numero_partida, partida.descargado, ''
|
||||||
|
])
|
||||||
|
return response
|
||||||
|
# Si se solicita Excel, generar archivo y devolverlo
|
||||||
|
if request.query_params.get('excel') == '1':
|
||||||
|
import openpyxl
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
from django.http import HttpResponse
|
||||||
|
wb = openpyxl.Workbook()
|
||||||
|
ws = wb.active
|
||||||
|
ws.title = "Resumen"
|
||||||
|
# Encabezados
|
||||||
|
headers = [
|
||||||
|
'aduana', 'patente', 'regimen', 'pedimento', 'pedimento_app', 'clave_pedimento',
|
||||||
|
'tipo_operacion_id', 'contribuyente_id', 'tipo_documento', 'numero_documento', 'estado', 'acuse_estado'
|
||||||
|
]
|
||||||
|
ws.append(headers)
|
||||||
|
# Llenar filas
|
||||||
|
for ped in results:
|
||||||
|
for doc in ped['documentos']:
|
||||||
|
ws.append([
|
||||||
|
ped['aduana'], ped['patente'], ped['regimen'], ped['pedimento'], ped['pedimento_app'],
|
||||||
|
ped['clave_pedimento'], ped['tipo_operacion_id'], ped['contribuyente_id'],
|
||||||
|
doc.get('tipo'), doc.get('numero'), doc.get('estado'), doc.get('acuse_estado')
|
||||||
|
])
|
||||||
|
# Ajustar ancho de columnas
|
||||||
|
for i, col in enumerate(headers, 1):
|
||||||
|
ws.column_dimensions[get_column_letter(i)].width = max(12, len(col) + 2)
|
||||||
|
# Guardar en memoria y devolver como respuesta
|
||||||
|
from io import BytesIO
|
||||||
|
output = BytesIO()
|
||||||
|
wb.save(output)
|
||||||
|
output.seek(0)
|
||||||
|
response = HttpResponse(
|
||||||
|
output.read(),
|
||||||
|
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
|
)
|
||||||
|
response['Content-Disposition'] = 'attachment; filename=table_summary.xlsx'
|
||||||
|
return response
|
||||||
|
|
||||||
if not tipo_documento or tipo_documento == 'COVE':
|
# Aplicar paginación manual sobre results
|
||||||
coves = resultado.annotate(
|
|
||||||
identificador=Cast(Subquery(
|
|
||||||
Cove.objects.filter(pedimento_id=OuterRef('id')).values('numero_cove')[:1]
|
|
||||||
), CharField()),
|
|
||||||
documento=Value('COVE', CharField()),
|
|
||||||
estado=Cast(Subquery(
|
|
||||||
Cove.objects.filter(pedimento_id=OuterRef('id')).values('cove_descargado')[:1]
|
|
||||||
), CharField())
|
|
||||||
).filter(identificador__isnull=False)
|
|
||||||
queries.append(coves)
|
|
||||||
|
|
||||||
if not tipo_documento or tipo_documento == 'ACUSE EDOC':
|
|
||||||
edocs_acuse = resultado.annotate(
|
|
||||||
identificador=Cast(Subquery(
|
|
||||||
EDocument.objects.filter(pedimento_id=OuterRef('id')).values('numero_edocument')[:1]
|
|
||||||
), CharField()),
|
|
||||||
documento=Value('ACUSE EDOC', CharField()),
|
|
||||||
estado=Cast(Subquery(
|
|
||||||
EDocument.objects.filter(pedimento_id=OuterRef('id')).values('acuse_descargado')[:1]
|
|
||||||
), CharField())
|
|
||||||
).filter(identificador__isnull=False)
|
|
||||||
queries.append(edocs_acuse)
|
|
||||||
|
|
||||||
if not tipo_documento or tipo_documento == 'EDOC':
|
|
||||||
edocs = resultado.annotate(
|
|
||||||
identificador=Cast(Subquery(
|
|
||||||
EDocument.objects.filter(pedimento_id=OuterRef('id')).values('numero_edocument')[:1]
|
|
||||||
), CharField()),
|
|
||||||
documento=Value('EDOC', CharField()),
|
|
||||||
estado=Cast(Subquery(
|
|
||||||
EDocument.objects.filter(pedimento_id=OuterRef('id')).values('edocument_descargado')[:1]
|
|
||||||
), CharField())
|
|
||||||
).filter(identificador__isnull=False)
|
|
||||||
queries.append(edocs)
|
|
||||||
|
|
||||||
if not tipo_documento or tipo_documento == 'PARTIDA':
|
|
||||||
partidas = resultado.annotate(
|
|
||||||
identificador=Cast(Subquery(
|
|
||||||
Partida.objects.filter(pedimento_id=OuterRef('id')).values('numero_partida')[:1]
|
|
||||||
), CharField()),
|
|
||||||
documento=Value('PARTIDA', CharField()),
|
|
||||||
estado=Cast(Subquery(
|
|
||||||
Partida.objects.filter(pedimento_id=OuterRef('id')).values('descargado')[:1]
|
|
||||||
), CharField())
|
|
||||||
).filter(identificador__isnull=False)
|
|
||||||
queries.append(partidas)
|
|
||||||
|
|
||||||
# Unir los resultados usando UNION ALL para mejor rendimiento
|
|
||||||
if not queries:
|
|
||||||
return Response([])
|
|
||||||
|
|
||||||
resultado_final = queries[0]
|
|
||||||
for query in queries[1:]:
|
|
||||||
resultado_final = resultado_final.union(query, all=True)
|
|
||||||
|
|
||||||
# Aplicar paginación
|
|
||||||
paginator = CustomPagination()
|
paginator = CustomPagination()
|
||||||
page = paginator.paginate_queryset(
|
page = paginator.paginate_queryset(results, request)
|
||||||
resultado_final.order_by('pedimento', 'documento'),
|
|
||||||
request
|
|
||||||
)
|
|
||||||
|
|
||||||
return paginator.get_paginated_response({
|
return paginator.get_paginated_response({
|
||||||
"results": page,
|
"results": page,
|
||||||
|
|||||||
Reference in New Issue
Block a user