diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc
new file mode 100644
index 0000000..6df136b
Binary files /dev/null and b/__pycache__/app.cpython-312.pyc differ
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..6fa5a1a
--- /dev/null
+++ b/app.py
@@ -0,0 +1,213 @@
+from flask import Flask, request, render_template, redirect, url_for, jsonify
+from functions.database import execute_query
+
+app = Flask(__name__)
+
+# Rota para criar um novo militante
+@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)
+
+ 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'))
+
+ return render_template('novo_militante.html')
+
+# Rota para listar militantes
+@app.route('/militantes')
+def listar_militantes():
+ query = 'SELECT * FROM militantes'
+ militantes = execute_query(query)
+ return render_template('listar_militantes.html', militantes=militantes)
+
+# Rota para criar uma nova cota mensal
+@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']
+
+ 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'))
+
+ return render_template('nova_cota.html')
+
+# Rota para listar cotas mensais
+@app.route('/cotas')
+def listar_cotas():
+ query = 'SELECT * FROM cotas_mensais'
+ cotas = execute_query(query)
+ return render_template('listar_cotas.html', cotas=cotas)
+
+# Rota para criar um novo pagamento
+@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']
+
+ 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'))
+
+ return render_template('novo_pagamento.html')
+
+# Rota para listar pagamentos
+@app.route('/pagamentos')
+def listar_pagamentos():
+ query = 'SELECT * FROM pagamentos'
+ pagamentos = execute_query(query)
+ return render_template('listar_pagamentos.html', pagamentos=pagamentos)
+
+# Rota para criar um novo material vendido
+@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']
+
+ 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'))
+
+ return render_template('novo_material.html')
+
+# Rota para listar materiais vendidos
+@app.route('/materiais')
+def listar_materiais():
+ query = 'SELECT * FROM materiais_vendidos'
+ materiais = execute_query(query)
+ return render_template('listar_materiais.html', materiais=materiais)
+
+# Rota para criar uma nova venda de jornais avulsos
+@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']
+
+ 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'))
+
+ return render_template('nova_venda_jornal.html')
+
+# Rota para listar vendas de jornais avulsos
+@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)
+
+# Rota para criar uma nova assinatura anual
+@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']
+
+ 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'))
+
+ return render_template('nova_assinatura.html')
+
+# Rota para listar assinaturas anuais
+@app.route('/assinaturas')
+def listar_assinaturas():
+ query = 'SELECT * FROM assinaturas_anuais'
+ assinaturas = execute_query(query)
+ 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'])
+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']
+
+ 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'))
+
+ return render_template('novo_relatorio_cotas.html')
+
+# Rota para listar relatórios de cotas mensais
+@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)
+
+# Rota para criar um novo relatório de vendas de materiais
+@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']
+
+ 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'))
+
+ return render_template('novo_relatorio_vendas.html')
+
+# Rota para listar relatórios de vendas de materiais
+@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)
+
+# Iniciar o servidor Flask
+if __name__ == '__main__':
+ app.run(debug=True)
\ No newline at end of file
diff --git a/dao.py b/dao.py
new file mode 100644
index 0000000..98b37c6
--- /dev/null
+++ b/dao.py
@@ -0,0 +1,8 @@
+from functions.database import execute_query
+
+def get_user_by_email(email):
+ query = "SELECT * FROM users WHERE email = %s"
+ cursor = execute_query(query, (email,))
+ if cursor:
+ return cursor.fetchone()
+ return None
diff --git a/database.sql b/database.sql
new file mode 100644
index 0000000..d471a92
--- /dev/null
+++ b/database.sql
@@ -0,0 +1,99 @@
+-- Tabela de Militantes
+CREATE TABLE militantes (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ nome VARCHAR(100) NOT NULL,
+ cpf VARCHAR(14) UNIQUE,
+ email VARCHAR(100) UNIQUE,
+ telefone VARCHAR(15),
+ endereco VARCHAR(255),
+ filiado BOOLEAN DEFAULT false
+);
+
+-- Tabela de Cotas Mensais
+CREATE TABLE cotas_mensais (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ militante_id INT,
+ valor_antigo DECIMAL(10, 2) NOT NULL,
+ valor_novo DECIMAL(10, 2) NOT NULL,
+ data_alteracao DATE NOT NULL,
+ FOREIGN KEY (militante_id) REFERENCES militantes(id)
+);
+
+-- Tabela de Pagamentos
+CREATE TABLE tipos_pagamento (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ descricao VARCHAR(100) NOT NULL
+);
+
+CREATE TABLE pagamentos (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ militante_id INT,
+ tipo_pagamento_id INT,
+ valor DECIMAL(10, 2) NOT NULL,
+ data_pagamento DATE NOT NULL,
+ FOREIGN KEY (militante_id) REFERENCES militantes(id),
+ FOREIGN KEY (tipo_pagamento_id) REFERENCES tipos_pagamento(id)
+);
+
+-- Tabela de Tipos de Materiais
+CREATE TABLE tipos_materiais (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ descricao VARCHAR(100) NOT NULL
+);
+
+-- Tabela de Materiais Vendidos
+CREATE TABLE materiais_vendidos (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ militante_id INT,
+ tipo_material_id INT,
+ descricao VARCHAR(255) NOT NULL,
+ valor DECIMAL(10, 2) NOT NULL,
+ data_venda DATE NOT NULL,
+ FOREIGN KEY (militante_id) REFERENCES militantes(id),
+ FOREIGN KEY (tipo_material_id) REFERENCES tipos_materiais(id)
+);
+
+-- Tabela de Vendas de Jornais Avulsos
+CREATE TABLE vendas_jornais_avulsos (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ militante_id INT,
+ quantidade INT NOT NULL,
+ valor_total DECIMAL(10, 2) NOT NULL,
+ data_venda DATE NOT NULL,
+ FOREIGN KEY (militante_id) REFERENCES militantes(id)
+);
+
+-- Tabela de Assinaturas Anuais
+CREATE TABLE assinaturas_anuais (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ militante_id INT,
+ tipo_material_id INT,
+ quantidade INT NOT NULL,
+ valor_total DECIMAL(10, 2) NOT NULL,
+ data_inicio DATE NOT NULL,
+ data_fim DATE NOT NULL,
+ FOREIGN KEY (militante_id) REFERENCES militantes(id),
+ FOREIGN KEY (tipo_material_id) REFERENCES tipos_materiais(id)
+);
+
+-- Tabela de Relatório de Cotas Mensais
+CREATE TABLE relatorio_cotas_mensais (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ setor_id INT,
+ comite_id INT,
+ total_cotas DECIMAL(10, 2) NOT NULL,
+ data_relatorio DATE NOT NULL,
+ FOREIGN KEY (setor_id) REFERENCES setores(id),
+ FOREIGN KEY (comite_id) REFERENCES comites_centrais(id)
+);
+
+-- Tabela de Relatório de Vendas de Materiais
+CREATE TABLE relatorio_vendas_materiais (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ setor_id INT,
+ comite_id INT,
+ total_vendas DECIMAL(10, 2) NOT NULL,
+ data_relatorio DATE NOT NULL,
+ FOREIGN KEY (setor_id) REFERENCES setores(id),
+ FOREIGN KEY (comite_id) REFERENCES comites_centrais(id)
+);
diff --git a/functions/__pycache__/database.cpython-312.pyc b/functions/__pycache__/database.cpython-312.pyc
new file mode 100644
index 0000000..b6c6a0e
Binary files /dev/null and b/functions/__pycache__/database.cpython-312.pyc differ
diff --git a/functions/auth.py b/functions/auth.py
new file mode 100644
index 0000000..945100d
--- /dev/null
+++ b/functions/auth.py
@@ -0,0 +1,27 @@
+from flask import Flask, request, jsonify
+import jwt
+from datetime import datetime, timedelta
+from werkzeug.security import generate_password_hash, check_password_hash
+from dao import get_user_by_email
+
+app = Flask(__name__)
+app.config['SECRET_KEY'] = 'your_secret_key'
+
+def create_token(user_id):
+ payload = {
+ 'user_id': user_id,
+ 'exp': datetime.utcnow() + timedelta(hours=1)
+ }
+ return jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
+
+@app.route('/login', methods=['POST'])
+def login():
+ data = request.json
+ if not data or 'email' not in data or 'senha' not in data:
+ return jsonify({'message': 'Missing email or password'}), 400
+
+ user = get_user_by_email(data['email'])
+ if user and check_password_hash(user['senha_hash'], data['senha']):
+ token = create_token(user['id'])
+ return jsonify({'token': token})
+ return jsonify({'message': 'Invalid credentials'}), 401
\ No newline at end of file
diff --git a/functions/calc.js b/functions/calc.js
new file mode 100644
index 0000000..9c5bc2f
--- /dev/null
+++ b/functions/calc.js
@@ -0,0 +1,692 @@
+// TODO: extract all CONTANTS TO EASILY CHANGE CELLS
+
+const planilhaID= "13sLipAAD5LkzZK19iuzgscbCmODiS11hJDRgaNsnYvw";
+
+// LOCAIS DE LIMPEZA \/\/\/\/
+const cotas = 'B5:E40' ;
+const contribuintes = 'B43:E57' ;
+const brochuras = 'B60:D65';
+const campanha = 'B68:D84' ;
+const outras = 'B87:D94';
+const assinantes = 'B97:D109';
+const jornal = 'B112:D126';
+const despesaCE = 'D129';
+const depositos = 'B134:F251' ;
+const carimbo = 'Q287' ;
+// ACABOU :LOCAIS DE LIMPEZA /\/\/\/\
+
+const contagemRF='E2';
+const celulaPrincipal = 'A1' ;
+
+const enddepositos = 'D252';
+const endvendas = 'D130' ;
+
+const celulaValorTotalCotas = 'E41';
+
+const timeZone = Session.getScriptTimeZone();
+
+const CRSP = "crsptesouraria@gmail.com";
+const areaAProteger = 'A1:Y999' ;
+
+function getUser(){ return Session.getEffectiveUser();}
+
+function voltaAoTopo(){
+ SpreadsheetApp.getActiveSheet().setCurrentCell(SpreadsheetApp.getActiveSheet().getRange(celulaPrincipal)) ;
+
+}
+
+function onOpen() {
+ var ui = SpreadsheetApp.getUi();
+ ui.createMenu('CR')
+ .addItem('Enviar RF', 'menuItem1')
+ .addItem('Totalizar Cotas', 'menuItem2')
+ .addItem('Teste - Não usar', 'menuItem3')
+ .addToUi();
+}
+
+/// MENU ITEMS
+function menuItem1() {
+ SpreadsheetApp.getUi()
+ {
+ Logger.log(getUser());
+ resultado = enviaCR();
+ Logger.log("Resultado: " + resultado + ".");
+ }
+}
+
+function menuItem2() {
+ SpreadsheetApp.getUi()
+ {
+ Logger.log(getUser());
+ resultado = totalizar(curName)
+ Logger.log("Resultado: " + resultado + ".");
+ }
+}
+
+function menuItem3() {
+ SpreadsheetApp.getUi()
+ {
+ Logger.log(getUser());
+ carimboValue = pegarCarimbo(SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()) ;
+ if(!isNaN(parseFloat(carimboValue)) ) {
+ var mesAtual = Utilities.formatDate(carimboValue,timeZone, "MM");
+ Logger.log("Carimbo lido: " + mesAtual + ".");
+ }
+ else {
+ mesAtual = Utilities.formatDate(new Date(),timeZone, "MM") ;
+ Logger.log("Carimbo vazio, mês atual: " + mesAtual + ".");
+ }
+
+ voltaAoTopo();
+ }
+}
+/// FUNCTIONS BELOW
+
+
+
+/// SEND RF
+function enviaCR() {
+ var ss = SpreadsheetApp.getActiveSpreadsheet(); // cria o objeto do arquivo da planilha
+ var sheet = ss.getActiveSheet(); // cria objeto da Sheet ativa agora
+ var curName = ss.getActiveSheet().getName() ; // pega nome da Sheet
+
+ // validar contas
+ if (validar(sheet))
+ {
+ // subir dados na planilha de controle
+ var resultadoEnvio = enviando(curName,sheet,ss);
+ if (resultadoEnvio == "Enviado" )
+ {SpreadsheetApp.getUi().alert('Relatório Enviado!');}
+ else
+ {SpreadsheetApp.getUi().alert('ERRO: ' + resultadoEnvio );}
+ } return resultadoEnvio;
+}
+
+
+// VALIDAR VALORES TODO: ADIOCIONAR NOVAS
+function validar(sheet){
+ // trocar vendas por centralizado
+ var celulaDepositos = sheet.getRange(enddepositos);
+ var depositos = sheet.setCurrentCell(celulaDepositos).getValue();
+ var celulaVendas = sheet.getRange(endvendas);
+ var vendas = sheet.setCurrentCell(celulaVendas).getValue();
+ if ( vendas === depositos )
+ { return true;}
+ else
+ { SpreadsheetApp.getUi().alert('Centralizado ' + vendas + ' não bate com Depósitos ' + depositos ); return false ;}
+}
+
+
+function enviando(curName,sheet,ss) {
+ valorCotas = pegarTotalCota(curName, ss); // TOTAL das cotas
+ marcaCarimbos(curName, valorCotas, sheet); // SALVA TOTAL DAS COTAS ETC
+ novaAba = renomearAba(curName, ss); // Renomeia Aba e coloca nomero da nova aba no numero do relatorio
+ limpaEntradas(novaAba) ; // limpa carimbo e entradas
+
+ if (travar(curName, ss) === "Travada"){
+ ss.setActiveSheet(novaAba); // coloca novo em evidencia
+ return "Enviado";
+ }
+}
+
+
+function pegarTotalCota(curName, ss){
+ var sheet = ss.getSheetByName(curName);
+ var valorNovaAvulso = Number(sheet.setCurrentCell(sheet.getRange(celulaValorTotalCotas)).getValue());
+ Logger.log(" valorNovaAvulso: " + valorNovaAvulso + ".");
+ return valorNovaAvulso;
+}
+
+function marcaCarimbos(curName,totalCota,sheet){
+ var gravarTempo = Utilities.formatDate(new Date(),timeZone, "yyyyMMddHHmmssSSS");
+ var celulaTempo = 'D900';
+ var celulaTotalCotas = 'D901';
+ var celulaResponsavel = 'D902';
+ var celulaNomeContagem = 'D902';
+ var celulaResponsavelCel = 'H2';
+ var username = getUser();
+ sheet.setCurrentCell(sheet.getRange(celulaTempo)).setValue(gravarTempo);
+ sheet.setCurrentCell(sheet.getRange(celulaResponsavel)).setValue(username);
+ sheet.setCurrentCell(sheet.getRange(celulaNomeContagem)).setValue(curName);
+ sheet.setCurrentCell(sheet.getRange(celulaResponsavelCel)).setValue(username);
+ sheet.setCurrentCell(sheet.getRange(celulaTotalCotas)).setValue(totalCota);
+
+}
+
+function pegarCarimbo(sheet)
+{
+ new Date(sheet.setCurrentCell(sheet.getRange(carimbo)).getValue())
+}
+
+
+function renomearAba(curName,ss){
+
+ var newName = Number(curName) + 1 ; // cria nome da nova
+ ss.moveActiveSheet(ss.getNumSheets() - 1); // move a atual para a ultima posicao antes da Validacao que é escondida
+ ss.duplicateActiveSheet(); // duplica ativa
+ ss.renameActiveSheet(newName); // renomeia nova
+ ss.moveActiveSheet(1); // move para a primeira posicao
+ var sheet = ss.getSheetByName(newName); // torna a nova ativa usando nome
+ sheet.getRange(contagemRF).setValue(newName); //altera contagem do relatorio usando numero da aba
+ return sheet;
+}
+
+function limpaEntradas(sheet)
+{
+ function limpaTudo(value){
+ sheet.getRange(value).clearContent();
+ }
+ var limpeza = [ cotas, contribuintes, brochuras, campanha , outras, assinantes, jornal , despesaCE, depositos, carimbo ];
+ limpeza.forEach(limpaTudo) ;
+
+ let range = sheet.getRange("I:Y");
+ sheet.hideColumn(range);
+ range = sheet.getRange("A258:A999");
+ sheet.hideRow(range);
+
+ SpreadsheetApp.getActiveSheet().setCurrentCell(SpreadsheetApp.getActiveSheet().getRange(celulaPrincipal)) ;
+
+}
+
+function travar(curName, ss){
+ var sheet = ss.getSheetByName(curName);
+ var areaProtegida = false ;
+ var abaProtegida = false ;
+ var userName = getUser();
+ var protections = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET);
+
+ for (var i = 0; i < protections.length; i++) {
+ var desc = protections[i].getDescription();
+ Logger.log("protection desc: " + desc);
+ if ( desc === 'Area protegida' ){ areaProtegida = true ; }
+ if ( desc === 'Aba protegida') { abaProtegida = true ; }
+ }
+
+
+ // Protege area, e remove todos da lista de editores.
+ var range = sheet.getRange(areaAProteger);
+
+ if (areaProtegida === false && userName != CRSP ) {
+ proteRange = range.protect().setDescription('Area protegida') ;
+ areaProtegida = true ;
+ proteRange.removeEditor(userName);
+ if (proteRange.canDomainEdit()) {
+ proteRange.setDomainEdit(false);
+ }
+ }
+
+ Logger.log(userName);
+
+ if (abaProtegida === false && userName != CRSP ) {
+ var proteSheet = sheet.protect().setDescription('Aba protegida');
+ abaProtegida = true ;
+ Logger.log("Removendo: " + userName);
+ proteSheet.removeEditor(userName);
+ if (proteSheet.canDomainEdit()) {
+ proteSheet.setDomainEdit(false);
+ }
+
+ }
+ if (abaProtegida === true && areaProtegida === true ) { return "Travada" ;}
+}
+
+function efetuarRotinaMadrugada(){
+ travaNoturna();
+ totalizar();
+}
+
+function travaNoturna(){
+ var ss = SpreadsheetApp.openById(planilhaID);
+ var trava = 0 ;
+ console.log( getUser());
+
+ // Protects the sheet.
+ const sampleProtectedSheet = sheet.protect();
+ // Logs whether domain users have permission to edit the protected sheet to the console.
+ console.log(sampleProtectedSheet.canDomainEdit());
+
+ var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
+ for (var cadaSheet = 0 ; cadaSheet < sheets.length ; cadaSheet++){
+ var nomeSheet = sheets[cadaSheet].getName();
+ Logger.log(" TravaNoturna nomeSheet: " + nomeSheet);
+ if (!isNaN(parseFloat(nomeSheet)) && isFinite(nomeSheet) && nomeSheet === anterior) {
+ SpreadsheetApp.setActiveSheet(sheets[cadaSheet]);
+ var protections = sheets[cadaSheet].getProtections(SpreadsheetApp.ProtectionType.SHEET);
+ for (var i = 0; i < protections.length; i++) {
+ var desc = protections[i].getDescription();
+ Logger.log("trava desc: " + desc);
+ if ( desc === 'Area protegida' || desc === 'Aba protegida' ) {
+ trava = trava + 1 ;
+ }
+ }
+ if ( trava == 2 ){
+ const protection = sheets[cadaSheet].protect();
+ // Logs whether domain users have permission to edit the protected sheet to the console.
+ console.log(protection.canDomainEdit());
+ protection.removeEditors(protection.getEditors());
+ if (protection.canDomainEdit()) {
+ protection.setDomainEdit(false);
+ }
+ console.log(protection.canDomainEdit());
+ protection.setDescription('Trava Noturna');
+ }
+ }
+ var sheet = ss.getSheetByName(anterior);
+ sheet.setCurrentCell(sheet.getRange(celulaPrincipal)) ;
+ }
+
+}
+
+
+function totalizar(curName){
+ var anterior = curName ;
+ Logger.log("anterior: " + anterior + ".");
+
+ var ss = SpreadsheetApp.getActiveSpreadsheet() ;
+ var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
+ var gravou = 0;
+
+ function enviarTotal() {
+ var sheet = ss.getSheetByName(anterior);
+
+ var brochuras = sheet.setCurrentCell(sheet.getRange('D66')).getValue() ;
+ var campanha = sheet.setCurrentCell(sheet.getRange('D71')).getValue();
+ var campanhaCCCE = sheet.setCurrentCell(sheet.getRange('D85')).getValue();
+
+ var outras = sheet.setCurrentCell(sheet.getRange('D95')).getValue();
+ var assinantes = sheet.setCurrentCell(sheet.getRange('D115')).getValue();
+ var jornal = sheet.setCurrentCell(sheet.getRange('D127')).getValue();
+ var carimboValue = pegarCarimbo() ;
+
+ var sheet = ss.getSheetByName("TOTAL");
+
+ // ABA TOTAL COLUNAS DE VALORES TOTALIZADOS
+ var cotascol = 'C'; // 0
+ var contribuintescol = 'E'; // 1
+ var brochurascol = 'H' ; // 2
+ var cfcol = 'J'; // 3
+ var outrascol = 'L'; // 4
+ var asscol = 'P'; // 5
+ var jornalcol ='R'; // 6
+ var varJaneiro = 3 ;
+ var varFevereiro = 4 ;
+ var varMarço = 5 ;
+ var varAbril = 6 ;
+ var varMaio = 7 ;
+ var varJunho = 8 ;
+ var varJulho = 9 ;
+ var varAgosto = 10 ;
+ var varSetembro = 11 ;
+ var varOutubro = 12 ;
+ var varNovembro = 13 ;
+ var varDezembro = 14 ;
+ var decimoTerceiro = 15 ;
+ var decimoQuarto = 16 ;
+ var decimoQuinto = 17 ;
+ var colunas = [ cotascol, contribuintescol , brochurascol , cfcol , outrascol , asscol , jornalcol ] ;
+ var linhas = [varJaneiro , varFevereiro ,varMarço ,varAbril ,varMaio ,varJunho ,varJulho ,varAgosto ,varSetembro ,varOutubro ,varNovembro ,varDezembro, decimoTerceiro, decimoQuarto, decimoQuinto] ;
+ // TERMINOU TABELA TOTAL /\
+
+
+ // PEGAR MES ATUAL
+
+ if(!isNaN(parseFloat(carimboValue)) ) {var mesAtual = Utilities.formatDate(carimboValue,timeZone, "MM");}
+ else { mesAtual = Utilities.formatDate(new Date(),timeZone, "MM") }
+
+ // Para cada Coluna de TOTAL executar totalização:
+ colunas.forEach(function(letra,coluna,tudo) {
+ Logger.log("letra: " + letra );
+ // começa com cota, checa se é o mes e coloca no switch.
+ switch (letra){
+ case cotascol:
+ // mes igual mes da primeira linha
+ for (var cadaMesdeCota = 5 ; cadaMesdeCota <=40 ; cadaMesdeCota++ ){
+ var celulaMilitante = 'B' + cadaMesdeCota ;
+ var celulaAno = 'C' + cadaMesdeCota ;
+ var celulaMes = 'D' + cadaMesdeCota ;
+ var celulaValor = 'E' + cadaMesdeCota ;
+
+
+ // Vai pra Anterior pra pegar cota de cadaMesdeCota ++++++++++++++++++++++++++++++++++++++++++++++
+ var sheet = ss.getSheetByName(anterior);
+
+ valorCelula = sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue() ;
+
+ // if (!isNaN(parseFloat(mesCelula)) && !isNaN(parseFloat(valorCelula)))
+ if (!isNaN(parseFloat(valorCelula)))
+ {
+ var mesCelula = sheet.setCurrentCell(sheet.getRange(celulaMes)).getValue();
+ var retornoMes = checkMonth(mesCelula);
+ militanteCota = sheet.setCurrentCell(sheet.getRange(celulaMilitante)).getValue();
+ anoCota = sheet.setCurrentCell(sheet.getRange(celulaAno)).getValue();
+ Logger.log( " COTA valorCelula: " + valorCelula + " militanteCota " + militanteCota + "retornoMes" + retornoMes);
+
+ if ( !isNaN(parseFloat(retornoMes)) ) {
+ var mesNovaCota = new Date(retornoMes) ;
+ var mesNCemN = Number(Utilities.formatDate(mesNovaCota,timeZone, "MM")) - 1;
+ var valorNovaCota = valorCelula ;
+
+ if (!isNaN(parseFloat(valorNovaCota))){
+ // ENVIA PARA TOTAL:
+ Logger.log( " COTA valorNovaCota: " + valorNovaCota + ".");
+
+ var sheet = ss.getSheetByName("TOTAL");
+ var celulaObjetivo = letra + linhas[mesNCemN] ;
+ Logger.log( " COTA celulaObjetivo: " + celulaObjetivo + ".");
+
+
+ var valorAntigoCota = sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).getValue() ;
+ if (!isNaN(parseFloat(valorAntigoCota))){
+ Logger.log( " COTA valorAntigoCota: " + valorAntigoCota + ".");
+ var gravar = valorAntigoCota + valorNovaCota ;
+ }
+ else { var gravar = valorNovaCota ; }
+ sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).setValue(gravar);
+ Logger.log( " COTA Gravou: " + gravar + ".");
+ // ENVIOU PARA TOTAL /\
+
+ }
+ }
+ }
+ }
+ break;
+
+ // segunda iteração contribuintes, checa se é o mes e coloca no switch.
+ case contribuintescol:
+ // mes igual mes da primeira linha
+ for (var cadaMesContrib = 43 ; cadaMesContrib <=57 ; cadaMesContrib++ ){
+ var celulaContribuinte = 'B' + cadaMesContrib ;
+ var celulaAno = 'C' + cadaMesContrib ;
+ var celulaMes = 'D' + cadaMesContrib ;
+ var celulaValor = 'E' + cadaMesContrib ;
+ var celulaResponsavel = 'F' + cadaMesContrib ;
+
+ // Vai pra Anterior pra pegar Contribuição de cadaMesdeCota
+ var sheet = ss.getSheetByName(anterior);
+ var retornoMes = sheet.setCurrentCell(sheet.getRange(celulaMes)).getValue();
+
+ if ( !isNaN(parseFloat(retornoMes)) ) {
+ var mesNovaContrib = new Date(checkMonth(retornoMes)) ;
+ var mesNCemN = Number(Utilities.formatDate(mesNovaContrib,timeZone, "MM")) - 1;
+ var valorNovaContr = Number(sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue());
+ if (!isNaN(parseFloat(valorNovaContr))){
+ Logger.log( " CONTRIB valorNovaContr: " + valorNovaContr + ".");
+ var celulaObjetivo = letra + linhas[mesNCemN] ;
+ Logger.log( " CONTRIB celulaObjetivo: " + celulaObjetivo + ".");
+ var sheet = ss.getSheetByName("TOTAL");
+ var valorAntigoContr = sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).getValue() ;
+ Logger.log( " CONTRIB valorAntigoContr: " + valorAntigoContr + ".");
+ if (!isNaN(parseFloat(valorAntigoContr)) ){
+ var gravar = valorNovaContr + valorAntigoContr ; }
+ else {
+ gravar = valorNovaContr ;
+ }
+ Logger.log( " CONTRIB celulaMes: " + celulaMes + " celulaValor: " + celulaValor + ".");
+ var sheet = ss.getSheetByName("TOTAL");
+ sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).setValue(gravar);
+ Logger.log( " CONTRIB Gravou: " + gravar + ".");
+ }
+ }
+ }
+ break;
+
+ // FALTA TERMINAR BROCHURAS
+ case brochurascol:
+ for (var linhaBro = 60 ; linhaBro <=65 ; linhaBro++ ){
+ // var celulaNome = 'B' +linhaBro ;
+ var celulaQuantidade = 'C' + linhaBro ;
+ var celulaValor = 'D' + linhaBro ;
+ var celulaCodigo = 'E' + linhaBro ;
+ // Vai pra Anterior pra pegar dados acima
+ var sheet = ss.getSheetByName(anterior);
+ var difLinBro = 2 ;
+ var quantidadeBro = sheet.setCurrentCell(sheet.getRange(celulaQuantidade)).getValue();
+ if ( !isNaN(parseFloat(quantidadeBro)) ) {
+ var valorNovaBro = Number(sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue());
+ var codigoNovaBro = Number(sheet.setCurrentCell(sheet.getRange(celulaCodigo)).getValue()) + difLinBro ;
+ Logger.log(" BROCHURAS valorNovaBro: " + valorNovaBro + " codigoNovaBro: " + codigoNovaBro);
+ if (!isNaN(parseFloat(valorNovaBro))){
+ var celulaObjetivo = letra + codigoNovaBro ;
+ var qtdObjetivo = 'G' + codigoNovaBro ;
+ var qtdAntigoBro = sheet.setCurrentCell(sheet.getRange(qtdObjetivo)).getValue() ;
+ var sheet = ss.getSheetByName("TOTAL");
+ var valorAntigoBro = sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).getValue() ;
+ if (!isNaN(parseFloat(valorAntigoBro)) ){
+ var gravar = valorNovaBro + valorAntigoBro ; }
+ else {
+ gravar = valorNovaBro ;
+ }
+ Logger.log(" BROCHURAS celulaQuantidade: " + celulaQuantidade + " celulaValor: " + celulaValor + " gravar: " + gravar );
+
+ if (!isNaN(parseFloat(qtdAntigoBro)) ){
+ var gravarQtd = quantidadeBro + qtdAntigoBro ; }
+ else {
+ var gravarQtd = quantidadeBro ;
+ }
+ var sheet = ss.getSheetByName("TOTAL");
+ // Grava Valor
+ Logger.log(" BROCHURAS celulaValorObjetivo: " + celulaObjetivo + " gravar: " + gravar );
+ sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).setValue(gravar);
+ Logger.log( " BROCHURAS Gravou Valor: " + gravar + ".");
+ // Grava quantidade
+ sheet.setCurrentCell(sheet.getRange(qtdObjetivo)).setValue(gravarQtd);
+ Logger.log( " BROCHURAS Gravou Qtd: " + gravarQtd + ".")
+ }
+ }
+ }
+ break;
+ case cfcol:
+ for (var linhaCF = 68 ; linhaCF <=84 ; linhaCF++ ){
+ var celulaNome = 'B' + linhaCF ;
+ var celulaQuantidade = 'C' + linhaCF ;
+ var celulaValor = 'D' + linhaCF ;
+ var celulaCodigo = 'F' + linhaCF ;
+ var sheet = ss.getSheetByName(anterior);
+ var valorCF = sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue();
+ if ( !isNaN(parseFloat(valorCF)) ) {
+ var militanteNovaCF = sheet.setCurrentCell(sheet.getRange(celulaNome)).getValue();
+ // VAI PRA TOTAL
+ var sheet = ss.getSheetByName("TOTAL");
+ var linhaSalvar = sheet.getRange('I3:J22').createTextFinder(militanteNovaCF).findNext();
+ if (linhaSalvar){
+ var valorAntigoCF = linhaSalvar.offset(0,1).getValue();
+ Logger.log(" CF linhaSalvar.getA1Notation(): " + linhaSalvar.getA1Notation() + " militanteNovaCF: " + militanteNovaCF + " valorCF: " + valorCF + " valorAntigoCF: " + valorAntigoCF );
+ if (!isNaN(parseFloat(valorAntigoCF)) ){ var gravar = valorCF + valorAntigoCF ; }
+ else { gravar = valorCF ; }
+ // Grava Valor
+ linhaSalvar.offset(0,1).setValue(gravar);
+ Logger.log( " CF Gravou Valor: " + gravar + ".");
+ }
+ }
+ }
+ break;
+ case outrascol:
+ for (var linhaOutros = 87 ; linhaOutros <=94 ; linhaOutros++ ){
+ var celulaQuantidade = 'C' + linhaOutros ;
+ var celulaValor = 'D' + linhaOutros ;
+ var celulaCodigo = 'E' + linhaOutros ;
+
+ // Vai pra Anterior pra pegar dados acima
+ var sheet = ss.getSheetByName(anterior);
+
+ var quantidadeOutro = sheet.setCurrentCell(sheet.getRange(celulaQuantidade)).getValue();
+ if ( !isNaN(parseFloat(quantidadeOutro)) ) {
+ var valorNovaOutro = Number(sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue());
+ var difLinOut = 2 ;
+ var codigoNovaOutro = Number(sheet.setCurrentCell(sheet.getRange(celulaCodigo)).getValue()) + difLinOut ;
+ if (!isNaN(parseFloat(valorNovaOutro))){
+ var celulaObjetivo = letra + codigoNovaOutro ;
+ var qtdObjetivo = 'K' + codigoNovaOutro ;
+ var qtdAntigoOutro = sheet.setCurrentCell(sheet.getRange(qtdObjetivo)).getValue() ;
+ var sheet = ss.getSheetByName("TOTAL");
+ var valorAntigoOutro = sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).getValue() ;
+ if (!isNaN(parseFloat(valorAntigoOutro)) ){
+ var gravar = valorNovaOutro + valorAntigoOutro ; }
+ else {
+ gravar = valorNovaOutro ;
+ }
+ Logger.log( " OUTRAS celulaQuantidade: " + celulaQuantidade + " celulaValor: " + celulaValor + " gravar: " + gravar );
+
+ if (!isNaN(parseFloat(qtdAntigoOutro)) ){
+ var gravarQtd = quantidadeOutro + qtdAntigoOutro ; }
+ else {
+ var gravarQtd = quantidadeOutro ;
+ }
+ var sheet = ss.getSheetByName("TOTAL");
+ // Grava Valor
+ Logger.log( " OUTRAS celulaValorObjetivo: " + celulaObjetivo + " gravar: " + gravar );
+ sheet.setCurrentCell(sheet.getRange(celulaObjetivo)).setValue(gravar);
+ Logger.log( " OUTRAS Gravou Valor: " + gravar + ".");
+ // Grava quantidade
+ sheet.setCurrentCell(sheet.getRange(qtdObjetivo)).setValue(gravarQtd);
+ Logger.log( " OUTRAS Gravou Qtd: " + gravarQtd + ".")
+ }
+ }
+ }
+ break;
+ case asscol:
+ // ARRUMAR ASSINATURAS
+ var linha = mesAtual - 1 ;
+ Logger.log(" ASSINATURA linhas[linha]: " + linhas[linha] + " linha: " + linha + " mesAtual: " + mesAtual + ".");
+ var celula = letra + linhas[linha] ;
+
+ // PEGAR TOTAL ATUAL
+ var sheet = ss.getSheetByName(anterior);
+ var totalatual = sheet.setCurrentCell(sheet.getRange(celula)).getValue() ;
+ if ( !isNaN(parseFloat(outras)) && assinantes > 0 ){
+ var gravar = totalatual + assinantes ;
+ // GRAVAR
+ var sheet = ss.getSheetByName("TOTAL");
+ sheet.setCurrentCell(sheet.getRange(celula)).setValue(gravar);
+ }
+ break ;
+ case jornalcol:
+ for (var linhaAvulso = 112 ; linhaAvulso <=126 ; linhaAvulso++ ){
+ var celulaQuantidade = 'C' + linhaAvulso ;
+ var celulaValor = 'D' + linhaAvulso ;
+ var celulaEdicao = 'B' + linhaAvulso ;
+
+ // Vai pra Anterior pra pegar dados acima
+ var sheet = ss.getSheetByName(anterior);
+ var difLinEdicao = 11
+ var quantidadeAvulso = sheet.setCurrentCell(sheet.getRange(celulaQuantidade)).getValue();
+ if ( !isNaN(parseFloat(quantidadeAvulso)) ) {
+ var valorNovaAvulso = Number(sheet.setCurrentCell(sheet.getRange(celulaValor)).getValue());
+ var edicaoNovaAvulso = Number(sheet.setCurrentCell(sheet.getRange(celulaEdicao)).getValue()) - difLinEdicao ;
+ Logger.log( " JORNALA. edicaoNovaAvulso: " + edicaoNovaAvulso + "valorNovaAvulso: " + valorNovaAvulso + "Quantidade: " + quantidadeAvulso );
+ if (!isNaN(parseFloat(valorNovaAvulso))){
+ var celulaValorObjetivo = letra + edicaoNovaAvulso ;
+ var qtdVendido = 'T' + edicaoNovaAvulso ;
+ var sheet = ss.getSheetByName("TOTAL");
+ var valorAntigoAvulso = sheet.setCurrentCell(sheet.getRange(celulaValorObjetivo)).getValue() ;
+ var qtdAntigoAvulso = sheet.setCurrentCell(sheet.getRange(qtdVendido)).getValue() ;
+ if (!isNaN(parseFloat(valorAntigoAvulso)) ){
+ var gravar = valorNovaAvulso + valorAntigoAvulso ; }
+ else {
+ var gravar = valorNovaAvulso ;
+ }
+ if (!isNaN(parseFloat(qtdAntigoAvulso)) ){
+ var gravarQtd = quantidadeAvulso + qtdAntigoAvulso ; }
+ else {
+ var gravarQtd = quantidadeAvulso ;
+ }
+ var sheet = ss.getSheetByName("TOTAL");
+ // Grava Valor
+ sheet.setCurrentCell(sheet.getRange(celulaValorObjetivo)).setValue(gravar);
+ Logger.log( " JORNALA. Gravou Valor: " + gravar );
+ // Grava quantidade
+ sheet.setCurrentCell(sheet.getRange(qtdVendido)).setValue(gravarQtd);
+ Logger.log( " JORNALA. Gravou Qtd: " + gravarQtd );
+
+ }
+ }
+ }
+ break;
+ }
+ } )
+ }
+
+ if (sheets.length > 1) {
+ for (var cadaSheet = 0 ; cadaSheet < sheets.length ; cadaSheet++)
+ {
+ var nomeSheet = sheets[cadaSheet].getName();
+ Logger.log("nomeSheet: " + nomeSheet);
+ if (!isNaN(parseFloat(nomeSheet)) && isFinite(nomeSheet) && nomeSheet === anterior) {
+ SpreadsheetApp.setActiveSheet(sheets[cadaSheet]);
+ var protections = sheets[cadaSheet].getProtections(SpreadsheetApp.ProtectionType.SHEET);
+ for (var i = 0; i < protections.length; i++) {
+ var desc = protections[i].getDescription();
+ Logger.log("protection desc: " + desc);
+ if ( desc === 'Aba protegida') {
+ enviarTotal();
+ gravou = 1;
+ }
+ }
+ }
+ var sheet = ss.getSheetByName(anterior);
+ sheet.setCurrentCell(sheet.getRange(celulaPrincipal)) ;
+ }
+ }
+ if (gravou === 1 ) { return "Totalizado";}
+ Logger.log("gravou: " + gravou + ".");
+
+}
+
+
+function checkMonth(nomedoMes)
+{
+ Logger.log(" checkMonth nomedoMes: " + nomedoMes + ".");
+ switch (nomedoMes){
+ case 1:
+ case "Janeiro" :
+ return "1";
+ break;
+ case 2:
+ case "Fevereiro":
+ return "2";
+ break;
+ case 3:
+ case "Março":
+ return "3";
+ break;
+ case 4:
+ case "Abril":
+ return "4";
+ break;
+ case 5:
+ case "Maio":
+ return "5";
+ break;
+ case 6:
+ case "Junho":
+ return "6";
+ break;
+ case 7:
+ case "Julho":
+ return "7";
+ break;
+ case 8:
+ case "Agosto":
+ return "8";
+ break;
+ case 9:
+ case "Setembro":
+ return "9";
+ break;
+ case 10:
+ case "Outubro":
+ return "10";
+ break;
+ case 11:
+ case "Novembro":
+ return "11";
+ break;
+ case 12:
+ case "Dezembro":
+ return "12";
+ break;
+ default:
+ return nomedoMes;
+ break;
+ }
+}
diff --git a/functions/carteirinha.py b/functions/carteirinha.py
new file mode 100644
index 0000000..0a86173
--- /dev/null
+++ b/functions/carteirinha.py
@@ -0,0 +1,19 @@
+from PIL import Image, ImageDraw, ImageFont
+import qrcode
+
+def gerar_carteirinha(militante_id, nome):
+ # Criar imagem base
+ img = Image.new('RGB', (300, 200), color=(255, 255, 255))
+ d = ImageDraw.Draw(img)
+
+ # Adicionar texto
+ font = ImageFont.load_default()
+ d.text((10, 10), f"Nome: {nome}", font=font, fill=(0, 0, 0))
+ d.text((10, 30), f"ID: {militante_id}", font=font, fill=(0, 0, 0))
+
+ # Gerar QR code
+ qr = qrcode.make(f"ID: {militante_id}")
+ img.paste(qr, (200, 50))
+
+ # Salvar imagem
+ img.save(f"carteirinha_{militante_id}.png")
\ No newline at end of file
diff --git a/functions/database.py b/functions/database.py
new file mode 100644
index 0000000..cc22955
--- /dev/null
+++ b/functions/database.py
@@ -0,0 +1,28 @@
+import mysql.connector
+from mysql.connector import Error
+from config.db_config import db_config
+
+def get_db_connection():
+ try:
+ connection = mysql.connector.connect(**db_config)
+ return connection
+ except Error as e:
+ print(f"Error connecting to database: {e}")
+ return None
+
+def execute_query(query, params=None):
+ connection = get_db_connection()
+ if connection is None:
+ return None
+ try:
+ cursor = connection.cursor(dictionary=True)
+ cursor.execute(query, params)
+ connection.commit()
+ return cursor
+ except Error as e:
+ print(f"Error executing query: {e}")
+ return None
+ finally:
+ if connection.is_connected():
+ cursor.close()
+ connection.close()
\ No newline at end of file
diff --git a/templates/listar_assinaturas.html b/templates/listar_assinaturas.html
new file mode 100644
index 0000000..51eb07a
--- /dev/null
+++ b/templates/listar_assinaturas.html
@@ -0,0 +1,37 @@
+
+
+
+
+ Listar Assinaturas Anuais
+
+
+ Assinaturas Anuais
+ Adicionar Nova Assinatura
+
+
+
+ | ID |
+ Militante ID |
+ Tipo Material |
+ Quantidade |
+ Valor Total |
+ Data Início |
+ Data Fim |
+
+
+
+ {% for assinatura in assinaturas %}
+
+ | {{ assinatura.id }} |
+ {{ assinatura.militante_id }} |
+ {{ assinatura.tipo_material_id }} |
+ {{ assinatura.quantidade }} |
+ R$ {{ assinatura.valor_total }} |
+ {{ assinatura.data_inicio }} |
+ {{ assinatura.data_fim }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_cotas.html b/templates/listar_cotas.html
new file mode 100644
index 0000000..4ab4e33
--- /dev/null
+++ b/templates/listar_cotas.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Listar Cotas Mensais
+
+
+ Cotas Mensais
+ Adicionar Nova Cota
+
+
+
+ | ID |
+ Militante ID |
+ Valor Antigo |
+ Valor Novo |
+ Data de Alteração |
+
+
+
+ {% for cota in cotas %}
+
+ | {{ cota.id }} |
+ {{ cota.militante_id }} |
+ R$ {{ cota.valor_antigo }} |
+ R$ {{ cota.valor_novo }} |
+ {{ cota.data_alteracao }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_materiais.html b/templates/listar_materiais.html
new file mode 100644
index 0000000..e78b172
--- /dev/null
+++ b/templates/listar_materiais.html
@@ -0,0 +1,35 @@
+
+
+
+
+ Listar Materiais
+
+
+ Materiais Vendidos
+ Adicionar Novo Material
+
+
+
+ | ID |
+ Militante ID |
+ Tipo Material |
+ Descrição |
+ Valor |
+ Data da Venda |
+
+
+
+ {% for material in materiais %}
+
+ | {{ material.id }} |
+ {{ material.militante_id }} |
+ {{ material.tipo_material_id }} |
+ {{ material.descricao }} |
+ R$ {{ material.valor }} |
+ {{ material.data_venda }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_militantes.html b/templates/listar_militantes.html
new file mode 100644
index 0000000..416e70b
--- /dev/null
+++ b/templates/listar_militantes.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Lista de Militantes
+
+
+ Militantes
+
+ {% for militante in militantes %}
+ - {{ militante.nome }} - {{ militante.email }}
+ {% endfor %}
+
+ Adicionar Novo Militante
+
+
\ No newline at end of file
diff --git a/templates/listar_pagamentos.html b/templates/listar_pagamentos.html
new file mode 100644
index 0000000..ffdf8fd
--- /dev/null
+++ b/templates/listar_pagamentos.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Listar Pagamentos
+
+
+ Pagamentos
+ Adicionar Novo Pagamento
+
+
+
+ | ID |
+ Militante ID |
+ Tipo de Pagamento |
+ Valor |
+ Data do Pagamento |
+
+
+
+ {% for pagamento in pagamentos %}
+
+ | {{ pagamento.id }} |
+ {{ pagamento.militante_id }} |
+ {{ pagamento.tipo_pagamento_id }} |
+ R$ {{ pagamento.valor }} |
+ {{ pagamento.data_pagamento }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_relatorios_cotas.html b/templates/listar_relatorios_cotas.html
new file mode 100644
index 0000000..9abf22b
--- /dev/null
+++ b/templates/listar_relatorios_cotas.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Listar Relatórios de Cotas
+
+
+ Relatórios de Cotas Mensais
+ Adicionar Novo Relatório
+
+
+
+ | ID |
+ Setor ID |
+ Comitê ID |
+ Total de Cotas |
+ Data do Relatório |
+
+
+
+ {% for relatorio in relatorios %}
+
+ | {{ relatorio.id }} |
+ {{ relatorio.setor_id }} |
+ {{ relatorio.comite_id }} |
+ R$ {{ relatorio.total_cotas }} |
+ {{ relatorio.data_relatorio }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_relatorios_vendas.html b/templates/listar_relatorios_vendas.html
new file mode 100644
index 0000000..09133c8
--- /dev/null
+++ b/templates/listar_relatorios_vendas.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Listar Relatórios de Vendas
+
+
+ Relatórios de Vendas de Materiais
+ Adicionar Novo Relatório
+
+
+
+ | ID |
+ Setor ID |
+ Comitê ID |
+ Total de Vendas |
+ Data do Relatório |
+
+
+
+ {% for relatorio in relatorios %}
+
+ | {{ relatorio.id }} |
+ {{ relatorio.setor_id }} |
+ {{ relatorio.comite_id }} |
+ R$ {{ relatorio.total_vendas }} |
+ {{ relatorio.data_relatorio }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/listar_vendas_jornal.html b/templates/listar_vendas_jornal.html
new file mode 100644
index 0000000..54d9c9e
--- /dev/null
+++ b/templates/listar_vendas_jornal.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Listar Vendas de Jornais
+
+
+ Vendas de Jornais Avulsos
+ Adicionar Nova Venda
+
+
+
+ | ID |
+ Militante ID |
+ Quantidade |
+ Valor Total |
+ Data da Venda |
+
+
+
+ {% for venda in vendas %}
+
+ | {{ venda.id }} |
+ {{ venda.militante_id }} |
+ {{ venda.quantidade }} |
+ R$ {{ venda.valor_total }} |
+ {{ venda.data_venda }} |
+
+ {% endfor %}
+
+
+
+
diff --git a/templates/nova_assinatura.html b/templates/nova_assinatura.html
new file mode 100644
index 0000000..3619c9e
--- /dev/null
+++ b/templates/nova_assinatura.html
@@ -0,0 +1,38 @@
+
+
+
+
+ Nova Assinatura Anual
+
+
+ Registrar Nova Assinatura Anual
+
+ Voltar para Lista
+
+
diff --git a/templates/nova_cota.html b/templates/nova_cota.html
new file mode 100644
index 0000000..2c3c2fb
--- /dev/null
+++ b/templates/nova_cota.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Nova Cota Mensal
+
+
+ Registrar Nova Cota Mensal
+
+ Voltar para Lista
+
+
diff --git a/templates/nova_venda_jornal.html b/templates/nova_venda_jornal.html
new file mode 100644
index 0000000..a625c71
--- /dev/null
+++ b/templates/nova_venda_jornal.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Nova Venda de Jornal
+
+
+ Registrar Nova Venda de Jornal
+
+ Voltar para Lista
+
+
diff --git a/templates/novo_material.html b/templates/novo_material.html
new file mode 100644
index 0000000..6dd9ce2
--- /dev/null
+++ b/templates/novo_material.html
@@ -0,0 +1,34 @@
+
+
+
+
+ Novo Material
+
+
+ Registrar Novo Material
+
+ Voltar para Lista
+
+
diff --git a/templates/novo_militante.html b/templates/novo_militante.html
new file mode 100644
index 0000000..c22460f
--- /dev/null
+++ b/templates/novo_militante.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Novo Militante
+
+
+ Criar Novo Militante
+
+
+
\ No newline at end of file
diff --git a/templates/novo_pagamento.html b/templates/novo_pagamento.html
new file mode 100644
index 0000000..8d8170f
--- /dev/null
+++ b/templates/novo_pagamento.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Novo Pagamento
+
+
+ Registrar Novo Pagamento
+
+ Voltar para Lista
+
+
diff --git a/templates/novo_relatorio_cotas.html b/templates/novo_relatorio_cotas.html
new file mode 100644
index 0000000..4f6016d
--- /dev/null
+++ b/templates/novo_relatorio_cotas.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Novo Relatório de Cotas
+
+
+ Registrar Novo Relatório de Cotas
+
+ Voltar para Lista
+
+
diff --git a/templates/novo_relatorio_vendas.html b/templates/novo_relatorio_vendas.html
new file mode 100644
index 0000000..741261a
--- /dev/null
+++ b/templates/novo_relatorio_vendas.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Novo Relatório de Vendas
+
+
+ Registrar Novo Relatório de Vendas
+
+ Voltar para Lista
+
+