Overview
The Reporte model manages report definitions, data storage, and file generation for the Bar Galileo reporting system.
Reporte Model
Stores report configuration, metadata, and generated files.
Fields
Report name (max 200 characters)
Report type. Choices:
ventas - Sales
inventario - Inventory
gastos - Expenses
nominas - Payroll
productos - Products
mesas - Tables and Orders
general - General
Default: general
Time period. Choices:
diario - Daily
semanal - Weekly
mensual - Monthly
trimestral - Quarterly
anual - Annual
personalizado - Custom
Default: mensual
Export format. Choices:
pdf - PDF
excel - Excel
csv - CSV
Default: pdf
Optional report description
User who created the report (SET_NULL on delete)
When the report was created. Auto-set on creation.
Start date for report data
Generated file (uploaded to ‘reportes/’)
Whether the report has been generated. Default: False
Report data stored as JSON string
Timestamp of last generation
class Meta :
ordering = [ '-fecha_creacion' ]
verbose_name = 'Reporte'
verbose_name_plural = 'Reportes'
permissions = [
( 'exportar_reporte' , 'Puede exportar reportes' ),
( 'generar_reporte' , 'Puede generar reportes automáticamente' ),
]
Model Properties
duracion_dias
Returns the duration of the report period in days:
@ property
def duracion_dias ( self ):
"""Retorna la duración del periodo en días"""
if self .fecha_inicio and self .fecha_fin:
return ( self .fecha_fin - self .fecha_inicio).days + 1
return 0
esta_vencido
Checks if the report is outdated (more than 30 days old):
@ property
def esta_vencido ( self ):
"""Verifica si el reporte está desactualizado (más de 30 días)"""
if self .fecha_creacion:
return (timezone.now() - self .fecha_creacion).days > 30
return False
Model Methods
get_datos()
Retrieve report data from JSON:
def get_datos ( self ):
"""Obtiene los datos del reporte desde JSON"""
if self .datos_json:
try :
return json.loads( self .datos_json)
except json.JSONDecodeError:
return {}
return {}
set_datos(datos)
Save report data as JSON:
def set_datos ( self , datos ):
"""Guarda los datos del reporte en JSON"""
self .datos_json = json.dumps(datos, ensure_ascii = False )
self .ultima_generacion = timezone.now()
Usage Examples
Create Report Definition
from reportes.models import Reporte
from django.contrib.auth.models import User
from datetime import date
user = User.objects.get( username = 'admin' )
reporte = Reporte.objects.create(
nombre = 'Ventas Enero 2025' ,
tipo = 'ventas' ,
periodo = 'mensual' ,
formato = 'pdf' ,
descripcion = 'Reporte mensual de ventas' ,
creado_por = user,
fecha_inicio = date( 2025 , 1 , 1 ),
fecha_fin = date( 2025 , 1 , 31 )
)
Generate Report with Data
from reportes.models import Reporte
from tables.models import Factura
from django.db.models import Sum
# Get report
reporte = Reporte.objects.get( id = report_id)
# Query data
facturas = Factura.objects.filter(
fecha__range = [reporte.fecha_inicio, reporte.fecha_fin]
)
total = facturas.aggregate( total = Sum( 'total' ))[ 'total' ] or 0
# Store data
datos = {
'total_ventas' : float (total),
'num_facturas' : facturas.count(),
'periodo' : f " { reporte.fecha_inicio } - { reporte.fecha_fin } " ,
'facturas' : [
{
'numero' : f.numero,
'fecha' : f.fecha.isoformat(),
'total' : float (f.total)
}
for f in facturas[: 100 ] # Limit for JSON size
]
}
reporte.set_datos(datos)
reporte.generado = True
reporte.save()
Query Reports
from reportes.models import Reporte
# Get all sales reports
ventas_reports = Reporte.objects.filter( tipo = 'ventas' )
# Get monthly reports for current user
monthly_reports = Reporte.objects.filter(
creado_por = request.user,
periodo = 'mensual'
).order_by( '-fecha_creacion' )
# Get generated reports only
generated = Reporte.objects.filter(
generado = True ,
archivo__isnull = False
)
# Check for outdated reports
outdated = [r for r in Reporte.objects.all() if r.esta_vencido]
Retrieve Report Data
reporte = Reporte.objects.get( id = report_id)
# Get stored data
datos = reporte.get_datos()
if datos:
print ( f "Total Ventas: $ { datos.get( 'total_ventas' , 0 ) } " )
print ( f "Número de Facturas: { datos.get( 'num_facturas' , 0 ) } " )
# Access facturas list
for factura in datos.get( 'facturas' , []):
print ( f "Factura { factura[ 'numero' ] } : $ { factura[ 'total' ] } " )
Report Generation Workflow
Complete Generation Example
from reportes.models import Reporte
from reportes.utils import generar_pdf_ventas, generar_excel_ventas
from django.core.files.base import ContentFile
import io
def generar_reporte_completo ( reporte_id ):
"""Generate complete report with file"""
reporte = Reporte.objects.get( id = reporte_id)
# 1. Collect data
datos = collect_report_data(reporte)
reporte.set_datos(datos)
# 2. Generate file based on format
if reporte.formato == 'pdf' :
buffer = generar_pdf_ventas(datos)
filename = f " { reporte.nombre } .pdf"
elif reporte.formato == 'excel' :
buffer = generar_excel_ventas(datos)
filename = f " { reporte.nombre } .xlsx"
else : # csv
buffer = generar_csv_ventas(datos)
filename = f " { reporte.nombre } .csv"
# 3. Save file
reporte.archivo.save(filename, ContentFile(buffer.getvalue()))
reporte.generado = True
reporte.save()
return reporte
def collect_report_data ( reporte ):
"""Collect data based on report type"""
if reporte.tipo == 'ventas' :
return collect_ventas_data(reporte)
elif reporte.tipo == 'inventario' :
return collect_inventario_data(reporte)
elif reporte.tipo == 'gastos' :
return collect_gastos_data(reporte)
# ... other types
Report Type Specific Data
Sales Report Data
def collect_ventas_data ( reporte ):
from tables.models import Factura
from django.db.models import Sum, Avg, Count
facturas = Factura.objects.filter(
fecha__range = [reporte.fecha_inicio, reporte.fecha_fin]
)
return {
'total_ventas' : float (facturas.aggregate(Sum( 'total' ))[ 'total' ] or 0 ),
'num_facturas' : facturas.count(),
'promedio_venta' : float (facturas.aggregate(Avg( 'total' ))[ 'total__avg' ] or 0 ),
'ventas_por_dia' : get_daily_sales(facturas),
'facturas' : [serialize_factura(f) for f in facturas]
}
Inventory Report Data
def collect_inventario_data ( reporte ):
from products.models import Producto, Stock
productos = Producto.objects.filter( activo = True )
return {
'total_productos' : productos.count(),
'valor_inventario' : float (productos.aggregate(
total = Sum( 'precio_compra' * 'stock' )
)[ 'total' ] or 0 ),
'productos_bajo_stock' : productos.filter( stock__lt = 10 ).count(),
'productos' : [
{
'nombre' : p.nombre,
'stock' : p.stock,
'precio_venta' : float (p.precio_venta),
'categoria' : p.id_categoria.nombre_categoria if p.id_categoria else None
}
for p in productos
]
}
Expenses Report Data
def collect_gastos_data ( reporte ):
from expenses.models import Expense
from django.db.models import Sum, Count
gastos = Expense.objects.filter(
date__range = [reporte.fecha_inicio, reporte.fecha_fin]
)
by_category = gastos.values( 'category__name' ).annotate(
total = Sum( 'amount' ),
count = Count( 'id' )
)
return {
'total_gastos' : float (gastos.aggregate(Sum( 'amount' ))[ 'amount__sum' ] or 0 ),
'num_gastos' : gastos.count(),
'por_categoria' : [
{
'categoria' : item[ 'category__name' ],
'total' : float (item[ 'total' ]),
'cantidad' : item[ 'count' ]
}
for item in by_category
]
}
Custom Permissions
The Reporte model defines custom permissions:
from django.contrib.auth.models import User
# Check if user can export reports
if user.has_perm( 'reportes.exportar_reporte' ):
# Allow export
pass
# Check if user can generate automatic reports
if user.has_perm( 'reportes.generar_reporte' ):
# Allow automatic generation
pass
Scheduled Report Generation
Use Django management command or Celery task:
# management/commands/generar_reportes_automaticos.py
from django.core.management.base import BaseCommand
from reportes.models import Reporte
from datetime import date, timedelta
class Command ( BaseCommand ):
def handle ( self , * args , ** options ):
# Generate monthly reports on first day of month
if date.today().day == 1 :
last_month_start = date.today().replace( day = 1 ) - timedelta( days = 1 )
last_month_start = last_month_start.replace( day = 1 )
last_month_end = date.today().replace( day = 1 ) - timedelta( days = 1 )
for tipo in [ 'ventas' , 'gastos' , 'inventario' ]:
reporte = Reporte.objects.create(
nombre = f "Reporte { tipo.title() } - { last_month_start.strftime( '%B %Y' ) } " ,
tipo = tipo,
periodo = 'mensual' ,
formato = 'pdf' ,
fecha_inicio = last_month_start,
fecha_fin = last_month_end
)
generar_reporte_completo(reporte.id)
Reports Feature User guide for report generation
API Overview REST API endpoints