84 lines
3.8 KiB
Python
84 lines
3.8 KiB
Python
"""
|
|
deshacer_btc.py — Volver a empezar el bitcoin: quita lo que metieron el CSV de
|
|
un extracto de exchanges y el historial de los monederos, sin tocar nada más.
|
|
|
|
Qué se quita:
|
|
• las operaciones que creó el CSV de exchanges (su línea empieza por «ct:»);
|
|
• todo lo que guardaste desde el nodo, sea revisando todo el historial o
|
|
en la comprobación diaria (cada importación se deshace entera: lo creado
|
|
se borra y a lo enlazado se le quita el txid);
|
|
• las decisiones sin guardar (borradores) y lo recordado de cada exchange;
|
|
• los activos «BTC en …» que creó el CSV, si se quedan sin operaciones.
|
|
|
|
Qué se queda: los monederos, lo que tenías apuntado antes (aunque el historial
|
|
lo hubiera enlazado) y cualquier operación hecha a mano. Se borra marcando, como todo en la app, así que la
|
|
sincronización lo lleva también a la copia de tu servidor git.
|
|
|
|
Primero se simula (qué y cuánto) y solo se aplica si se confirma.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from . import historial_btc
|
|
|
|
PREFIJOS_CSV = ("ct:", "ct-fee:")
|
|
|
|
|
|
def _del_csv(m: dict) -> bool:
|
|
return str(m.get("extracto") or "").startswith(PREFIJOS_CSV)
|
|
|
|
|
|
def plan(cartera, config_btc: dict) -> dict:
|
|
"""Lo que se quitaría, sin tocar nada."""
|
|
movs = cartera.datos.vivos("movimientos")
|
|
todos = cartera.datos.movimientos
|
|
imps = config_btc.get("importaciones") or []
|
|
vivos = {m["id"] for m in movs}
|
|
creados_hist = {i for imp in imps for i in imp.get("creados") or [] if i in vivos}
|
|
enlazados = {i for imp in imps for i in imp.get("enlazados") or [] if i in vivos}
|
|
del_csv = {m["id"] for m in movs if _del_csv(m)}
|
|
quitar = del_csv | creados_hist
|
|
|
|
# Activos que creó el CSV: tienen (o tuvieron) alguna operación suya y no
|
|
# les queda ninguna que no se vaya a quitar
|
|
con_csv = {m["activo"] for m in todos if _del_csv(m)}
|
|
activos, se_quedan = [], []
|
|
for a in cartera.datos.vivos("activos"):
|
|
if a["id"] not in con_csv:
|
|
continue
|
|
restantes = [m for m in movs if m["activo"] == a["id"] and m["id"] not in quitar]
|
|
if restantes:
|
|
se_quedan.append({"id": a["id"], "nombre": a["nombre"], "operaciones": len(restantes)})
|
|
else:
|
|
activos.append({"id": a["id"], "nombre": a["nombre"]})
|
|
en_uso = {m.get("activo") for m in config_btc.get("monederos") or []}
|
|
for a in list(activos):
|
|
if a["id"] in en_uso: # un monedero apunta ahí: no se borra
|
|
activos.remove(a)
|
|
se_quedan.append({**a, "operaciones": 0, "monedero": True})
|
|
return {"del_csv": len(del_csv), "del_historial": len(creados_hist - del_csv),
|
|
"desenlazar": len(enlazados - quitar), "importaciones": len(imps),
|
|
"decisiones": len(config_btc.get("resueltas") or {}),
|
|
"borradores": len(config_btc.get("borradores") or {}),
|
|
"activos": activos, "activos_que_se_quedan": se_quedan}
|
|
|
|
|
|
def aplicar(cartera, config_btc: dict, ajustes_extractos: dict) -> dict:
|
|
"""Quita lo del plan. Cambia config_btc y ajustes_extractos en el sitio;
|
|
quien llama los guarda."""
|
|
p = plan(cartera, config_btc)
|
|
# 1. El historial, importación a importación (borra lo creado, quita enlaces)
|
|
for imp in list(config_btc.get("importaciones") or []):
|
|
historial_btc.deshacer(cartera, config_btc, imp["id"])
|
|
config_btc["resueltas"] = {}
|
|
config_btc["borradores"] = {}
|
|
config_btc["importaciones"] = []
|
|
# 2. Lo que metió el CSV
|
|
ids = [m["id"] for m in cartera.datos.vivos("movimientos") if _del_csv(m)]
|
|
if ids:
|
|
cartera.borrar_movimientos(ids)
|
|
# 3. Los activos «BTC en …» que se han quedado vacíos
|
|
if p["activos"]:
|
|
cartera.borrar_activos_vacios([a["id"] for a in p["activos"]])
|
|
ajustes_extractos.pop("destinos_exchange", None)
|
|
return p
|