pkmntrade.club/trades/signals.py

83 lines
No EOL
3.3 KiB
Python

from django.db.models.signals import post_save, post_delete, pre_save
from django.dispatch import receiver
from django.db.models import F
from trades.models import TradeOfferHaveCard, TradeOfferWantCard, TradeAcceptance
from django.db import transaction
ACTIVE_STATES = [
TradeAcceptance.AcceptanceState.ACCEPTED,
TradeAcceptance.AcceptanceState.SENT,
TradeAcceptance.AcceptanceState.RECEIVED,
TradeAcceptance.AcceptanceState.THANKED_BY_INITIATOR,
TradeAcceptance.AcceptanceState.THANKED_BY_ACCEPTOR,
TradeAcceptance.AcceptanceState.THANKED_BY_BOTH,
]
def adjust_qty_for_trade_offer(trade_offer, card, side, delta):
"""
Increment (or decrement) qty_accepted by delta for the given card on the specified side.
"""
if side == 'have':
TradeOfferHaveCard.objects.filter(
trade_offer=trade_offer,
card=card
).update(qty_accepted=F('qty_accepted') + delta)
elif side == 'want':
TradeOfferWantCard.objects.filter(
trade_offer=trade_offer,
card=card
).update(qty_accepted=F('qty_accepted') + delta)
def update_trade_offer_closed_status(trade_offer):
"""
Check if both sides of the trade offer meet the quantity requirement.
Mark the trade_offer as closed if all cards have qty_accepted
greater than or equal to quantity; otherwise, mark it as open.
"""
have_complete = not TradeOfferHaveCard.objects.filter(
trade_offer=trade_offer,
qty_accepted__lt=F('quantity')
).exists()
want_complete = not TradeOfferWantCard.objects.filter(
trade_offer=trade_offer,
qty_accepted__lt=F('quantity')
).exists()
closed = have_complete or want_complete
if trade_offer.is_closed != closed:
trade_offer.is_closed = closed
trade_offer.save(update_fields=["is_closed"])
@receiver(pre_save, sender=TradeAcceptance)
def trade_acceptance_pre_save(sender, instance, **kwargs):
if instance.pk:
old_instance = TradeAcceptance.objects.get(pk=instance.pk)
instance._old_state = old_instance.state
@receiver(post_save, sender=TradeAcceptance)
def trade_acceptance_post_save(sender, instance, created, **kwargs):
delta = 0
if created:
if instance.state in ACTIVE_STATES:
delta = 1
else:
old_state = getattr(instance, '_old_state', None)
if old_state is not None:
if old_state in ACTIVE_STATES and instance.state not in ACTIVE_STATES:
delta = -1
elif old_state not in ACTIVE_STATES and instance.state in ACTIVE_STATES:
delta = 1
if delta != 0:
trade_offer = instance.trade_offer
adjust_qty_for_trade_offer(trade_offer, instance.requested_card, side='have', delta=delta)
adjust_qty_for_trade_offer(trade_offer, instance.offered_card, side='want', delta=delta)
update_trade_offer_closed_status(trade_offer)
@receiver(post_delete, sender=TradeAcceptance)
def trade_acceptance_post_delete(sender, instance, **kwargs):
if instance.state in ACTIVE_STATES:
delta = -1
trade_offer = instance.trade_offer
adjust_qty_for_trade_offer(trade_offer, instance.requested_card, side='have', delta=delta)
adjust_qty_for_trade_offer(trade_offer, instance.offered_card, side='want', delta=delta)
update_trade_offer_closed_status(trade_offer)