Configuración de automatización de CICD #35

Merged
jkuijperm merged 9 commits from dev into main 2026-09-29 16:11:55 +00:00
Showing only changes of commit 9af6e749d5 - Show all commits

View File

@ -0,0 +1,72 @@
"""Convierte en Transfer los traspasos históricos que estaban sueltos.
Antes de que existiera Transfer, un traspaso eran dos movimientos marcados con
is_transfer pero sin nada que los relacionara: un Expense en la cuenta de origen
y un Income en la de destino. Aquí se emparejan y se les cuelga un Transfer.
No se pueden emparejar con certeza: nada en la base de datos dice qué gasto va
con qué ingreso. El criterio es mismo owner, mismo importe, misma fecha y cuentas
distintas, y solo cuando en ese grupo hay exactamente un gasto y un ingreso. Los
ambiguos (varios candidatos con el mismo importe y fecha) y los huérfanos (sin
pareja) se dejan tal cual, con su is_transfer=True: siguen contando en los saldos
y fuera de los análisis igual que antes, solo que sin Transfer que los orqueste.
Emparejarlos a ojo sería inventarse datos del usuario.
"""
from collections import defaultdict
from django.db import migrations
def link_legacy_transfers(apps, schema_editor):
Expense = apps.get_model("expenses", "Expense")
Income = apps.get_model("expenses", "Income")
Transfer = apps.get_model("expenses", "Transfer")
# Solo las patas que aún no pertenecen a ningún Transfer.
expenses_by_key = defaultdict(list)
for expense in Expense.objects.filter(
is_transfer=True, transfer_out__isnull=True, transfer_fee__isnull=True
):
expenses_by_key[(expense.owner_id, expense.amount, expense.date)].append(
expense
)
incomes_by_key = defaultdict(list)
for income in Income.objects.filter(is_transfer=True, transfer_in__isnull=True):
incomes_by_key[(income.owner_id, income.amount, income.date)].append(income)
for key, expenses in expenses_by_key.items():
incomes = incomes_by_key.get(key, [])
# Uno y solo uno de cada lado: cualquier otra cosa es ambigua.
if len(expenses) != 1 or len(incomes) != 1:
continue
expense, income = expenses[0], incomes[0]
if expense.account_id == income.account_id:
continue
Transfer.objects.create(
owner_id=expense.owner_id,
date=expense.date,
amount=expense.amount,
from_account_id=expense.account_id,
to_account_id=income.account_id,
expense_leg=expense,
income_leg=income,
)
class Migration(migrations.Migration):
dependencies = [
("expenses", "0014_category_is_system_transfer"),
]
operations = [
# Sin marcha atrás: deshacer esto es deshacer 0014, que se lleva la tabla
# Transfer entera y deja las patas intactas, que es el estado de partida.
migrations.RunPython(link_legacy_transfers, migrations.RunPython.noop),
]