176 lines
5.4 KiB
Python
176 lines
5.4 KiB
Python
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
|
|
|