Skip to content

Commit

Permalink
Merge pull request #29 from ricval/blueprint-domicilios
Browse files Browse the repository at this point in the history
Blueprint domicilios
  • Loading branch information
guivaloz authored Sep 5, 2024
2 parents 83c76ee + 37a8fd8 commit dccf809
Show file tree
Hide file tree
Showing 16 changed files with 516 additions and 12 deletions.
4 changes: 4 additions & 0 deletions orion/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from orion.blueprints.carreras.views import carreras
from orion.blueprints.centros_trabajos.views import centros_trabajos
from orion.blueprints.distritos.views import distritos
from orion.blueprints.domicilios.views import domicilios
from orion.blueprints.entradas_salidas.views import entradas_salidas
from orion.blueprints.historial_academicos.views import historial_academicos
from orion.blueprints.historial_puestos.views import historial_puestos
Expand All @@ -25,6 +26,7 @@
from orion.blueprints.organos.views import organos
from orion.blueprints.permisos.views import permisos
from orion.blueprints.personas.views import personas
from orion.blueprints.personas_domicilios.views import personas_domicilios
from orion.blueprints.puestos.views import puestos
from orion.blueprints.puestos_funciones.views import puestos_funciones
from orion.blueprints.roles.views import roles
Expand Down Expand Up @@ -58,6 +60,7 @@ def create_app():
app.register_blueprint(carreras)
app.register_blueprint(centros_trabajos)
app.register_blueprint(distritos)
app.register_blueprint(domicilios)
app.register_blueprint(entradas_salidas)
app.register_blueprint(historial_academicos)
app.register_blueprint(historial_puestos)
Expand All @@ -68,6 +71,7 @@ def create_app():
app.register_blueprint(organos)
app.register_blueprint(permisos)
app.register_blueprint(personas)
app.register_blueprint(personas_domicilios)
app.register_blueprint(puestos)
app.register_blueprint(puestos_funciones)
app.register_blueprint(roles)
Expand Down
Empty file.
22 changes: 22 additions & 0 deletions orion/blueprints/domicilios/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Domicilios, formularios
"""

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, IntegerField
from wtforms.validators import DataRequired, Length, Optional


class DomicilioForm(FlaskForm):
"""Formulario Domicilio"""

persona = StringField("Persona") # ReadOnly
calle = StringField("Calle", validators=[DataRequired(), Length(max=128)])
numero_exterior = StringField("Número Exterior", validators=[DataRequired(), Length(max=16)])
numero_interior = StringField("Número Interior", validators=[Optional(), Length(max=16)])
colonia = StringField("Colonia", validators=[DataRequired(), Length(max=64)])
municipio = StringField("Municipio", validators=[DataRequired(), Length(max=64)])
estado = StringField("Estado", validators=[DataRequired(), Length(max=64)])
pais = StringField("País", validators=[DataRequired(), Length(max=64)])
codigo_postal = StringField("Código Postal", validators=[Optional()])
guardar = SubmitField("Guardar")
59 changes: 59 additions & 0 deletions orion/blueprints/domicilios/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
Domicilios, modelos
"""

from typing import List

from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column, relationship

from lib.universal_mixin import UniversalMixin
from orion.extensions import database


class Domicilio(database.Model, UniversalMixin):
"""Domicilio"""

# Nombre de la tabla
__tablename__ = "domicilios"

# Clave primaria
id: Mapped[int] = mapped_column(primary_key=True)

# Columnas
estado: Mapped[str] = mapped_column(String(64))
municipio: Mapped[str] = mapped_column(String(64))
pais: Mapped[str] = mapped_column(String(64))
calle: Mapped[str] = mapped_column(String(256))
num_ext: Mapped[str] = mapped_column(String(16))
num_int: Mapped[str] = mapped_column(String(16))
colonia: Mapped[str] = mapped_column(String(256))
cp: Mapped[str] = mapped_column(String(5), default="00000")
completo: Mapped[str] = mapped_column(String(1024))

# Hijos
personas_domicilios: Mapped[List["PersonaDomicilio"]] = relationship(back_populates="domicilio")
# familiares = db.relationship("PersonaFamiliar", back_populates="domicilio")

def elaborar_completo(self):
"""Elaborar completo"""
elementos = []
if self.calle and self.num_ext and self.num_int:
elementos.append(f"{self.calle} #{self.num_ext}-{self.num_int}")
elif self.calle and self.num_ext:
elementos.append(f"{self.calle} #{self.num_ext}")
elif self.calle:
elementos.append(self.calle)
if self.colonia:
elementos.append(self.colonia)
if self.municipio:
elementos.append(self.municipio)
if self.estado and self.cp > 0:
elementos.append(f"{self.estado}, C.P. {self.cp}")
elif self.estado:
elementos.append(self.estado)
return ", ".join(elementos)

def __repr__(self):
"""Representación"""
return f"<Domicilio {self.id}>"
27 changes: 27 additions & 0 deletions orion/blueprints/domicilios/templates/domicilios/edit.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends 'layouts/app.jinja2' %}
{% import 'macros/form.jinja2' as f with context %}
{% import 'macros/topbar.jinja2' as topbar %}

{% block title %}Editar Domicilio{% endblock %}

{% block topbar_actions %}
{{ topbar.page('Editar Domicilio') }}
{% endblock %}

{% block content %}
{% call f.card() %}
{% set form_kwargs = {'domicilio_id': domicilio.id, 'persona_id': persona.id} %}
{% call f.form_tag('domicilios.edit', fid='domicilio_form', **form_kwargs) %}
{% call f.form_group(form.persona, readonly=true) %}{% endcall %}
{% call f.form_group(form.calle) %}{% endcall %}
{% call f.form_group(form.numero_exterior) %}{% endcall %}
{% call f.form_group(form.numero_interior) %}{% endcall %}
{% call f.form_group(form.colonia) %}{% endcall %}
{% call f.form_group(form.municipio) %}{% endcall %}
{% call f.form_group(form.estado) %}{% endcall %}
{% call f.form_group(form.pais) %}{% endcall %}
{% call f.form_group(form.codigo_postal) %}{% endcall %}
{% call f.form_group(form.guardar) %}{% endcall %}
{% endcall %}
{% endcall %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends 'layouts/app.jinja2' %}
{% import 'macros/form.jinja2' as f with context %}
{% import 'macros/topbar.jinja2' as topbar %}

{% block title %}Nuevo Domicilio{% endblock %}

{% block topbar_actions %}
{{ topbar.page('Nuevo Domicilio') }}
{% endblock %}

{% block content %}
{% call f.card() %}
{% set form_kwargs = {'persona_id': persona.id} %}
{% call f.form_tag('domicilios.new_with_persona_id', fid='domicilio_form', **form_kwargs) %}
{% call f.form_group(form.persona, readonly=true) %}{% endcall %}
{% call f.form_group(form.calle) %}{% endcall %}
{% call f.form_group(form.numero_exterior) %}{% endcall %}
{% call f.form_group(form.numero_interior) %}{% endcall %}
{% call f.form_group(form.colonia) %}{% endcall %}
{% call f.form_group(form.municipio) %}{% endcall %}
{% call f.form_group(form.estado) %}{% endcall %}
{% call f.form_group(form.pais) %}{% endcall %}
{% call f.form_group(form.codigo_postal) %}{% endcall %}
{% call f.form_group(form.guardar) %}{% endcall %}
{% endcall %}
{% endcall %}
{% endblock %}
157 changes: 157 additions & 0 deletions orion/blueprints/domicilios/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""
Domicilios, vistas
"""

import json
from flask import Blueprint, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required

from lib.datatables import get_datatable_parameters, output_datatable_json
from lib.safe_string import safe_string, safe_message

from orion.blueprints.bitacoras.models import Bitacora
from orion.blueprints.modulos.models import Modulo
from orion.blueprints.permisos.models import Permiso
from orion.blueprints.usuarios.decorators import permission_required
from orion.blueprints.domicilios.models import Domicilio
from orion.blueprints.domicilios.forms import DomicilioForm
from orion.blueprints.personas.models import Persona
from orion.blueprints.personas_domicilios.models import PersonaDomicilio

MODULO = "DOMICILIOS"

domicilios = Blueprint("domicilios", __name__, template_folder="templates")


@domicilios.before_request
@login_required
@permission_required(MODULO, Permiso.VER)
def before_request():
"""Permiso por defecto"""


@domicilios.route("/domicilios/<int:domicilio_id>")
def detail(domicilio_id):
"""Detalle de un Domicilio"""
domicilio = Domicilio.query.get_or_404(domicilio_id)
return render_template("domicilios/detail.jinja2", domicilio=domicilio)


@domicilios.route("/domicilios/<int:persona_id>")
def detail_with_persona_id(persona_id):
"""Detalle de un Domicilio de una Persona"""
domicilio = Domicilio.query.filter(persona_id=persona_id).first()
return render_template("domicilios/detail.jinja2", domicilio=domicilio)


# NEW TODO:
@domicilios.route("/domicilios/nuevo_con_persona/<int:persona_id>", methods=["GET", "POST"])
@permission_required(MODULO, Permiso.CREAR)
def new_with_persona_id(persona_id):
"""Nuevo Domicilio"""
persona = Persona.query.get_or_404(persona_id)
form = DomicilioForm()
if form.validate_on_submit():
domicilio = Domicilio(
calle=safe_string(form.calle.data, save_enie=True),
num_ext=safe_string(form.numero_exterior.data),
num_int=safe_string(form.numero_interior.data),
colonia=safe_string(form.colonia.data, save_enie=True),
municipio=safe_string(form.municipio.data, save_enie=True),
estado=safe_string(form.estado.data, save_enie=True),
pais=safe_string(form.pais.data, save_enie=True),
cp=form.codigo_postal.data,
completo="",
)
domicilio.save()
# Crear la relación de muchos a muchos
PersonaDomicilio(
persona=persona,
domicilio=domicilio,
).save()
# Guardar en bitacora
bitacora = Bitacora(
modulo=Modulo.query.filter_by(nombre=MODULO).first(),
usuario=current_user,
descripcion=safe_message(f"Nuevo Domicilio {domicilio.calle}"),
url=url_for("domicilios.detail", domicilio_id=domicilio.id),
)
bitacora.save()
flash(bitacora.descripcion, "success")
return redirect(url_for("personas.detail_section", seccion="domicilios", persona_id=persona.id))
form.persona.data = persona.nombre_completo
return render_template("domicilios/new_with_persona_id.jinja2", form=form, persona=persona)


@domicilios.route("/domicilios/edicion/<int:persona_id>/<int:domicilio_id>", methods=["GET", "POST"])
@permission_required(MODULO, Permiso.MODIFICAR)
def edit(persona_id, domicilio_id):
"""Editar Domicilio"""
persona = Persona.query.get_or_404(persona_id)
domicilio = Domicilio.query.get_or_404(domicilio_id)
form = DomicilioForm()
if form.validate_on_submit():
domicilio.calle = safe_string(form.calle.data, save_enie=True)
domicilio.num_ext = safe_string(form.numero_exterior.data)
domicilio.num_int = safe_string(form.numero_interior.data)
domicilio.colonia = safe_string(form.colonia.data, save_enie=True)
domicilio.municipio = safe_string(form.municipio.data, save_enie=True)
domicilio.estado = safe_string(form.estado.data, save_enie=True)
domicilio.pais = safe_string(form.pais.data, save_enie=True)
domicilio.cp = form.codigo_postal.data
domicilio.save()
bitacora = Bitacora(
modulo=Modulo.query.filter_by(nombre=MODULO).first(),
usuario=current_user,
descripcion=safe_message(f"Editado Domicilio de {persona.nombre_completo}"),
url=url_for("domicilios.detail", domicilio_id=domicilio.id),
)
bitacora.save()
flash(bitacora.descripcion, "success")
return redirect(url_for("personas.detail_section", seccion="domicilios", persona_id=persona.id))
form.persona.data = persona.nombre_completo
form.calle.data = domicilio.calle
form.numero_exterior.data = domicilio.num_ext
form.numero_interior.data = domicilio.num_int
form.colonia.data = domicilio.colonia
form.municipio.data = domicilio.municipio
form.estado.data = domicilio.estado
form.pais.data = domicilio.pais
form.codigo_postal.data = domicilio.cp
return render_template("domicilios/edit.jinja2", form=form, persona=persona, domicilio=domicilio)


@domicilios.route("/domicilios/eliminar/<int:domicilio_id>")
@permission_required(MODULO, Permiso.ADMINISTRAR)
def delete(domicilio_id):
"""Eliminar Domicilio"""
domicilio = Domicilio.query.get_or_404(domicilio_id)
if domicilio.estatus == "A":
domicilio.delete()
bitacora = Bitacora(
modulo=Modulo.query.filter_by(nombre=MODULO).first(),
usuario=current_user,
descripcion=safe_message(f"Eliminado Domicilio {domicilio.id}"),
url=url_for("domicilios.detail", domicilio_id=domicilio.id),
)
bitacora.save()
flash(bitacora.descripcion, "success")
return redirect(url_for("domicilios.detail", domicilio_id=domicilio.id))


@domicilios.route("/domicilios/recuperar/<int:domicilio_id>")
@permission_required(MODULO, Permiso.ADMINISTRAR)
def recover(domicilio_id):
"""Recuperar Domicilio"""
domicilio = Domicilio.query.get_or_404(domicilio_id)
if domicilio.estatus == "B":
domicilio.recover()
bitacora = Bitacora(
modulo=Modulo.query.filter_by(nombre=MODULO).first(),
usuario=current_user,
descripcion=safe_message(f"Recuperado Domicilio {domicilio.id}"),
url=url_for("domicilios.detail", domicilio_id=domicilio.id),
)
bitacora.save()
flash(bitacora.descripcion, "success")
return redirect(url_for("domicilios.detail", domicilio_id=domicilio.id))
30 changes: 30 additions & 0 deletions orion/blueprints/personas/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
Personas, formularios
"""

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, IntegerField
from wtforms.validators import DataRequired, Length, Optional


class PersonaForm(FlaskForm):
"""Formulario Persona"""

clave = StringField("Clave", validators=[DataRequired(), Length(max=16)])
descripcion = StringField("Descripción", validators=[DataRequired(), Length(max=256)])
guardar = SubmitField("Guardar")


class PersonaEditDomicilioFiscalForm(FlaskForm):
"""Editar el Domicilio Fiscal de una Persona"""

persona = StringField("Persona") # ReadOnly
calle = StringField("Calle", validators=[DataRequired(), Length(max=128)])
numero_exterior = StringField("Número Exterior", validators=[DataRequired(), Length(max=16)])
numero_interior = StringField("Número Interior", validators=[Optional(), Length(max=16)])
colonia = StringField("Colonia", validators=[DataRequired(), Length(max=64)])
localidad = StringField("Localidad", validators=[DataRequired(), Length(max=64)])
municipio = StringField("Municipio", validators=[DataRequired(), Length(max=64)])
estado = StringField("Estado", validators=[DataRequired(), Length(max=64)])
codigo_postal = IntegerField("Código Postal", validators=[DataRequired()])
guardar = SubmitField("Guardar")
22 changes: 11 additions & 11 deletions orion/blueprints/personas/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,19 @@ class Persona(database.Model, UniversalMixin):
observaciones: Mapped[Optional[str]] = mapped_column(String(512))
observaciones_especiales: Mapped[Optional[str]] = mapped_column(String(512))

# TODO: Declarar columnas restantes
# Domicilio Fiscal
# domicilio_fiscal_calle = db.Column(db.String(128))
# domicilio_fiscal_numero_exterior = db.Column(db.String(16))
# domicilio_fiscal_numero_interior = db.Column(db.String(16))
# domicilio_fiscal_colonia = db.Column(db.String(64))
# domicilio_fiscal_localidad = db.Column(db.String(64))
# domicilio_fiscal_municipio = db.Column(db.String(64))
# domicilio_fiscal_estado = db.Column(db.String(64))
# domicilio_fiscal_cp = db.Column(db.Integer)
domicilio_fiscal_calle: Mapped[Optional[str]] = mapped_column(String(128))
domicilio_fiscal_numero_exterior: Mapped[Optional[str]] = mapped_column(String(16))
domicilio_fiscal_numero_interior: Mapped[Optional[str]] = mapped_column(String(16))
domicilio_fiscal_colonia: Mapped[Optional[str]] = mapped_column(String(64))
domicilio_fiscal_localidad: Mapped[Optional[str]] = mapped_column(String(64))
domicilio_fiscal_municipio: Mapped[Optional[str]] = mapped_column(String(64))
domicilio_fiscal_estado: Mapped[Optional[str]] = mapped_column(String(64))
domicilio_fiscal_cp: Mapped[Optional[int]]

# Datos Extra
fecha_baja: Mapped[date]
falta_papeleria: Mapped[bool] = mapped_column(default=False)
fecha_baja: Mapped[Optional[date]]
falta_papeleria: Mapped[Optional[bool]] = mapped_column(default=False)

# Hijos
# TODO: Conectar hijos
Expand All @@ -136,6 +135,7 @@ class Persona(database.Model, UniversalMixin):
# cursos = db.relationship("PersonaCurso", back_populates="persona")
# familiares = db.relationship("PersonaFamiliar", back_populates="persona")
# personas_domicilios = db.relationship("PersonaDomicilio", back_populates="persona")
personas_domicilios: Mapped[List["PersonaDomicilio"]] = relationship(back_populates="persona")
# personas_enfermedades = db.relationship("PersonaEnfermedad", back_populates="persona")
historial_puestos: Mapped[List["HistorialPuesto"]] = relationship(back_populates="persona")
historial_academicos: Mapped[List["HistorialAcademico"]] = relationship(back_populates="persona")
Expand Down
Loading

0 comments on commit dccf809

Please sign in to comment.