140 lines
4.5 KiB
Python
140 lines
4.5 KiB
Python
import logging
|
|
import json
|
|
import stripe
|
|
from requests import ConnectionError
|
|
from urllib.parse import quote
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.core.mail import EmailMessage
|
|
from django.core.exceptions import ValidationError
|
|
from localflavor.us.us_states import USPS_CHOICES
|
|
from usps import USPSApi, Address
|
|
from captcha.fields import CaptchaField
|
|
from django_measurement.forms import MeasurementField
|
|
|
|
from core.models import Order, ProductVariant, Subscription
|
|
from core import CoffeeGrind, ShippingContainer
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AddToCartForm(forms.Form):
|
|
quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)
|
|
|
|
def __init__(self, variants, options, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields['variant'] = forms.ChoiceField(
|
|
label='',
|
|
choices=[(variant.pk, f'{variant.name} | ${variant.price}') for variant in variants]
|
|
)
|
|
|
|
for option in options:
|
|
self.fields[option.name] = forms.ChoiceField(
|
|
choices=[(opt, opt) for opt in option.options]
|
|
)
|
|
|
|
|
|
class CartItemUpdateForm(forms.Form):
|
|
item_index = forms.IntegerField(widget=forms.HiddenInput())
|
|
quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)
|
|
|
|
|
|
class AddressForm(forms.Form):
|
|
full_name = forms.CharField()
|
|
email = forms.EmailField()
|
|
street_address_1 = forms.CharField()
|
|
street_address_2 = forms.CharField(required=False)
|
|
city = forms.CharField()
|
|
state = forms.ChoiceField(
|
|
choices=USPS_CHOICES
|
|
)
|
|
postal_code = forms.CharField()
|
|
|
|
def process_full_name(self, full_name):
|
|
name = full_name.split()
|
|
|
|
if len(name) > 2:
|
|
last_name = ''.join(name.pop(-1))
|
|
first_name = ' '.join(name)
|
|
elif len(name) > 1:
|
|
first_name = name[0]
|
|
last_name = name[1]
|
|
else:
|
|
first_name = name[0]
|
|
last_name = ''
|
|
|
|
return first_name, last_name
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
address = Address(
|
|
name=quote(cleaned_data.get('full_name')),
|
|
address_1=quote(cleaned_data.get('street_address_1')),
|
|
address_2=quote(cleaned_data.get('street_address_2')),
|
|
city=quote(cleaned_data.get('city')),
|
|
state=quote(cleaned_data.get('state')),
|
|
zipcode=quote(cleaned_data.get('postal_code'))
|
|
)
|
|
usps = USPSApi(settings.USPS_USER_ID, test=True)
|
|
|
|
try:
|
|
validation = usps.validate_address(address)
|
|
except ConnectionError:
|
|
raise ValidationError(
|
|
'Could not connect to USPS, try again.'
|
|
)
|
|
|
|
if 'Error' in validation.result['AddressValidateResponse']['Address']:
|
|
error = validation.result['AddressValidateResponse']['Address']['Error']['Description']
|
|
raise ValidationError(
|
|
"USPS: " + error
|
|
)
|
|
|
|
try:
|
|
cleaned_data['postal_code'] = validation.result['AddressValidateResponse']['Address']['Zip5']
|
|
except KeyError:
|
|
raise ValidationError(
|
|
'Could not find Zip5'
|
|
)
|
|
|
|
|
|
class CheckoutShippingForm(forms.Form):
|
|
def __init__(self, containers, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields['shipping_method'] = forms.ChoiceField(
|
|
label='',
|
|
widget=forms.RadioSelect,
|
|
choices=[(container.pk, f'{container.name} ${container.s_cost}') for container in containers]
|
|
)
|
|
|
|
|
|
class OrderCreateForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Order
|
|
fields = []
|
|
|
|
|
|
class CouponApplyForm(forms.Form):
|
|
code = forms.CharField(label='Coupon code')
|
|
|
|
|
|
class SubscriptionForm(forms.Form):
|
|
GRIND_CHOICES = [
|
|
('Whole Beans', 'Whole Beans'),
|
|
('Espresso', 'Espresso'),
|
|
('Cone Drip', 'Cone Drip'),
|
|
('Basket Drip', 'Basket Drip'),
|
|
('French Press', 'French Press'),
|
|
('Stovetop Espresso (Moka Pot)', 'Stovetop Espresso (Moka Pot)'),
|
|
('AeroPress', 'AeroPress'),
|
|
('Percolator', 'Percolator'),
|
|
('BLTC cafe pour over', 'BLTC cafe pour over')
|
|
]
|
|
grind = forms.ChoiceField(choices=GRIND_CHOICES, label='')
|
|
products_and_quantities = forms.CharField(widget=forms.HiddenInput())
|
|
stripe_price_id = forms.CharField(widget=forms.HiddenInput())
|
|
total_quantity = forms.IntegerField(widget=forms.HiddenInput())
|
|
total_weight = forms.CharField(widget=forms.HiddenInput())
|