Some optimizations to trade_offers to reduce loading times
This commit is contained in:
parent
0ac8ac8d5c
commit
9ce5d525b3
13 changed files with 255 additions and 222 deletions
|
|
@ -1,8 +1,9 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.db.models.signals import m2m_changed, post_save, post_delete
|
||||
from django.db.models.signals import m2m_changed, post_save, post_delete, pre_save
|
||||
from django.dispatch import receiver
|
||||
from .models import TradeOffer
|
||||
from cards.models import Card
|
||||
from django.db.models import F
|
||||
from trades.models import TradeOfferHaveCard, TradeOfferWantCard, TradeAcceptance
|
||||
|
||||
def check_trade_offer_rarity(instance):
|
||||
|
|
@ -31,46 +32,79 @@ ACTIVE_STATES = [
|
|||
TradeAcceptance.AcceptanceState.THANKED_BY_BOTH,
|
||||
]
|
||||
|
||||
def update_qty_for_trade_offer(trade_offer, card, side):
|
||||
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':
|
||||
count = TradeAcceptance.objects.filter(
|
||||
trade_offer=trade_offer,
|
||||
requested_card=card,
|
||||
state__in=ACTIVE_STATES
|
||||
).count()
|
||||
TradeOfferHaveCard.objects.filter(
|
||||
trade_offer=trade_offer,
|
||||
card=card
|
||||
).update(qty_accepted=count)
|
||||
|
||||
if count >= TradeOfferHaveCard.objects.filter(trade_offer=trade_offer, card=card).first().quantity:
|
||||
trade_offer.is_closed = True
|
||||
trade_offer.save(update_fields=["is_closed"])
|
||||
elif side == 'want':
|
||||
count = TradeAcceptance.objects.filter(
|
||||
trade_offer=trade_offer,
|
||||
offered_card=card,
|
||||
state__in=ACTIVE_STATES
|
||||
).count()
|
||||
TradeOfferWantCard.objects.filter(
|
||||
trade_offer=trade_offer,
|
||||
card=card
|
||||
).update(qty_accepted=count)
|
||||
|
||||
if count >= TradeOfferWantCard.objects.filter(trade_offer=trade_offer, card=card).first().quantity:
|
||||
trade_offer.is_closed = True
|
||||
trade_offer.save(update_fields=["is_closed"])
|
||||
).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"])
|
||||
|
||||
def update_all_qty(instance):
|
||||
trade_offer = instance.trade_offer
|
||||
update_qty_for_trade_offer(trade_offer, instance.requested_card, 'have')
|
||||
update_qty_for_trade_offer(trade_offer, instance.offered_card, 'want')
|
||||
# Pre-save signal to capture the original state before any changes.
|
||||
@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
|
||||
|
||||
# Post-save signal to adjust qty_accepted incrementally.
|
||||
@receiver(post_save, sender=TradeAcceptance)
|
||||
def trade_acceptance_post_save(sender, instance, **kwargs):
|
||||
update_all_qty(instance)
|
||||
def trade_acceptance_post_save(sender, instance, created, **kwargs):
|
||||
delta = 0
|
||||
if created:
|
||||
# For a new acceptance, increment only if the state is active.
|
||||
if instance.state in ACTIVE_STATES:
|
||||
delta = 1
|
||||
else:
|
||||
old_state = getattr(instance, '_old_state', None)
|
||||
if old_state is not None:
|
||||
# Transition from active to non-active (e.g. a rejection)
|
||||
if old_state in ACTIVE_STATES and instance.state not in ACTIVE_STATES:
|
||||
delta = -1
|
||||
# Transition from non-active to active
|
||||
elif old_state not in ACTIVE_STATES and instance.state in ACTIVE_STATES:
|
||||
delta = 1
|
||||
|
||||
if delta != 0:
|
||||
trade_offer = instance.trade_offer
|
||||
# Update the "have" side using the requested_card.
|
||||
adjust_qty_for_trade_offer(trade_offer, instance.requested_card, side='have', delta=delta)
|
||||
# Update the "want" side using the offered_card.
|
||||
adjust_qty_for_trade_offer(trade_offer, instance.offered_card, side='want', delta=delta)
|
||||
update_trade_offer_closed_status(trade_offer)
|
||||
|
||||
# Post-delete signal to decrement qty_accepted if the deleted acceptance was active.
|
||||
@receiver(post_delete, sender=TradeAcceptance)
|
||||
def trade_acceptance_post_delete(sender, instance, **kwargs):
|
||||
update_all_qty(instance)
|
||||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue