um monte de coisas

This commit is contained in:
Gabu Bellon
2025-01-08 00:19:49 -03:00
parent d6357803b8
commit 02147fd6cd
23 changed files with 660 additions and 148 deletions

262
.gitignore vendored Normal file
View File

@@ -0,0 +1,262 @@
# Created by https://www.toptal.com/developers/gitignore/api/python,flask
# Edit at https://www.toptal.com/developers/gitignore?templates=python,flask
### Flask ###
instance/*
!instance/.gitignore
.webassets-cache
.env
### Flask.Python Stack ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python ###
# Byte-compiled / optimized / DLL files
# C extensions
# Distribution / packaging
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
# Installer logs
# Unit test / coverage reports
# Translations
# Django stuff:
# Flask stuff:
# Scrapy stuff:
# Sphinx documentation
# PyBuilder
# Jupyter Notebook
# IPython
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
# Celery stuff
# SageMath parsed files
# Environments
# Spyder project settings
# Rope project settings
# mkdocs documentation
# mypy
# Pyre type checker
# pytype static type analyzer
# Cython debug symbols
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python,flask

5
Makefile Normal file
View File

@@ -0,0 +1,5 @@
install:
pip install -r requirements.txt
run:
python app.py

View File

@@ -1 +1,15 @@
# controles
## Para instalar
```bash
make install
```
## Para executar
```bash
make run
```
Acesse por: http://127.0.0.1:5000

337
app.py
View File

@@ -1,213 +1,262 @@
from flask import Flask, request, render_template, redirect, url_for, jsonify
from flask import Flask, request, render_template, redirect, url_for
from functions.database import execute_query
from functions.database import (
Base,
Militante,
CotaMensal,
TipoPagamento,
Pagamento,
MaterialVendido,
TipoMaterial,
VendaJornalAvulso,
engine,
AssinaturaAnual,
RelatorioCotasMensais,
RelatorioVendasMateriais,
engine,
)
from sqlalchemy import create_engine, and_
from sqlalchemy.orm import sessionmaker
from datetime import datetime
Session = sessionmaker(bind=engine)
session = Session()
app = Flask(__name__)
def session_run(model):
session.add(model)
try:
session.commit()
except Exception as e:
print(e)
session.rollback()
# Rota para criar um novo militante
@app.route('/militantes/novo', methods=['GET', 'POST'])
@app.route("/militantes/novo", methods=["GET", "POST"])
def novo_militante():
if request.method == 'POST':
nome = request.form['nome']
cpf = request.form['cpf']
email = request.form['email']
telefone = request.form['telefone']
endereco = request.form['endereco']
filiado = request.form.get('filiado', False)
if request.method == "POST":
novo_militante = Militante(
nome=request.form["nome"],
cpf=request.form["cpf"],
email=request.form["email"],
telefone=request.form["telefone"],
endereco=request.form["endereco"],
filiado=request.form.get("filiado", False),
)
query = '''
INSERT INTO militantes (nome, cpf, email, telefone, endereco, filiado)
VALUES (%s, %s, %s, %s, %s, %s)
'''
execute_query(query, (nome, cpf, email, telefone, endereco, filiado))
return redirect(url_for('listar_militantes'))
session_run(novo_militante)
# execute_query(query, (nome, cpf, email, telefone, endereco, filiado))
return redirect(url_for("listar_militantes"))
return render_template("novo_militante.html")
return render_template('novo_militante.html')
# Rota para listar militantes
@app.route('/militantes')
@app.route("/militantes")
def listar_militantes():
query = 'SELECT * FROM militantes'
militantes = execute_query(query)
return render_template('listar_militantes.html', militantes=militantes)
militantes = session.query(Militante).all()
return render_template("listar_militantes.html", militantes=militantes)
# Rota para criar uma nova cota mensal
@app.route('/cotas/novo', methods=['GET', 'POST'])
@app.route("/cotas/novo", methods=["GET", "POST"])
def nova_cota():
if request.method == 'POST':
militante_id = request.form['militante_id']
valor_antigo = request.form['valor_antigo']
valor_novo = request.form['valor_novo']
data_alteracao = request.form['data_alteracao']
if request.method == "POST":
cotas_mensais = CotaMensal(
militante_id=request.form["militante_id"],
valor_antigo=request.form["valor_antigo"],
valor_novo=request.form["valor_novo"],
data_alteracao=datetime.strptime(request.form["data_alteracao"], "%Y-%m-%d")
)
query = '''
INSERT INTO cotas_mensais (militante_id, valor_antigo, valor_novo, data_alteracao)
VALUES (%s, %s, %s, %s)
'''
execute_query(query, (militante_id, valor_antigo, valor_novo, data_alteracao))
return redirect(url_for('listar_cotas'))
session_run(cotas_mensais)
return redirect(url_for("listar_cotas"))
return render_template("nova_cota.html")
return render_template('nova_cota.html')
# Rota para listar cotas mensais
@app.route('/cotas')
@app.route("/cotas")
def listar_cotas():
query = 'SELECT * FROM cotas_mensais'
cotas = execute_query(query)
return render_template('listar_cotas.html', cotas=cotas)
cotas = session.query(CotaMensal).all()
return render_template("listar_cotas.html", cotas=cotas)
# Rota para criar um novo pagamento
@app.route('/pagamentos/novo', methods=['GET', 'POST'])
@app.route("/pagamentos/novo", methods=["GET", "POST"])
def novo_pagamento():
if request.method == 'POST':
militante_id = request.form['militante_id']
tipo_pagamento_id = request.form['tipo_pagamento_id']
valor = request.form['valor']
data_pagamento = request.form['data_pagamento']
if request.method == "POST":
pagamentos = Pagamento(
militante_id=request.form["militante_id"],
tipo_pagamento_id=request.form["tipo_pagamento_id"],
valor=request.form["valor"],
data_pagamento=datetime.strptime(request.form["data_pagamento"], "%Y-%m-%d")
)
query = '''
INSERT INTO pagamentos (militante_id, tipo_pagamento_id, valor, data_pagamento)
VALUES (%s, %s, %s, %s)
'''
execute_query(query, (militante_id, tipo_pagamento_id, valor, data_pagamento))
return redirect(url_for('listar_pagamentos'))
session_run(pagamentos)
return redirect(url_for("listar_pagamentos"))
return render_template("novo_pagamento.html")
return render_template('novo_pagamento.html')
# Rota para listar pagamentos
@app.route('/pagamentos')
@app.route("/pagamentos")
def listar_pagamentos():
query = 'SELECT * FROM pagamentos'
pagamentos = execute_query(query)
return render_template('listar_pagamentos.html', pagamentos=pagamentos)
pagamentos = session.query(Pagamento).all()
return render_template("listar_pagamentos.html", pagamentos=pagamentos)
# Rota para criar um novo material vendido
@app.route('/materiais/novo', methods=['GET', 'POST'])
@app.route("/materiais/novo", methods=["GET", "POST"])
def novo_material():
if request.method == 'POST':
militante_id = request.form['militante_id']
tipo_material_id = request.form['tipo_material_id']
descricao = request.form['descricao']
valor = request.form['valor']
data_venda = request.form['data_venda']
if request.method == "POST":
materiais_vendidos = MaterialVendido(
militante_id=request.form["militante_id"],
tipo_material_id=request.form["tipo_material_id"],
descricao=request.form["descricao"],
valor=request.form["valor"],
data_venda=datetime.strptime(request.form["data_venda"], "%Y-%m-%d"),
)
query = '''
INSERT INTO materiais_vendidos (militante_id, tipo_material_id, descricao, valor, data_venda)
VALUES (%s, %s, %s, %s, %s)
'''
execute_query(query, (militante_id, tipo_material_id, descricao, valor, data_venda))
return redirect(url_for('listar_materiais'))
session_run(materiais_vendidos)
return redirect(url_for("listar_materiais"))
return render_template("novo_material.html")
return render_template('novo_material.html')
# Rota para listar materiais vendidos
@app.route('/materiais')
@app.route("/materiais")
def listar_materiais():
query = 'SELECT * FROM materiais_vendidos'
materiais = execute_query(query)
return render_template('listar_materiais.html', materiais=materiais)
materiais = session.query(MaterialVendido).all()
return render_template("listar_materiais.html", materiais=materiais)
# Rota para criar uma nova venda de jornais avulsos
@app.route('/jornais/novo', methods=['GET', 'POST'])
@app.route("/jornais/novo", methods=["GET", "POST"])
def nova_venda_jornal():
if request.method == 'POST':
militante_id = request.form['militante_id']
quantidade = request.form['quantidade']
valor_total = request.form['valor_total']
data_venda = request.form['data_venda']
if request.method == "POST":
vendas_jornais_avulsos = VendaJornalAvulso(
militante_id=request.form["militante_id"],
quantidade=request.form["quantidade"],
valor_total=request.form["valor_total"],
data_venda=datetime.strptime(request.form["data_venda"], "%Y-%m-%d"),
)
query = '''
INSERT INTO vendas_jornais_avulsos (militante_id, quantidade, valor_total, data_venda)
VALUES (%s, %s, %s, %s)
'''
execute_query(query, (militante_id, quantidade, valor_total, data_venda))
return redirect(url_for('listar_vendas_jornal'))
session_run(VendaJornalAvulso)
return redirect(url_for("listar_vendas_jornal"))
return render_template("nova_venda_jornal.html")
return render_template('nova_venda_jornal.html')
# Rota para listar vendas de jornais avulsos
@app.route('/jornais')
@app.route("/jornais")
def listar_vendas_jornal():
query = 'SELECT * FROM vendas_jornais_avulsos'
vendas = execute_query(query)
return render_template('listar_vendas_jornal.html', vendas=vendas)
vendas = session.query(VendaJornalAvulso).all()
return render_template("listar_vendas_jornal.html", vendas=vendas)
# Rota para criar uma nova assinatura anual
@app.route('/assinaturas/novo', methods=['GET', 'POST'])
@app.route("/assinaturas/novo", methods=["GET", "POST"])
def nova_assinatura():
if request.method == 'POST':
militante_id = request.form['militante_id']
tipo_material_id = request.form['tipo_material_id']
quantidade = request.form['quantidade']
valor_total = request.form['valor_total']
data_inicio = request.form['data_inicio']
data_fim = request.form['data_fim']
if request.method == "POST":
assinaturas_anuais = AssinaturaAnual(
militante_id=request.form["militante_id"],
tipo_material_id=request.form["tipo_material_id"],
quantidade=request.form["quantidade"],
valor_total=request.form["valor_total"],
data_inicio=datetime.strptime(request.form["data_inicio"], "%Y-%m-%d"),
data_fim=datetime.strptime(request.form["data_fim"], "%Y-%m-%d")
)
query = '''
INSERT INTO assinaturas_anuais (militante_id, tipo_material_id, quantidade, valor_total, data_inicio, data_fim)
VALUES (%s, %s, %s, %s, %s, %s)
'''
execute_query(query, (militante_id, tipo_material_id, quantidade, valor_total, data_inicio, data_fim))
return redirect(url_for('listar_assinaturas'))
session_run(assinaturas_anuais)
return redirect(url_for("listar_assinaturas"))
return render_template("nova_assinatura.html")
return render_template('nova_assinatura.html')
# Rota para listar assinaturas anuais
@app.route('/assinaturas')
@app.route("/assinaturas")
def listar_assinaturas():
query = 'SELECT * FROM assinaturas_anuais'
assinaturas = execute_query(query)
return render_template('listar_assinaturas.html', assinaturas=assinaturas)
assinaturas = session.query(AssinaturaAnual).all()
return render_template("listar_assinaturas.html", assinaturas=assinaturas)
# Rota para criar um novo relatório de cotas mensais
@app.route('/relatorios/cotas/novo', methods=['GET', 'POST'])
@app.route("/relatorios/cotas/novo", methods=["GET", "POST"])
def novo_relatorio_cotas():
if request.method == 'POST':
setor_id = request.form['setor_id']
comite_id = request.form['comite_id']
total_cotas = request.form['total_cotas']
data_relatorio = request.form['data_relatorio']
if request.method == "POST":
relatorio_cotas_mensais = RelatorioCotasMensais(
setor_id=request.form["setor_id"],
comite_id=request.form["comite_id"],
total_cotas=request.form["total_cotas"],
data_relatorio=datetime.strptime(request.form["data_relatorio"], "%Y-%m-%d")
)
query = '''
INSERT INTO relatorio_cotas_mensais (setor_id, comite_id, total_cotas, data_relatorio)
VALUES (%s, %s, %s, %s)
'''
execute_query(query, (setor_id, comite_id, total_cotas, data_relatorio))
return redirect(url_for('listar_relatorios_cotas'))
session_run(relatorio_cotas_mensais)
return redirect(url_for("listar_relatorios_cotas"))
return render_template("novo_relatorio_cotas.html")
return render_template('novo_relatorio_cotas.html')
# Rota para listar relatórios de cotas mensais
@app.route('/relatorios/cotas')
@app.route("/relatorios/cotas")
def listar_relatorios_cotas():
query = 'SELECT * FROM relatorio_cotas_mensais'
relatorios = execute_query(query)
return render_template('listar_relatorios_cotas.html', relatorios=relatorios)
relatorios = session.query(RelatorioCotasMensais).all()
return render_template("listar_relatorios_cotas.html", relatorios=relatorios)
# Rota para criar um novo relatório de vendas de materiais
@app.route('/relatorios/vendas/novo', methods=['GET', 'POST'])
@app.route("/relatorios/vendas/novo", methods=["GET", "POST"])
def novo_relatorio_vendas():
if request.method == 'POST':
setor_id = request.form['setor_id']
comite_id = request.form['comite_id']
total_vendas = request.form['total_vendas']
data_relatorio = request.form['data_relatorio']
if request.method == "POST":
relatorio_vendas_materiais = RelatorioVendasMateriais(
setor_id=request.form["setor_id"],
comite_id=request.form["comite_id"],
total_vendas=request.form["total_vendas"],
data_relatorio=datetime.strptime(request.form["data_relatorio"], "%Y-%m-%d")
)
query = '''
INSERT INTO relatorio_vendas_materiais (setor_id, comite_id, total_vendas, data_relatorio)
VALUES (%s, %s, %s, %s)
'''
execute_query(query, (setor_id, comite_id, total_vendas, data_relatorio))
return redirect(url_for('listar_relatorios_vendas'))
session_run(relatorio_vendas_materiais)
return redirect(url_for("listar_relatorios_vendas"))
return render_template("novo_relatorio_vendas.html")
return render_template('novo_relatorio_vendas.html')
# Rota para listar relatórios de vendas de materiais
@app.route('/relatorios/vendas')
@app.route("/relatorios/vendas")
def listar_relatorios_vendas():
query = 'SELECT * FROM relatorio_vendas_materiais'
relatorios = execute_query(query)
return render_template('listar_relatorios_vendas.html', relatorios=relatorios)
relatorios = session.query(RelatorioVendasMateriais).all()
return render_template("listar_relatorios_vendas.html", relatorios=relatorios)
@app.route("/")
def home():
links = []
for rule in app.url_map.iter_rules():
# Filter out rules we can't navigate to in a browser
# and rules that require parameters
if "GET" in rule.methods and has_no_empty_params(rule):
url = url_for(rule.endpoint, **(rule.defaults or {}))
links.append((url, rule.endpoint))
l_html = ""
for l in links:
l_html += f'<a href="{l[0]}">{l[1].replace("_"," ")}</a><br>'
home_html = f"""
<p>Links</p>
{l_html}
"""
return home_html
def has_no_empty_params(rule):
defaults = rule.defaults if rule.defaults is not None else ()
arguments = rule.arguments if rule.arguments is not None else ()
return len(defaults) >= len(arguments)
# Iniciar o servidor Flask
if __name__ == '__main__':
app.run(debug=True)
if __name__ == "__main__":
app.run(debug=True)

BIN
database.db Normal file

Binary file not shown.

View File

@@ -1,8 +1,16 @@
import mysql.connector
from mysql.connector import Error
from config.db_config import db_config
# from config.db_config import db_config
from sqlalchemy import create_engine, Column, Integer, String, Boolean, Numeric, Date, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
def get_db_connection():
Base = declarative_base()
engine = create_engine('sqlite:///database.db', echo=True)
Base = declarative_base()
def get_db_connection(db_config):
try:
connection = mysql.connector.connect(**db_config)
return connection
@@ -11,7 +19,7 @@ def get_db_connection():
return None
def execute_query(query, params=None):
connection = get_db_connection()
connection = get_db_connection('')
if connection is None:
return None
try:
@@ -25,4 +33,143 @@ def execute_query(query, params=None):
finally:
if connection.is_connected():
cursor.close()
connection.close()
connection.close()
class Militante(Base):
__tablename__ = 'militantes'
id = Column(Integer, primary_key=True, autoincrement=True)
nome = Column(String(100), nullable=False)
cpf = Column(String(14), unique=True)
email = Column(String(100), unique=True)
telefone = Column(String(15))
endereco = Column(String(255))
filiado = Column(Boolean, default=False)
cotas_mensais = relationship("CotaMensal", back_populates="militante")
pagamentos = relationship("Pagamento", back_populates="militante")
materiais_vendidos = relationship("MaterialVendido", back_populates="militante")
vendas_jornais = relationship("VendaJornalAvulso", back_populates="militante")
assinaturas = relationship("AssinaturaAnual", back_populates="militante")
class CotaMensal(Base):
__tablename__ = 'cotas_mensais'
id = Column(Integer, primary_key=True, autoincrement=True)
militante_id = Column(Integer, ForeignKey('militantes.id'))
valor_antigo = Column(Numeric(10, 2), nullable=False)
valor_novo = Column(Numeric(10, 2), nullable=False)
data_alteracao = Column(Date, nullable=False)
militante = relationship("Militante", back_populates="cotas_mensais")
class TipoPagamento(Base):
__tablename__ = 'tipos_pagamento'
id = Column(Integer, primary_key=True, autoincrement=True)
descricao = Column(String(100), nullable=False)
pagamentos = relationship("Pagamento", back_populates="tipo_pagamento")
class Pagamento(Base):
__tablename__ = 'pagamentos'
id = Column(Integer, primary_key=True, autoincrement=True)
militante_id = Column(Integer, ForeignKey('militantes.id'))
tipo_pagamento_id = Column(Integer, ForeignKey('tipos_pagamento.id'))
valor = Column(Numeric(10, 2), nullable=False)
data_pagamento = Column(Date, nullable=False)
militante = relationship("Militante", back_populates="pagamentos")
tipo_pagamento = relationship("TipoPagamento", back_populates="pagamentos")
class TipoMaterial(Base):
__tablename__ = 'tipos_materiais'
id = Column(Integer, primary_key=True, autoincrement=True)
descricao = Column(String(100), nullable=False)
materiais_vendidos = relationship("MaterialVendido", back_populates="tipo_material")
assinaturas = relationship("AssinaturaAnual", back_populates="tipo_material")
class MaterialVendido(Base):
__tablename__ = 'materiais_vendidos'
id = Column(Integer, primary_key=True, autoincrement=True)
militante_id = Column(Integer, ForeignKey('militantes.id'))
tipo_material_id = Column(Integer, ForeignKey('tipos_materiais.id'))
descricao = Column(String(255), nullable=False)
valor = Column(Numeric(10, 2), nullable=False)
data_venda = Column(Date, nullable=False)
militante = relationship("Militante", back_populates="materiais_vendidos")
tipo_material = relationship("TipoMaterial", back_populates="materiais_vendidos")
class VendaJornalAvulso(Base):
__tablename__ = 'vendas_jornais_avulsos'
id = Column(Integer, primary_key=True, autoincrement=True)
militante_id = Column(Integer, ForeignKey('militantes.id'))
quantidade = Column(Integer, nullable=False)
valor_total = Column(Numeric(10, 2), nullable=False)
data_venda = Column(Date, nullable=False)
militante = relationship("Militante", back_populates="vendas_jornais")
class AssinaturaAnual(Base):
__tablename__ = 'assinaturas_anuais'
id = Column(Integer, primary_key=True, autoincrement=True)
militante_id = Column(Integer, ForeignKey('militantes.id'))
tipo_material_id = Column(Integer, ForeignKey('tipos_materiais.id'))
quantidade = Column(Integer, nullable=False)
valor_total = Column(Numeric(10, 2), nullable=False)
data_inicio = Column(Date, nullable=False)
data_fim = Column(Date, nullable=False)
militante = relationship("Militante", back_populates="assinaturas")
tipo_material = relationship("TipoMaterial", back_populates="assinaturas")
class Setor(Base):
__tablename__ = 'setores'
id = Column(Integer, primary_key=True, autoincrement=True)
nome = Column(String(100), nullable=False)
relatorios_cotas = relationship("RelatorioCotasMensais", back_populates="setor")
relatorios_vendas = relationship("RelatorioVendasMateriais", back_populates="setor")
class ComiteCentral(Base):
__tablename__ = 'comites_centrais'
id = Column(Integer, primary_key=True, autoincrement=True)
nome = Column(String(100), nullable=False)
relatorios_cotas = relationship("RelatorioCotasMensais", back_populates="comite")
relatorios_vendas = relationship("RelatorioVendasMateriais", back_populates="comite")
class RelatorioCotasMensais(Base):
__tablename__ = 'relatorio_cotas_mensais'
id = Column(Integer, primary_key=True, autoincrement=True)
setor_id = Column(Integer, ForeignKey('setores.id'))
comite_id = Column(Integer, ForeignKey('comites_centrais.id'))
total_cotas = Column(Numeric(10, 2), nullable=False)
data_relatorio = Column(Date, nullable=False)
setor = relationship("Setor", back_populates="relatorios_cotas")
comite = relationship("ComiteCentral", back_populates="relatorios_cotas")
class RelatorioVendasMateriais(Base):
__tablename__ = 'relatorio_vendas_materiais'
id = Column(Integer, primary_key=True, autoincrement=True)
setor_id = Column(Integer, ForeignKey('setores.id'))
comite_id = Column(Integer, ForeignKey('comites_centrais.id'))
total_vendas = Column(Numeric(10, 2), nullable=False)
data_relatorio = Column(Date, nullable=False)
setor = relationship("Setor", back_populates="relatorios_vendas")
comite = relationship("ComiteCentral", back_populates="relatorios_vendas")
Base.metadata.create_all(engine)

19
requirements.txt Normal file
View File

@@ -0,0 +1,19 @@
black==24.10.0
blinker==1.9.0
click==8.1.7
Flask==3.1.0
greenlet==3.1.1
importlib_metadata==8.5.0
itsdangerous==2.2.0
Jinja2==3.1.4
MarkupSafe==3.0.2
mypy-extensions==1.0.0
mysql-connector-python==9.1.0
packaging==24.2
pathspec==0.12.1
platformdirs==4.3.6
SQLAlchemy==2.0.36
tomli==2.2.1
typing_extensions==4.12.2
Werkzeug==3.1.3
zipp==3.21.0

View File

@@ -33,5 +33,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -29,5 +29,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -31,5 +31,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -12,5 +12,6 @@
{% endfor %}
</ul>
<a href="{{ url_for('novo_militante') }}">Adicionar Novo Militante</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -29,5 +29,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -29,5 +29,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -29,5 +29,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -29,5 +29,6 @@
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -34,5 +34,6 @@
<button type="submit">Registrar Assinatura</button>
</form>
<a href="{{ url_for('listar_assinaturas') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -26,5 +26,6 @@
<button type="submit">Registrar Cota</button>
</form>
<a href="{{ url_for('listar_cotas') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -26,5 +26,6 @@
<button type="submit">Registrar Venda</button>
</form>
<a href="{{ url_for('listar_vendas_jornal') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -30,5 +30,6 @@
<button type="submit">Registrar Material</button>
</form>
<a href="{{ url_for('listar_materiais') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -15,5 +15,6 @@
Filiado: <input type="checkbox" name="filiado"><br>
<input type="submit" value="Criar">
</form>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -26,5 +26,6 @@
<button type="submit">Registrar Pagamento</button>
</form>
<a href="{{ url_for('listar_pagamentos') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -26,5 +26,6 @@
<button type="submit">Registrar Relatório</button>
</form>
<a href="{{ url_for('listar_relatorios_cotas') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>

View File

@@ -26,5 +26,6 @@
<button type="submit">Registrar Relatório</button>
</form>
<a href="{{ url_for('listar_relatorios_vendas') }}">Voltar para Lista</a>
<a href="{{ url_for('home') }}">Home</a>
</body>
</html>