Subir archivos a "/"

This commit is contained in:
2025-12-23 16:54:07 +00:00
commit b02694d9ff
222 changed files with 17869 additions and 0 deletions

175
timbres.py Normal file
View File

@@ -0,0 +1,175 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from app.database import get_db
from app.models import Cliente, SubCliente, MovimientoTimbre, Usuario
from app.models.enums import TipoMovimiento, EstadoCliente
from app.schemas import (
MovimientoCreate, MovimientoResponse, ConsumoTimbreCreate, MessageResponse
)
from app.dependencies import get_current_user
router = APIRouter()
@router.post("/consumir/{cliente_id}", response_model=MessageResponse)
def consumir_timbre_cliente(
cliente_id: int,
consumo: ConsumoTimbreCreate,
db: Session = Depends(get_db),
current_user: Usuario = Depends(get_current_user)
):
"""
Consumir timbres directamente del cliente (sin subcliente)
"""
cliente = db.query(Cliente).filter(Cliente.id == cliente_id).first()
if not cliente:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cliente no encontrado"
)
# Verificar que el cliente esté activo
if cliente.estado != EstadoCliente.ACTIVO:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"El cliente está {cliente.estado}"
)
# Obtener timbres disponibles calculados
timbres_disponibles = cliente.get_timbres_disponibles(db)
# Verificar que hay timbres disponibles
if timbres_disponibles < consumo.cantidad:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Timbres insuficientes. Disponibles: {timbres_disponibles}, Solicitados: {consumo.cantidad}"
)
# Realizar el consumo
cliente.timbres_consumidos += consumo.cantidad
# Calcular nuevo balance
nuevo_balance = cliente.get_timbres_disponibles(db)
# Registrar movimiento
movimiento = MovimientoTimbre(
cliente_id=cliente.id,
tipo=TipoMovimiento.CONSUMO,
cantidad=consumo.cantidad,
descripcion=consumo.descripcion,
referencia_externa=consumo.referencia_externa,
balance_cliente=nuevo_balance
)
db.add(movimiento)
db.commit()
return {
"message": f"Se consumieron {consumo.cantidad} timbre(s) exitosamente",
"detail": {
"cliente": cliente.nombre,
"timbres_disponibles": nuevo_balance,
"timbres_consumidos": cliente.timbres_consumidos
}
}
@router.get("/historial/{cliente_id}", response_model=List[MovimientoResponse])
def obtener_historial_cliente(
cliente_id: int,
skip: int = 0,
limit: int = 100,
tipo: TipoMovimiento = None,
db: Session = Depends(get_db),
current_user: Usuario = Depends(get_current_user)
):
"""
Obtener el historial de movimientos de un cliente
"""
cliente = db.query(Cliente).filter(Cliente.id == cliente_id).first()
if not cliente:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Cliente no encontrado"
)
query = db.query(MovimientoTimbre).filter(MovimientoTimbre.cliente_id == cliente_id)
if tipo:
query = query.filter(MovimientoTimbre.tipo == tipo)
movimientos = query.order_by(MovimientoTimbre.created_at.desc()).offset(skip).limit(limit).all()
return movimientos
@router.get("/historial/subcliente/{subcliente_id}", response_model=List[MovimientoResponse])
def obtener_historial_subcliente(
subcliente_id: int,
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db),
current_user: Usuario = Depends(get_current_user)
):
"""
Obtener el historial de movimientos de un subcliente
"""
subcliente = db.query(SubCliente).filter(SubCliente.id == subcliente_id).first()
if not subcliente:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="SubCliente no encontrado"
)
movimientos = db.query(MovimientoTimbre).filter(
MovimientoTimbre.subcliente_id == subcliente_id
).order_by(MovimientoTimbre.created_at.desc()).offset(skip).limit(limit).all()
return movimientos
@router.get("/{movimiento_id}", response_model=MovimientoResponse)
def obtener_movimiento(
movimiento_id: int,
db: Session = Depends(get_db),
current_user: Usuario = Depends(get_current_user)
):
"""
Obtener un movimiento específico por ID
"""
movimiento = db.query(MovimientoTimbre).filter(MovimientoTimbre.id == movimiento_id).first()
if not movimiento:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Movimiento no encontrado"
)
return movimiento
@router.get("/referencia/{referencia}", response_model=MovimientoResponse)
def obtener_movimiento_por_referencia(
referencia: str,
db: Session = Depends(get_db),
current_user: Usuario = Depends(get_current_user)
):
"""
Obtener un movimiento por su referencia externa
"""
movimiento = db.query(MovimientoTimbre).filter(
MovimientoTimbre.referencia_externa == referencia
).first()
if not movimiento:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Movimiento no encontrado"
)
return movimiento