gnit-api / app /models.py
Laevateinn707's picture
Sync backend: FK idempotentes + tablas financieras en startup; relaciones usuarios/cotizaciones
6e394e9
Raw
History Blame Contribute Delete
16.9 kB
import enum
from datetime import datetime, date
from sqlalchemy import (
Column, Integer, String, Text, Boolean, Numeric,
DateTime, Date, BigInteger, ForeignKey, Interval,
CheckConstraint
)
from sqlalchemy.orm import relationship
from app.database import Base
# ── Enums ──────────────────────────────────────────────────────────────────
class TipoMiembroEnum(str, enum.Enum):
comprometido = "Comprometido"
registrado = "Registrado"
voluntario = "Voluntario"
class CotizacionEstadoEnum(str, enum.Enum):
pendiente = "pendiente"
aprobado = "aprobado"
rechazado = "rechazado"
class EstadoPresenciaMisionEnum(str, enum.Enum):
con_iglesia = "Con iglesia"
evangelizado = "Evangelizado"
en_proceso = "En proceso"
class CuentaTipoEnum(str, enum.Enum):
banco = "Banco"
caja = "Caja"
class TipoSangreEnum(str, enum.Enum):
a_positivo = "A+"
a_negativo = "A-"
b_positivo = "B+"
b_negativo = "B-"
ab_positivo = "AB+"
ab_negativo = "AB-"
o_positivo = "O+"
o_negativo = "O-"
# ── Models ─────────────────────────────────────────────────────────────────
class Pais(Base):
__tablename__ = "paises"
id = Column(Integer, primary_key=True)
iso = Column(String(2))
nombre = Column(String(100), nullable=False)
continente_id = Column(Integer, ForeignKey("continentes.id", ondelete="SET NULL"))
miembros = relationship("Miembro", back_populates="pais_rel")
contactos = relationship("Contacto", back_populates="pais_rel")
reportes = relationship("Reporte", back_populates="pais_rel")
presupuestos = relationship("Presupuesto", back_populates="pais_rel")
ejecuciones = relationship("Ejecucion", back_populates="pais_rel")
estadisticas = relationship("EstadisticaPais", back_populates="pais_rel")
ciudades = relationship("Ciudad", back_populates="pais_rel")
ingresos = relationship("Ingreso", back_populates="pais_rel")
saldos = relationship("SaldoCajaBanco", back_populates="pais_rel")
traslados = relationship("Traslado", back_populates="pais_rel")
continente_rel = relationship("Continente", back_populates="paises")
class Ciudad(Base):
__tablename__ = "ciudades"
id = Column(Integer, primary_key=True)
nombre = Column(String(100), nullable=False)
nombre_ascii = Column(String(100))
lat = Column(Numeric(10, 7))
lng = Column(Numeric(10, 7))
pais_iso2 = Column(String(2), ForeignKey("paises.iso", ondelete="SET NULL"))
admin_name = Column(String(100))
capital = Column(String(20))
population = Column(BigInteger)
worldcity_id = Column(BigInteger)
pais_rel = relationship("Pais", back_populates="ciudades")
miembros = relationship("Miembro", back_populates="ciudad_rel")
contactos = relationship("Contacto", back_populates="ciudad_rel")
reportes = relationship("Reporte", back_populates="ciudad_rel")
misiones = relationship("CiudadMision", back_populates="ciudad_rel")
class Rol(Base):
__tablename__ = "roles"
id = Column(Integer, primary_key=True)
nombre = Column(String(30), nullable=False, default="")
descripcion = Column(String(100))
permisos = relationship("RolPermiso", back_populates="rol")
usuarios = relationship("Usuario", back_populates="rol_rel")
class RolPermiso(Base):
__tablename__ = "rol_permisos"
rol_id = Column(Integer, ForeignKey("roles.id"), primary_key=True)
permiso_id = Column(Integer, primary_key=True)
activo = Column(Boolean, default=True)
rol = relationship("Rol", back_populates="permisos")
class UsuarioPermiso(Base):
__tablename__ = "usuario_permisos"
id = Column(Integer, primary_key=True, index=True)
usuario_id = Column(String(30), ForeignKey("public.usuarios.id", ondelete="CASCADE"), nullable=False)
permiso_id = Column(Integer, nullable=False)
tiene_acceso = Column(Boolean, default=True)
class Usuario(Base):
__tablename__ = "usuarios"
id = Column(String(30), primary_key=True)
nombre = Column(Text, nullable=False)
email = Column(Text, nullable=False, unique=True)
password_hash = Column(Text, nullable=False)
rol = Column(Integer, ForeignKey("roles.id"), nullable=False)
fecha_registro = Column(DateTime, default=datetime.utcnow, nullable=False)
activo = Column(Boolean, default=False, nullable=False)
region = Column(String(20), nullable=True)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"))
miembro_id = Column(String(30), ForeignKey("miembros.id", ondelete="SET NULL"))
rol_rel = relationship("Rol", back_populates="usuarios")
pais_rel = relationship("Pais")
ciudad_rel = relationship("Ciudad")
miembro_rel = relationship("Miembro", foreign_keys=[miembro_id], primaryjoin="Usuario.miembro_id == Miembro.id")
class Miembro(Base):
__tablename__ = "miembros"
id = Column(String(30), primary_key=True)
nombre = Column(Text, nullable=False)
identidad = Column(String(30))
pais = Column(Text)
ciudad = Column(Text)
edad = Column(Integer)
evangelizado_por = Column(Text)
estado_civil = Column(Text)
profesion = Column(Text)
comentarios = Column(Text)
tipo_miembro = Column(String(20), nullable=False)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"))
cargo_funcion = Column(Text, nullable=True)
ministerio_of = Column(Text, nullable=True)
avance_audio = Column(Text, nullable=True)
pais_rel = relationship("Pais", back_populates="miembros")
ciudad_rel = relationship("Ciudad", back_populates="miembros")
contactos = relationship("Contacto", back_populates="miembro_rel")
reportes = relationship("Reporte", back_populates="miembro_rel")
cotizaciones = relationship("Cotizacion", back_populates="miembro_rel")
info_adicional = relationship("MiembroInfoAdicional", back_populates="miembro_rel", uselist=False)
estudios_diarios = relationship("EstudioDiario", back_populates="miembro_rel")
class Contacto(Base):
__tablename__ = "contactos"
id = Column(Integer, primary_key=True)
miembro_responsable = Column(Text, nullable=False)
nombre = Column(Text, nullable=False)
telefono = Column(Text)
pais = Column(Text)
notas = Column(Text)
profesion = Column(Text)
fecha_creacion = Column(DateTime, default=datetime.utcnow)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
miembro_responsable_id = Column(String(30), ForeignKey("miembros.id", ondelete="SET NULL"))
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"))
pais_rel = relationship("Pais", back_populates="contactos")
ciudad_rel = relationship("Ciudad", back_populates="contactos")
miembro_rel = relationship("Miembro", back_populates="contactos")
class Reporte(Base):
__tablename__ = "reportes"
id = Column(Integer, primary_key=True)
miembro_que_reporta = Column(Text, nullable=False)
fecha = Column(Date, nullable=False)
tiempo_evangelizacion = Column(Interval)
contactos_obtenidos = Column(Integer, default=0)
contactos_estudian = Column(Integer, default=0)
numero_estudios_dados = Column(Integer, default=0)
total_estudiantes = Column(Integer, default=0)
pais = Column(Text)
fecha_creacion = Column(DateTime, default=datetime.utcnow)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
miembro_id = Column(String(30), ForeignKey("miembros.id", ondelete="SET NULL"))
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"))
pais_rel = relationship("Pais", back_populates="reportes")
ciudad_rel = relationship("Ciudad", back_populates="reportes")
miembro_rel = relationship("Miembro", back_populates="reportes")
class Cotizacion(Base):
__tablename__ = "cotizaciones"
id = Column(Integer, primary_key=True)
fecha = Column(Date, nullable=False)
solicitante = Column(Text, nullable=False)
concepto = Column(Text, nullable=False)
monto = Column(Numeric(15, 2), nullable=False)
moneda = Column(String(10), default="USD", nullable=False)
estado = Column(String(20), default="pendiente", nullable=False)
agregado_a_gastos = Column(Boolean, default=False, nullable=False)
mes_agregado = Column(Integer)
anio_agregado = Column(Integer)
notas = Column(Text)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow, nullable=False)
miembro_id = Column(String(30), ForeignKey("miembros.id", ondelete="SET NULL"))
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"))
miembro_rel = relationship("Miembro", back_populates="cotizaciones")
pais_rel = relationship("Pais")
ciudad_rel = relationship("Ciudad")
class Presupuesto(Base):
__tablename__ = "presupuestos"
id = Column(Integer, primary_key=True)
pais = Column(String(100), nullable=False)
mes = Column(Integer)
anio = Column(Integer, nullable=False)
tipo_gasto = Column(String(100), nullable=False)
concepto = Column(Text)
monto = Column(Numeric(15, 2), nullable=False)
moneda = Column(String(10), nullable=False)
tasa_cambio = Column(Numeric(15, 6))
notas = Column(Text)
fecha_registro = Column(DateTime, default=datetime.utcnow)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
pais_rel = relationship("Pais", back_populates="presupuestos")
ejecuciones = relationship("Ejecucion", back_populates="presupuesto_rel")
class Ejecucion(Base):
__tablename__ = "ejecuciones"
id = Column(Integer, primary_key=True)
pais = Column(String(100), nullable=False)
mes = Column(Integer, nullable=False)
anio = Column(Integer, nullable=False)
monto_recibido_usd = Column(Numeric(15, 2), nullable=False)
presupuesto_id = Column(Integer, ForeignKey("presupuestos.id", ondelete="SET NULL"))
notas = Column(Text)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow, nullable=False)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
pais_rel = relationship("Pais", back_populates="ejecuciones")
presupuesto_rel = relationship("Presupuesto", back_populates="ejecuciones")
gastos = relationship("GastoReal", back_populates="ejecucion_rel", cascade="all, delete")
class GastoReal(Base):
__tablename__ = "gastos_reales"
id = Column(Integer, primary_key=True)
ejecucion_id = Column(Integer, ForeignKey("ejecuciones.id", ondelete="CASCADE"), nullable=False)
concepto = Column(Text, nullable=False)
monto = Column(Numeric(15, 2), nullable=False)
tipo_gasto = Column(String(100), nullable=False)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
ejecucion_rel = relationship("Ejecucion", back_populates="gastos")
class EstadisticaPais(Base):
__tablename__ = "estadisticas_paises"
id = Column(Integer, primary_key=True)
nombre_pais = Column(String(100), nullable=False)
cantidad_miembros = Column(Integer, default=0)
cantidad_estudios = Column(Integer, default=0)
cantidad_reportes = Column(Integer, default=0)
color = Column(String(20))
mes = Column(Integer)
anio = Column(Integer, nullable=False)
fecha_creacion = Column(DateTime, default=datetime.utcnow)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
pais_rel = relationship("Pais", back_populates="estadisticas")
class Configuracion(Base):
__tablename__ = "configuracion"
id = Column(Integer, primary_key=True)
clave = Column(String(100), nullable=False, unique=True)
valor = Column(Text, nullable=False)
descripcion = Column(Text)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow, nullable=False)
class CiudadMision(Base):
__tablename__ = "ciudades_mision"
id = Column(Integer, primary_key=True)
ciudad_id = Column(Integer, ForeignKey("ciudades.id", ondelete="SET NULL"), nullable=False)
region = Column(String(150))
estado_presencia = Column(String(30), nullable=False, default="En proceso")
fecha_inicio_trabajo = Column(Date)
pastor_encargado_id = Column(String(30), ForeignKey("miembros.id", ondelete="SET NULL"))
pastor_encargado_nombre = Column(Text)
cantidad_miembros_activos = Column(Integer, default=0)
notas = Column(Text)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow, nullable=False)
ciudad_rel = relationship("Ciudad", back_populates="misiones")
pastor_rel = relationship("Miembro", foreign_keys=[pastor_encargado_id])
class Ingreso(Base):
__tablename__ = "ingresos"
id = Column(Integer, primary_key=True)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
mes = Column(Integer, nullable=False)
anio = Column(Integer, nullable=False)
tipo = Column(String(100), nullable=False)
origen = Column(Text)
donde_ingresa = Column(String(10), nullable=False)
valor = Column(Numeric(15, 2), nullable=False)
observaciones = Column(Text)
fecha = Column(Date, nullable=False)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
pais_rel = relationship("Pais", back_populates="ingresos")
class MiembroInfoAdicional(Base):
__tablename__ = "miembros_info_adicional"
id = Column(String(30), ForeignKey("miembros.id", ondelete="CASCADE"), primary_key=True)
nombre_padre = Column(Text)
telefono_padre = Column(String(30))
nombre_madre = Column(Text)
telefono_madre = Column(String(30))
tipo_sangre = Column(String(5))
correo_electronico = Column(String(255))
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
fecha_actualizacion = Column(DateTime, default=datetime.utcnow, nullable=False)
miembro_rel = relationship("Miembro", back_populates="info_adicional")
class SaldoCajaBanco(Base):
__tablename__ = "saldos_caja_banco"
id = Column(Integer, primary_key=True)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
saldo_caja = Column(Numeric(15, 2), nullable=False, default=0)
saldo_banco = Column(Numeric(15, 2), nullable=False, default=0)
updated_at = Column(DateTime, default=datetime.utcnow, nullable=False)
pais_rel = relationship("Pais", back_populates="saldos")
class Traslado(Base):
__tablename__ = "traslados"
id = Column(Integer, primary_key=True)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
de = Column(String(10), nullable=False)
a = Column(String(10), nullable=False)
valor = Column(Numeric(15, 2), nullable=False)
observaciones = Column(Text)
fecha = Column(Date, nullable=False)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
pais_rel = relationship("Pais", back_populates="traslados")
class Continente(Base):
__tablename__ = "continentes"
id = Column(Integer, primary_key=True)
nombre = Column(String(100), nullable=False, unique=True)
paises = relationship("Pais", back_populates="continente_rel")
class EstudioDiario(Base):
__tablename__ = "estudios_diarios"
id = Column(Integer, primary_key=True)
miembro_id = Column(String(30), ForeignKey("miembros.id", ondelete="CASCADE"), nullable=False)
pais_id = Column(Integer, ForeignKey("paises.id", ondelete="SET NULL"))
contacto_id = Column(Integer, ForeignKey("contactos.id", ondelete="SET NULL"))
mes = Column(Integer, nullable=False)
anio = Column(Integer, nullable=False)
dia = Column(Integer, nullable=False)
capitulo = Column(String(255))
horas = Column(Numeric(5, 2))
tipo = Column(String(50))
donde = Column(String(255))
dijeron_si = Column(Integer, default=0)
nuevos_contactos = Column(Integer, default=0)
fecha_creacion = Column(DateTime, default=datetime.utcnow, nullable=False)
miembro_rel = relationship("Miembro", back_populates="estudios_diarios")
pais_rel = relationship("Pais")
contacto_rel = relationship("Contacto")