CRITICAL FIX: Remove duplicate signal handler causing double transactions
- Fixed signals.py which contained two signal handlers creating duplicate transactions - Removed broken signal handler that created transactions without referenz - Keep only the proper signal handler with PAY- referenz and duplicate prevention - This resolves the issue where payments were deducted twice from account balance - Cleaned up malformed docstring and signal structure in signals.py The issue was that payments were processed by both: 1. Broken signal handler (empty referenz) - creating first transaction 2. Proper signal handler (PAY- referenz) - creating second transaction Now only the proper handler runs, preventing double balance deduction.
This commit is contained in:
@@ -1,31 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
Django signals for the Stiftung app.
|
Django signals for the Stiftung app.
|
||||||
Handles automatic # Check if a bank transaction already exists for this specific payment
|
Handles automatic payment tracking and account balance updates when model instances change.
|
||||||
existing_transaction = BankTransaction.objects.filter(
|
|
||||||
konto=instance.konto,
|
|
||||||
betrag=-instance.betrag, # Negative for outgoing payment
|
|
||||||
kommentare__contains=f'Unterstützung {instance.id}'
|
|
||||||
).first()
|
|
||||||
|
|
||||||
if existing_transaction:
|
|
||||||
print(f"⚠️ Transaction already exists for payment {instance.id} - skipping creation")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Create a bank transaction for this payment
|
|
||||||
BankTransaction.objects.create(
|
|
||||||
konto=instance.konto,
|
|
||||||
datum=instance.ausgezahlt_am or timezone.now().date(),
|
|
||||||
valuta=instance.ausgezahlt_am or timezone.now().date(),
|
|
||||||
betrag=-instance.betrag, # Negative because it's an outgoing payment
|
|
||||||
waehrung='EUR',
|
|
||||||
verwendungszweck=f"Unterstützungszahlung: {instance.beschreibung or instance.destinataer.get_full_name()}",
|
|
||||||
empfaenger_zahlungspflichtiger=instance.empfaenger_name or instance.destinataer.get_full_name(),
|
|
||||||
iban_gegenpartei=instance.empfaenger_iban or '',
|
|
||||||
transaction_type='ueberweisung',
|
|
||||||
status='verified',
|
|
||||||
kommentare=f'Automatisch erstellt bei Markierung als ausgezahlt für Unterstützung {instance.id}',
|
|
||||||
referenz=f'PAY-{instance.id}', # Add unique reference to avoid conflicts
|
|
||||||
)model instances change.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db.models.signals import post_save, pre_save
|
from django.db.models.signals import post_save, pre_save
|
||||||
@@ -64,8 +39,6 @@ def update_account_balance_on_payment(sender, instance, created, **kwargs):
|
|||||||
|
|
||||||
# Check if a transaction already exists for this payment to prevent duplicates
|
# Check if a transaction already exists for this payment to prevent duplicates
|
||||||
existing_transaction = BankTransaction.objects.filter(
|
existing_transaction = BankTransaction.objects.filter(
|
||||||
konto=instance.konto,
|
|
||||||
betrag=-instance.betrag, # Negative for outgoing payment
|
|
||||||
kommentare__contains=f'Unterstützung {instance.id}'
|
kommentare__contains=f'Unterstützung {instance.id}'
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
@@ -81,35 +54,28 @@ def update_account_balance_on_payment(sender, instance, created, **kwargs):
|
|||||||
ausgezahlt_am=instance.ausgezahlt_am
|
ausgezahlt_am=instance.ausgezahlt_am
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if a transaction already exists for this payment
|
# Create a bank transaction for this payment
|
||||||
existing_transaction = BankTransaction.objects.filter(
|
transaction = BankTransaction.objects.create(
|
||||||
kommentare__contains=f'Unterstützung {instance.id}'
|
konto=instance.konto,
|
||||||
).first()
|
datum=instance.ausgezahlt_am or timezone.now().date(),
|
||||||
|
valuta=instance.ausgezahlt_am or timezone.now().date(),
|
||||||
|
betrag=-instance.betrag, # Negative because it's an outgoing payment
|
||||||
|
waehrung='EUR',
|
||||||
|
verwendungszweck=f"Unterstützungszahlung: {instance.beschreibung or instance.destinataer.get_full_name()}",
|
||||||
|
empfaenger_zahlungspflichtiger=instance.empfaenger_name or instance.destinataer.get_full_name(),
|
||||||
|
iban_gegenpartei=instance.empfaenger_iban or '',
|
||||||
|
transaction_type='ueberweisung',
|
||||||
|
status='verified',
|
||||||
|
referenz=f'PAY-{instance.id}', # Unique reference to prevent duplicates
|
||||||
|
kommentare=f'Automatisch erstellt bei Markierung als ausgezahlt für Unterstützung {instance.id}',
|
||||||
|
)
|
||||||
|
|
||||||
if not existing_transaction:
|
# Update account balance
|
||||||
# Create a bank transaction for this payment
|
instance.konto.saldo -= instance.betrag
|
||||||
transaction = BankTransaction.objects.create(
|
instance.konto.saldo_datum = instance.ausgezahlt_am or timezone.now().date()
|
||||||
konto=instance.konto,
|
instance.konto.save()
|
||||||
datum=instance.ausgezahlt_am or timezone.now().date(),
|
|
||||||
valuta=instance.ausgezahlt_am or timezone.now().date(),
|
print(f"✅ Account balance updated: {instance.konto.kontoname} - €{instance.betrag} (Payment to {instance.destinataer.get_full_name()}) - Transaction {transaction.id}")
|
||||||
betrag=-instance.betrag, # Negative because it's an outgoing payment
|
|
||||||
waehrung='EUR',
|
|
||||||
verwendungszweck=f"Unterstützungszahlung: {instance.beschreibung or instance.destinataer.get_full_name()}",
|
|
||||||
empfaenger_zahlungspflichtiger=instance.empfaenger_name or instance.destinataer.get_full_name(),
|
|
||||||
iban_gegenpartei=instance.empfaenger_iban or '',
|
|
||||||
transaction_type='ueberweisung',
|
|
||||||
status='verified',
|
|
||||||
referenz=f'PAY-{instance.id}', # Unique reference to prevent duplicates
|
|
||||||
kommentare=f'Automatisch erstellt bei Markierung als ausgezahlt für Unterstützung {instance.id}',
|
|
||||||
)
|
|
||||||
# Update account balance only for new transactions
|
|
||||||
instance.konto.saldo -= instance.betrag
|
|
||||||
instance.konto.saldo_datum = instance.ausgezahlt_am or timezone.now().date()
|
|
||||||
instance.konto.save()
|
|
||||||
print(f"✅ Account balance updated: {instance.konto.kontoname} - €{instance.betrag} (Payment to {instance.destinataer.get_full_name()}) - Transaction {transaction.id}")
|
|
||||||
else:
|
|
||||||
transaction = existing_transaction
|
|
||||||
print(f"ℹ️ Transaction already exists for payment {instance.id}, balance not modified")
|
|
||||||
|
|
||||||
# Handle reversal if payment is changed from paid back to unpaid
|
# Handle reversal if payment is changed from paid back to unpaid
|
||||||
elif old_status == 'ausgezahlt' and instance.status != 'ausgezahlt':
|
elif old_status == 'ausgezahlt' and instance.status != 'ausgezahlt':
|
||||||
@@ -132,35 +98,31 @@ def update_account_balance_on_payment(sender, instance, created, **kwargs):
|
|||||||
instance.konto.saldo_datum = timezone.now().date()
|
instance.konto.saldo_datum = timezone.now().date()
|
||||||
instance.konto.save()
|
instance.konto.save()
|
||||||
|
|
||||||
print(f"✅ Account balance reversed: {instance.konto.kontoname} + €{instance.betrag} (Payment reversal for {instance.destinataer.get_full_name()})")
|
# Clear the ausgezahlt_am date
|
||||||
else:
|
# Update without triggering signals
|
||||||
print(f"⚠️ No transaction found to reverse for payment {instance.id}")
|
DestinataerUnterstuetzung.objects.filter(pk=instance.pk).update(
|
||||||
|
ausgezahlt_am=None
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"🔄 Payment reversal: Account balance restored for {instance.destinataer.get_full_name()} - €{instance.betrag}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"⚠️ Error reversing payment transaction: {e}")
|
print(f"⚠️ Error reversing payment for {instance.destinataer.get_full_name()}: {e}")
|
||||||
|
|
||||||
# Clear the ausgezahlt_am date
|
|
||||||
if instance.ausgezahlt_am:
|
|
||||||
# Update without triggering signals
|
|
||||||
DestinataerUnterstuetzung.objects.filter(pk=instance.pk).update(
|
|
||||||
ausgezahlt_am=None
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=BankTransaction)
|
@receiver(post_save, sender=BankTransaction)
|
||||||
def update_account_balance_on_transaction(sender, instance, created, **kwargs):
|
def update_account_balance_on_transaction(sender, instance, created, **kwargs):
|
||||||
"""
|
"""
|
||||||
Update account balance when a new bank transaction is imported or created.
|
Update account balance whenever a new bank transaction is created or modified
|
||||||
Only update if the transaction has a saldo_nach_buchung value or if it's manually created.
|
(excluding transactions created by payment processing to avoid double-counting)
|
||||||
"""
|
"""
|
||||||
if created and instance.status in ['verified', 'imported']:
|
# Skip if this is a payment-related transaction (already handled by payment signal)
|
||||||
# If the transaction has a balance after booking, use that
|
if instance.kommentare and 'Unterstützung' in instance.kommentare:
|
||||||
if instance.saldo_nach_buchung is not None:
|
return
|
||||||
instance.konto.saldo = instance.saldo_nach_buchung
|
|
||||||
instance.konto.saldo_datum = instance.datum
|
if created:
|
||||||
instance.konto.save()
|
# Update the account balance based on the transaction
|
||||||
else:
|
instance.konto.saldo += instance.betrag # Add the transaction amount
|
||||||
# Otherwise, calculate the new balance
|
instance.konto.saldo_datum = instance.valuta or instance.datum
|
||||||
instance.konto.saldo += instance.betrag
|
instance.konto.save()
|
||||||
instance.konto.saldo_datum = instance.datum
|
|
||||||
instance.konto.save()
|
print(f"💰 Account balance updated from transaction: {instance.konto.kontoname} {'+ ' if instance.betrag >= 0 else '- '}€{abs(instance.betrag)}")
|
||||||
Reference in New Issue
Block a user