70 lines
3 KiB
Python
70 lines
3 KiB
Python
from django import forms
|
|
from django.core.exceptions import ValidationError
|
|
from .models import TradeOffer
|
|
from friend_codes.models import FriendCode
|
|
from cards.models import Card
|
|
|
|
class TradeOfferUpdateForm(forms.ModelForm):
|
|
class Meta:
|
|
model = TradeOffer
|
|
# We now only edit the `state` field
|
|
fields = ["state"]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""
|
|
Expects additional keyword arguments:
|
|
- friend_codes: a list of friend code objects for the current user.
|
|
This initializer filters the available state choices based on:
|
|
- The current state's allowed transition.
|
|
- Which party (initiated_by or accepted_by) is acting.
|
|
"""
|
|
friend_codes = kwargs.pop("friend_codes")
|
|
super().__init__(*args, **kwargs)
|
|
|
|
instance = self.instance
|
|
allowed_state = None
|
|
|
|
# Define permitted transitions based on the current state and user role:
|
|
if instance.state == TradeOffer.State.INITIATED:
|
|
# Allow the accepted_by party to accept the trade.
|
|
if instance.accepted_by in friend_codes:
|
|
allowed_state = TradeOffer.State.ACCEPTED
|
|
elif instance.state == TradeOffer.State.ACCEPTED:
|
|
# Allow the initiated_by party to mark the trade as sent.
|
|
if instance.initiated_by in friend_codes:
|
|
allowed_state = TradeOffer.State.SENT
|
|
elif instance.state == TradeOffer.State.SENT:
|
|
# Allow the accepted_by party to mark the trade as received.
|
|
if instance.accepted_by in friend_codes:
|
|
allowed_state = TradeOffer.State.RECEIVED
|
|
|
|
if allowed_state:
|
|
# Limit the `state` field's choices to only the permitted transition.
|
|
label = dict(TradeOffer.State.choices)[allowed_state]
|
|
self.fields["state"].choices = [(allowed_state, label)]
|
|
else:
|
|
# If no valid transition is available for this user, remove the field.
|
|
self.fields.pop("state")
|
|
|
|
def clean_have_cards(self):
|
|
have_cards = self.cleaned_data.get("have_cards")
|
|
if have_cards:
|
|
for card in have_cards.all():
|
|
if card.rarity not in ALLOWED_RARITIES:
|
|
# Raising a ValidationError here will cause this error message to be shown beneath the 'have_cards' field.
|
|
raise ValidationError(
|
|
f"The card '{card}' has an invalid rarity: {card.rarity}. Allowed rarities are: {', '.join(ALLOWED_RARITIES)}."
|
|
)
|
|
return have_cards
|
|
|
|
class TradeOfferAcceptForm(forms.Form):
|
|
friend_code = forms.ModelChoiceField(
|
|
queryset=FriendCode.objects.none(),
|
|
label="Select a Friend Code to Accept This Trade Offer"
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
# Expecting a keyword argument `friend_codes` with the user's friend codes.
|
|
friend_codes = kwargs.pop("friend_codes")
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["friend_code"].queryset = friend_codes
|