webmoney/import_transactions.py
marco 54cccdd095 refactor: migração para desenvolvimento direto no servidor
- Removido README.md padrão do Laravel (backend)
- Removidos scripts de deploy (não mais necessários)
- Atualizado copilot-instructions.md para novo fluxo
- Adicionada documentação de auditoria do servidor
- Sincronizado código de produção com repositório

Novo workflow:
- Trabalhamos diretamente em /root/webmoney (symlink para /var/www/webmoney)
- Mudanças PHP são instantâneas
- Mudanças React requerem 'npm run build'
- Commit após validação funcional
2025-12-19 11:45:32 +01:00

222 lines
7.2 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Script para importar transações do arquivo Excel para o WebMoney
"""
import openpyxl
import requests
import json
from datetime import datetime
import hashlib
# Configurações
API_BASE = "https://webmoney.cnxifly.com/api"
EXCEL_FILE = "moneypro_backup_2025-12-06_093049.xlsx"
# Mapeamento de contas Excel -> IDs do banco
# BBVA (Conta Corrente) -> Conta "Viviane" (bank_name: BBVA) -> id: 3
# Santander (Conta Corrente) -> Conta "Marco" (bank_name: Santander) -> id: 2
ACCOUNT_MAP = {
"BBVA": 3, # Viviane - BBVA
"Santander": 2, # Marco - Santander
}
def get_token():
"""Obter token de autenticação"""
response = requests.post(
f"{API_BASE}/login",
headers={"Content-Type": "application/json", "Accept": "application/json"},
json={"email": "marco@cnxifly.com", "password": "Master9354"}
)
data = response.json()
return data["data"]["token"]
def get_existing_transactions(token):
"""Obter transações existentes para verificar duplicidades"""
response = requests.get(
f"{API_BASE}/transactions?per_page=10000",
headers={"Authorization": f"Bearer {token}", "Accept": "application/json"}
)
transactions = response.json().get("data", [])
# Criar conjunto de hashes únicos
existing = set()
for t in transactions:
# Criar hash baseado em data planejada, descrição, valor e conta
key = f"{t['planned_date'][:10]}|{t['description']}|{float(t['planned_amount']):.2f}|{t['account_id']}"
existing.add(key)
return existing
def parse_date(date_str):
"""Converter data do formato DD/MM/YYYY para YYYY-MM-DD"""
if not date_str:
return None
try:
dt = datetime.strptime(date_str, "%d/%m/%Y")
return dt.strftime("%Y-%m-%d")
except:
return None
def read_excel_transactions():
"""Ler transações do arquivo Excel"""
wb = openpyxl.load_workbook(EXCEL_FILE)
ws = wb["Transações"]
transactions = []
for row_idx in range(2, ws.max_row + 1):
planned_date = ws.cell(row=row_idx, column=1).value
effective_date = ws.cell(row=row_idx, column=2).value
description = ws.cell(row=row_idx, column=3).value
notes = ws.cell(row=row_idx, column=4).value
planned_amount = ws.cell(row=row_idx, column=5).value
effective_amount = ws.cell(row=row_idx, column=6).value
extra_amount = ws.cell(row=row_idx, column=7).value
status = ws.cell(row=row_idx, column=8).value
account_name = ws.cell(row=row_idx, column=9).value
account_type = ws.cell(row=row_idx, column=10).value
if not description or not account_name:
continue
transactions.append({
"planned_date": planned_date,
"effective_date": effective_date,
"description": description.replace('\n', ' ').strip() if description else "",
"notes": notes.strip() if notes else None,
"planned_amount": float(planned_amount) if planned_amount else 0,
"effective_amount": float(effective_amount) if effective_amount else None,
"status": status,
"account_name": account_name,
})
return transactions
def create_transaction(token, trans, account_id):
"""Criar uma transação via API"""
planned_date = parse_date(trans["planned_date"])
effective_date = parse_date(trans["effective_date"])
# Determinar tipo e valor (positivo = credit, negativo = debit)
amount = trans["planned_amount"]
if amount < 0:
trans_type = "debit"
amount = abs(amount)
else:
trans_type = "credit"
# Determinar status
if trans["status"] == "Efetivada":
status = "completed"
elif trans["status"] == "Pendente":
status = "pending"
else:
status = "pending"
# Determinar valor efetivo
eff_amount = trans["effective_amount"]
if eff_amount is not None:
eff_amount = abs(eff_amount)
else:
eff_amount = amount
payload = {
"account_id": account_id,
"type": trans_type,
"description": trans["description"],
"planned_amount": amount,
"amount": eff_amount,
"planned_date": planned_date,
"effective_date": effective_date if status == "completed" else None,
"status": status,
"notes": trans["notes"],
}
response = requests.post(
f"{API_BASE}/transactions",
headers={
"Authorization": f"Bearer {token}",
"Accept": "application/json",
"Content-Type": "application/json"
},
json=payload
)
return response.status_code == 201, response.text
def main():
print("=" * 60)
print("IMPORTAÇÃO DE TRANSAÇÕES DO MONEYPRO")
print("=" * 60)
# 1. Obter token
print("\n[1/4] Obtendo token de autenticação...")
token = get_token()
print(f"✓ Token obtido")
# 2. Obter transações existentes
print("\n[2/4] Verificando transações existentes...")
existing = get_existing_transactions(token)
print(f"{len(existing)} transações existentes encontradas")
# 3. Ler Excel
print("\n[3/4] Lendo arquivo Excel...")
transactions = read_excel_transactions()
print(f"{len(transactions)} transações lidas do Excel")
# 4. Importar transações
print("\n[4/4] Importando transações...")
imported = 0
duplicates = 0
errors = 0
error_details = []
for i, trans in enumerate(transactions):
account_id = ACCOUNT_MAP.get(trans["account_name"])
if not account_id:
errors += 1
error_details.append(f"Conta não mapeada: {trans['account_name']}")
continue
# Verificar duplicidade
planned_date = parse_date(trans["planned_date"])
amount = abs(trans["planned_amount"])
key = f"{planned_date}|{trans['description']}|{amount:.2f}|{account_id}"
if key in existing:
duplicates += 1
continue
# Criar transação
success, response = create_transaction(token, trans, account_id)
if success:
imported += 1
existing.add(key) # Evitar duplicatas no mesmo lote
else:
errors += 1
if len(error_details) < 10:
error_details.append(f"Erro ao criar: {trans['description'][:30]}... - {response[:100]}")
# Progresso
if (i + 1) % 100 == 0:
print(f" Processadas: {i + 1}/{len(transactions)} | Importadas: {imported} | Duplicatas: {duplicates} | Erros: {errors}")
# Resultado final
print("\n" + "=" * 60)
print("RESULTADO DA IMPORTAÇÃO")
print("=" * 60)
print(f"Total no Excel: {len(transactions)}")
print(f"Importadas: {imported}")
print(f"Duplicatas ignoradas: {duplicates}")
print(f"Erros: {errors}")
print(f"Total processadas: {imported + duplicates + errors}")
if error_details:
print(f"\nPrimeiros erros:")
for err in error_details[:5]:
print(f" - {err}")
print("\n✓ Importação concluída!")
if __name__ == "__main__":
main()