190 lines
8.8 KiB
Python
190 lines
8.8 KiB
Python
from django import forms
|
|
from .models import Seller, CardListing, PackListing, Game, Bounty, BountyOffer
|
|
from users.models import Profile
|
|
|
|
class SellerThemeForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Profile
|
|
fields = ['theme_preference']
|
|
widgets = {
|
|
'theme_preference': forms.Select(attrs={'class': 'form-select'})
|
|
}
|
|
|
|
class SellerRegistrationForm(forms.ModelForm):
|
|
street = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'placeholder': 'Street Address'}))
|
|
city = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'placeholder': 'City'}))
|
|
state = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'placeholder': 'State'}))
|
|
zip_code = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'placeholder': 'Zip Code'}))
|
|
|
|
class Meta:
|
|
model = Seller
|
|
fields = ['store_name', 'description', 'contact_email', 'contact_phone']
|
|
widgets = {
|
|
'description': forms.Textarea(attrs={'rows': 4}),
|
|
}
|
|
|
|
def save(self, commit=True):
|
|
seller = super().save(commit=False)
|
|
# Create address
|
|
# We need the user to link the address to? The Seller model has user.
|
|
# But here seller.user might not be set yet if it's done in the view.
|
|
# However, save(commit=True) usually saves.
|
|
# We'll create the Address instance but we need the user.
|
|
# We can't easily get the user here unless we pass it or it's already on seller.
|
|
# In the view `seller_register`, we do `form.instance.user = request.user` before saving?
|
|
# Let's check `seller_register` view.
|
|
# If we can't create Address yet, we might need to handle it in the view.
|
|
# BUT, standard ModelForm save() returns the instance.
|
|
# Let's attach the address data to the instance temporarily?
|
|
# Or better: Override save to creating the Address.
|
|
# We will assume seller.user is set by the view before save is called,
|
|
# or we just create the address without user first (but user is required in Address model).
|
|
# Actually, Address.user is required.
|
|
# So we MUST have the user.
|
|
return seller
|
|
|
|
class SellerEditForm(forms.ModelForm):
|
|
street = forms.CharField(max_length=200, required=False)
|
|
city = forms.CharField(max_length=100, required=False)
|
|
state = forms.CharField(max_length=100, required=False)
|
|
zip_code = forms.CharField(max_length=20, required=False)
|
|
|
|
tax_id = forms.CharField(required=False, widget=forms.TextInput(attrs={'type': 'password'}), help_text="SSN, ITIN, or EIN (Stored securely)")
|
|
payout_details = forms.CharField(required=False, widget=forms.Textarea(attrs={'rows': 3}), help_text="Bank account or other payout details (Stored securely)")
|
|
|
|
class Meta:
|
|
model = Seller
|
|
fields = ['store_name', 'description', 'contact_email', 'contact_phone', 'store_image', 'hero_image', 'minimum_order_amount', 'shipping_cost', 'tax_id', 'payout_details']
|
|
widgets = {
|
|
'description': forms.Textarea(attrs={'rows': 4}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if self.instance and self.instance.pk:
|
|
self.fields['tax_id'].initial = self.instance.tax_id
|
|
self.fields['payout_details'].initial = self.instance.payout_details
|
|
# Populate address fields
|
|
if self.instance.store_address:
|
|
self.fields['street'].initial = self.instance.store_address.street
|
|
self.fields['city'].initial = self.instance.store_address.city
|
|
self.fields['state'].initial = self.instance.store_address.state
|
|
self.fields['zip_code'].initial = self.instance.store_address.zip_code
|
|
|
|
def save(self, commit=True):
|
|
seller = super().save(commit=False)
|
|
seller.tax_id = self.cleaned_data.get('tax_id')
|
|
seller.payout_details = self.cleaned_data.get('payout_details')
|
|
|
|
# Handle Address
|
|
# We need to update existing or create new.
|
|
street = self.cleaned_data.get('street')
|
|
city = self.cleaned_data.get('city')
|
|
state = self.cleaned_data.get('state')
|
|
zip_code = self.cleaned_data.get('zip_code')
|
|
|
|
if street and city and state and zip_code:
|
|
from users.models import Address
|
|
if seller.store_address:
|
|
seller.store_address.street = street
|
|
seller.store_address.city = city
|
|
seller.store_address.state = state
|
|
seller.store_address.zip_code = zip_code
|
|
if commit:
|
|
seller.store_address.save()
|
|
else:
|
|
# Create new address. Requires user.
|
|
# seller.user should exist.
|
|
address = Address(
|
|
user=seller.user,
|
|
name=seller.store_name, # Use store name for address name
|
|
street=street,
|
|
city=city,
|
|
state=state,
|
|
zip_code=zip_code,
|
|
address_type='shipping' # Default
|
|
)
|
|
if commit:
|
|
address.save()
|
|
seller.store_address = address
|
|
|
|
if commit:
|
|
seller.save()
|
|
return seller
|
|
|
|
class CardListingForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CardListing
|
|
fields = ['condition', 'price', 'quantity', 'status', 'image']
|
|
# TODO: Add search widget for card selection or filter by game/set
|
|
|
|
class PackListingForm(forms.ModelForm):
|
|
class Meta:
|
|
model = PackListing
|
|
fields = ['game', 'name', 'listing_type', 'price', 'quantity', 'image_url']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# Helper to indicate quantity logic
|
|
self.fields['quantity'].help_text = "For Virtual packs, this is automatically updated based on inventory."
|
|
|
|
class AddCardListingForm(forms.Form):
|
|
card_name = forms.CharField(max_length=200, label="Card Name", help_text="Enter the card name.")
|
|
game = forms.ModelChoiceField(queryset=Game.objects.all(), empty_label="Select Game")
|
|
set_name = forms.CharField(max_length=200, label="Set Name", help_text="Enter the set name (e.g., 'Alpha', 'Base Set').")
|
|
collector_number = forms.CharField(max_length=20, required=False, label="Card Number", help_text="The number on the bottom of the card (e.g. '197'). Useful for variants.")
|
|
condition = forms.ChoiceField(choices=CardListing.CONDITION_CHOICES)
|
|
price = forms.DecimalField(max_digits=10, decimal_places=2)
|
|
quantity = forms.IntegerField(min_value=1, initial=1)
|
|
image = forms.ImageField(required=False, label="Card Image")
|
|
|
|
class BountyForm(forms.ModelForm):
|
|
card_name = forms.CharField(max_length=200, label="Card Name", help_text="Search for a card...", required=False)
|
|
card_id = forms.CharField(widget=forms.HiddenInput(), required=False)
|
|
|
|
class Meta:
|
|
model = Bounty
|
|
fields = ['title', 'description', 'target_price', 'quantity_wanted']
|
|
widgets = {
|
|
'description': forms.Textarea(attrs={'rows': 3}),
|
|
}
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
card_id = cleaned_data.get('card_id')
|
|
title = cleaned_data.get('title')
|
|
card_name = cleaned_data.get('card_name')
|
|
|
|
if not card_id and not title and not card_name:
|
|
raise forms.ValidationError("You must either select a Card or provide a Title.")
|
|
|
|
return cleaned_data
|
|
|
|
class BountyOfferForm(forms.ModelForm):
|
|
class Meta:
|
|
model = BountyOffer
|
|
fields = ['price', 'description']
|
|
widgets = {
|
|
'description': forms.Textarea(attrs={'rows': 3}),
|
|
}
|
|
|
|
class MultipleFileInput(forms.ClearableFileInput):
|
|
allow_multiple_selected = True
|
|
|
|
class BulkListingForm(forms.Form):
|
|
csv_file = forms.FileField(label="Upload CSV", help_text="Upload the filled-out template CSV.")
|
|
images = forms.FileField(widget=MultipleFileInput(attrs={'multiple': True}), required=False, label="Upload Images", help_text="Select all images referenced in your CSV.")
|
|
|
|
class CheckoutForm(forms.Form):
|
|
shipping_address = forms.ModelChoiceField(queryset=None, empty_label="Select Shipping Address", widget=forms.Select(attrs={'class': 'form-select'}))
|
|
payment_method = forms.ModelChoiceField(queryset=None, empty_label="Select Payment Method", widget=forms.Select(attrs={'class': 'form-select'}))
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
user = kwargs.pop('user', None)
|
|
super().__init__(*args, **kwargs)
|
|
if user:
|
|
from users.models import Address, PaymentMethod
|
|
self.fields['shipping_address'].queryset = Address.objects.filter(user=user, address_type='shipping')
|
|
self.fields['payment_method'].queryset = PaymentMethod.objects.filter(user=user)
|
|
|