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