def account_billing(self, request): if request.method == 'POST': form = BillingAddressForm(request.POST) else: form = BillingAddressForm() form.configure(request) if form.is_valid(): data = form.cleaned_data request.user.first_name = data.get('first_name') request.user.last_name = data.get('last_name') request.user.save() profile = get_customer_model().objects.get(user=request.user) profile.title = data.get('title') profile.company = data.get('company') profile.address1 = data.get('address1') profile.address2 = data.get('address2') profile.address3 = data.get('address3') profile.city = data.get('city') profile.county = data.get('county') profile.postcode = data.get('postcode') profile.country = data.get('country') profile.save() messages.success(request, 'Your delivery address has been changed.') return HttpResponseRedirect(reverse('shop.account.index')) return { 'account_section': True, 'form': form }
def account_details(self, request): if request.method == 'POST': form = ChangeDetailsForm(request.POST) else: form = ChangeDetailsForm() form.configure(request) if form.is_valid(): data = form.cleaned_data u = request.user p = get_customer_model().objects.get(user=u) if request.settings.mailchimp_enabled: # subscription details ms = MailSnake(request.settings.mailchimp_api) person_name = [data.get('first_name'), data.get('last_name')] merge_vars = {'FNAME': ' '.join(person_name)} # unsubscribe if email changed or we no longer want to be subscribed if 'email_address' in form.changed_data or ('newsletter' in form.changed_data and not data.get('newsletter')): try: ms.listUnsubscribe(id=request.settings.mailchimp_list_id, email_address=u.email) except: pass # subscribe if newsletter subscription changed or email was changed if ('email_address' in form.changed_data or 'newsletter' in form.changed_data) and data.get('newsletter'): try: ms.listSubscribe(id=request.settings.mailchimp_list_id, email_address=data.get('email_address'), merge_vars=merge_vars) except: pass # update newletter state in profile p.newsletter = data.get('newsletter') # update personal details on user record u.first_name = data.get('first_name') u.last_name = data.get('last_name') u.email = data.get('email_address') u.save() # update personal details on profile record p.title = data.get('title') p.first_name = data.get('first_name') p.last_name = data.get('last_name') p.telephone = data.get('phone') p.email = data.get('email_address') p.save() # success message and redirect to dashboard messages.success(request, 'Your details have been changed.') return HttpResponseRedirect(reverse('shop.account.index')) return { 'account_section': True, 'form': form }
def clean_email_address(self): email = self.cleaned_data['email_address'] if 'email_address' in self.changed_data: if get_customer_model().objects.filter(email=email).count( ) > 0 or get_user_model().objects.filter(email=email).count() > 0: raise forms.ValidationError( 'An account with the given email address already exists.') return email
def _wrapped_view(request, *args, **kwargs): # authenticated users are free to continue if request.user.is_authenticated(): if get_customer_model().objects.filter( user=request.user).count() == 1: return view_func(request, *args, **kwargs) # otherwise we redirect to checkout login page return HttpResponseRedirect(reverse('shop.account.login'))
def clean_email(self): """ Make sure that the email is not taken if the user checked signup. """ signup = self.cleaned_data.get('signup', False) email = self.cleaned_data.get('email', None) if signup == True: if get_customer_model().objects.filter(email=email).count() > 0: raise forms.ValidationError( 'Email address already used. Please provide a different email address for signing up for a new account.' ) return email
def account_index(self, request): profile = get_customer_model().objects.get(user=request.user) orders = get_order_model().objects.get_processing_orders(user=request.user)[:3] try: address = request.user.delivery_addresses.all()[0] except IndexError: address = None return { 'account_section': True, 'profile': profile, 'orders': orders, 'address': address }
def configure(self, request): self._request = request u = self._request.user p = get_customer_model().objects.get(user=u) self.fields['first_name'].initial = u.first_name self.fields['last_name'].initial = u.last_name self.fields['email_address'].initial = u.email self.fields['title'].initial = p.title self.fields['phone'].initial = p.telephone self.fields['newsletter'].initial = p.newsletter if not request.settings.mailchimp_enabled: self.remove_field('newsletter')
def configure(self, request): self._request = request u = self._request.user p = get_customer_model().objects.get(user=u) self.fields['first_name'].initial = u.first_name self.fields['last_name'].initial = u.last_name self.fields['title'].initial = p.title self.fields['company'].initial = p.company self.fields['address1'].initial = p.address1 self.fields['address2'].initial = p.address2 self.fields['address3'].initial = p.address3 self.fields['city'].initial = p.city self.fields['county'].initial = p.county self.fields['postcode'].initial = p.postcode self.fields['country'].initial = p.country if 'cubane.postcode' not in settings.INSTALLED_APPS: self.remove_field('postcode_lookup')
def _wrapped_view(request, *args, **kwargs): # authenticated users are free to continue if request.user.is_authenticated(): if get_customer_model().objects.filter( user_id=request.user.id).count() == 1: return view_func(request, *args, **kwargs) # Do we provide guest checkout? if request.settings.guest_checkout: # AnonymousUser need to provide an email if request.user.is_anonymous(): if request.session.get(settings.GUEST_USER_SESSION_VAR, None) != None: return view_func(request, *args, **kwargs) # otherwise we redirect to checkout login page return HttpResponseRedirect(reverse('shop.order.login')) else: # No guest checkout -> Go to account registration/login return HttpResponseRedirect( reverse('shop.account.login') + '?checkout=1')
def complete(request): """ (3) Final checkout step, where the order is actually created from the basket. """ basket = Basket(request) # redirect back to a previous step if we missed anything... next = get_next_checkout_step(request, basket, CurrentPage.COMPLETE()) if next: return HttpResponseRedirect(next) # state or county if 'state' in basket.billing_address: county = basket.billing_address.get('state') else: county = basket.billing_address.get('county') # create account if requested if basket.signup: # create user account md5 = hashlib.md5() md5.update(basket.signup.get('email')) email = basket.signup.get('email') if User.objects.filter(email=email).count() > 0: messages.warning( request, 'There is already an account with this email: %s.' % email) return HttpResponseRedirect(reverse('shop.account.login')) user = User.objects.create(username=md5.hexdigest()[:30], first_name=basket.signup.get('first_name'), last_name=basket.signup.get('last_name'), email=email) # replace username with user id and set password user.username = unicode(user.id) user.set_password(basket.signup.get('password')) user.save() # create profile get_customer_model().objects.create( user=user, first_name=user.first_name, last_name=user.last_name, email=user.email, title=basket.billing_address.get('title'), address1=basket.billing_address.get('address1'), address2=basket.billing_address.get('address2'), address3=basket.billing_address.get('address3'), city=basket.billing_address.get('city'), county=county, postcode=basket.billing_address.get('postcode'), country=basket.billing_address.get('country'), telephone=basket.billing_address.get('telephone'), newsletter=basket.newsletter) # log user in login_user_without_password(request, user) basket.signup = None else: if request.user.is_anonymous(): user = None else: user = request.user # if specified, copy relevant information to customer's profile if user != None and basket.update_profile: user.first_name = basket.billing_address.get('first_name') user.last_name = basket.billing_address.get('last_name') user.save() customer = get_customer_model().objects.get(user=user) customer.address1 = basket.billing_address.get('address1') customer.address2 = basket.billing_address.get('address2') customer.address3 = basket.billing_address.get('address3') customer.city = basket.billing_address.get('city') customer.county = county customer.postcode = basket.billing_address.get('postcode') customer.country = basket.billing_address.get('country') customer.telephone = basket.billing_address.get('telephone') customer.save() # create single order order = get_order_model().create_from_basket(request, basket, user) # mailchimp if request.settings.mailchimp_enabled and basket.newsletter: email = basket.billing_address.get('email') first_name = basket.billing_address.get('first_name') last_name = basket.billing_address.get('last_name') person_name = (first_name, last_name) merge_vars = {'FNAME': " ".join(person_name)} ms = MailSnake(request.settings.mailchimp_api) try: ms.listSubscribe(id=request.settings.mailchimp_list_id, email_address=email, merge_vars=merge_vars) except: pass # redirect to order status page (payment from there...) basket.save() return HttpResponseRedirect( reverse('shop.order.status', args=[order.secret_id]))
class ChangeDetailsForm(BaseForm): _name = SectionField( label='Personal Details', help_text='These details are also used on your delivery address') title = forms.ChoiceField(required=True, choices=get_customer_model().TITLE_CHOICES) first_name = forms.CharField(label='First Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) last_name = forms.CharField(label='Last Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) phone = forms.CharField( label='Phone', max_length=40, required=True, help_text='We may give you a call regarding your order if required.') email_address = forms.EmailField( label='Email', help_text='This E-mail address is also your username for this website', widget=EmailInput) newsletter = forms.BooleanField( label='', required=False, initial=False, help_text='Yes, subscribe me to the newsletter.') def configure(self, request): self._request = request u = self._request.user p = get_customer_model().objects.get(user=u) self.fields['first_name'].initial = u.first_name self.fields['last_name'].initial = u.last_name self.fields['email_address'].initial = u.email self.fields['title'].initial = p.title self.fields['phone'].initial = p.telephone self.fields['newsletter'].initial = p.newsletter if not request.settings.mailchimp_enabled: self.remove_field('newsletter') def clean(self): d = super(ChangeDetailsForm, self).clean() return clean_address(self, d) def clean_email_address(self): email = self.cleaned_data['email_address'] if 'email_address' in self.changed_data: if get_customer_model().objects.filter(email=email).count( ) > 0 or get_user_model().objects.filter(email=email).count() > 0: raise forms.ValidationError( 'An account with the given email address already exists.') return email
def clean_email(self): email = self.cleaned_data['email'] # check customer and admin if get_customer_model().objects.filter(email=email).count() > 0 or get_user_model().objects.filter(email=email).count() > 0: raise forms.ValidationError('An account with the given email address already exists. If you forgot your password, please use the password forgotten function.') return email
class SignupForm(BaseForm): __name = SectionField(label='Your Name') title = forms.ChoiceField( required=True, choices=get_customer_model().TITLE_CHOICES ) first_name = forms.CharField( label='First Name', max_length=30, required=True, widget=forms.TextInput(attrs={'size':'40', 'class': 'text'}) ) last_name = forms.CharField( label='Last Name', max_length=30, required=True, widget=forms.TextInput(attrs={'size':'40', 'class': 'text'}) ) country = forms.ModelChoiceField( required=True, empty_label=None, initial='GB', queryset=Country.objects.all() ) __account = SectionField(label='Account Name and Password') email = forms.EmailField( label='Email', max_length=255, required=True, help_text='This E-mail address is also your username for this website', widget=EmailInput ) password = forms.CharField( label='Password', #min_length=6, max_length=255, required=True, help_text='Your password must be at least 6 characters in length.', widget=forms.PasswordInput(render_value=True) ) password_confirm = forms.CharField( label='Confirm Password', min_length=6, max_length=255, required=True, help_text='Confirm your password.', widget=forms.PasswordInput(render_value=True) ) _newsletter = SectionField(label='Newsletter (Optional)') newsletter = forms.BooleanField( label='', required=False, initial=False, help_text='Yes, subscribe me to the newsletter.' ) # init the captchas captcha = captchas.get_captcha_widget() if settings.CAPTCHA else None captcha_hash = forms.CharField(max_length=255, widget=forms.HiddenInput, required=False) if hasattr(settings, 'CAPTCHA') and not hasattr(settings, 'CAPTCHA_SECRET_KEY') else None checkout = forms.BooleanField(required=False, initial=False, widget=forms.HiddenInput) def clean(self): d = super(SignupForm, self).clean() # clean captcha if not hasattr(settings, 'CAPTCHA_SECRET_KEY') and hasattr(settings, 'CAPTCHA'): captchas.clean_captcha_data(d, self) return d def configure(self, request): self._request = request if not self._request.settings.mailchimp_enabled: self.remove_field('newsletter') def clean_email(self): email = self.cleaned_data['email'] # check customer and admin if get_customer_model().objects.filter(email=email).count() > 0 or get_user_model().objects.filter(email=email).count() > 0: raise forms.ValidationError('An account with the given email address already exists. If you forgot your password, please use the password forgotten function.') return email def clean_password_confirm(self): """ Password confirm must match password. """ password = self.cleaned_data.get('password', None) password_confirm = self.cleaned_data.get('password_confirm', None) if password != password_confirm: raise forms.ValidationError('Password confirmation is required to match password.') return password_confirm
def configure(self, request, basket): self._request = request self._basket = basket fields_list = [ 'email', 'signup', 'password', 'password_confirm', 'survey' ] if request.settings.has_survey: self.fields['survey'].choices = [('', '-------')] + [ (o, o) for o in request.settings.get_survey_options() ] else: del self.fields['survey'] if not request.settings.mailchimp_enabled: del self.fields['newsletter'] # finance option self.fields[ 'finance_option'].queryset = basket.get_finance_options_queryset() # terms and condition if not request.settings.has_terms: del self.fields['terms'] else: self.fields['terms'].help_text = mark_safe( 'I have read and agree to the <a href="' + request.settings.get_terms() + '" target="_blank">terms and conditions</a>.') # collect additional delivery address options from customer's profile # (only available if we are allowed to edit the delivery address) if basket.can_edit_delivery_address and not request.user.is_anonymous( ): addresses = [(x.id, unicode(x)) for x in request.user.delivery_addresses.all()] self.fields['deliver_to'].choices += addresses if not request.user.is_anonymous(): # authenticated user with a valid profile do not need to fill out # all the information but we pre fill out the majority of the # fields... self.fields['first_name'].initial = request.user.first_name self.fields['last_name'].initial = request.user.last_name try: p = get_customer_model().objects.get(user=request.user) self.fields['title'].initial = p.title self.fields['address1'].initial = p.address1 self.fields['address2'].initial = p.address2 self.fields['address3'].initial = p.address3 self.fields['city'].initial = p.city self.fields['county'].initial = p.county self.fields['postcode'].initial = p.postcode self.fields['country'].initial = p.country self.fields['telephone'].initial = p.telephone if p.newsletter: if 'newsletter' in self.fields: del self.fields['newsletter'] if '_newsletter' in self.fields: del self.fields['_newsletter'] for field in fields_list: if field in self.fields: del self.fields[field] except get_customer_model().DoesNotExist: pass else: # guests need to fill out the entire form, copy only the email self.fields['email'].initial = request.session.get( settings.GUEST_USER_SESSION_VAR, '') del self.fields['update_profile'] # billing address changable? if not basket.can_edit_billing_address: for field in self.ADDRESS_FIELD_NAMES: del self.fields[field] # delivery address changeable? if not basket.can_edit_delivery_address: self.fields[ 'deliver_to'].choices = self.DELIVERY_CHOICES_RESTRICTED for field in self.ADDRESS_FIELD_NAMES: del self.fields['delivery_%s' % field] # free delivery to if basket.can_have_free_delivery_to(): self.fields['deliver_to'].choices = [ (DeliveryAddressFrom.FREE_DELIVERY_TO, 'Free delivery to %s' % basket.get_free_delivery_to()) ] + self.fields['deliver_to'].choices else: del self.fields['delivery_code'] # special requirements if not request.settings.special_requirements: del self.fields['special_req']
class BillingAddressForm(BaseForm): postcode_lookup = PostcodeLookupField(label='Find Address', address1='id_address1', address2='id_address2', address3='id_address3', address4=None, locality=None, city='id_city', county='id_county', postcode='id_postcode', custom_css='text') __name = SectionField(label='Name') title = forms.ChoiceField(required=True, choices=get_customer_model().TITLE_CHOICES) first_name = forms.CharField(label='First Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) last_name = forms.CharField(label='Last Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) __address = SectionField(label='Address') company = forms.CharField(label='Company', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address1 = forms.CharField(label='Address 1', max_length=255, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address2 = forms.CharField(label='Address 2', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address3 = forms.CharField(label='Address 3', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) city = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) country = forms.ModelChoiceField(required=True, empty_label=None, initial='GB', queryset=Country.objects.all()) county = forms.CharField(required=True, max_length=255, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) postcode = forms.CharField(max_length=10, required=True, widget=forms.TextInput(attrs={ 'size': '10', 'class': 'text' })) def configure(self, request): self._request = request u = self._request.user p = get_customer_model().objects.get(user=u) self.fields['first_name'].initial = u.first_name self.fields['last_name'].initial = u.last_name self.fields['title'].initial = p.title self.fields['company'].initial = p.company self.fields['address1'].initial = p.address1 self.fields['address2'].initial = p.address2 self.fields['address3'].initial = p.address3 self.fields['city'].initial = p.city self.fields['county'].initial = p.county self.fields['postcode'].initial = p.postcode self.fields['country'].initial = p.country if 'cubane.postcode' not in settings.INSTALLED_APPS: self.remove_field('postcode_lookup') def clean(self): d = super(BillingAddressForm, self).clean() return clean_address(self, d)
def delivery(request): """ (1) Start to checkout by confirming the delivery address. The customer is required to login for checkout first (see login). """ basket = Basket(request) if basket.is_empty(): return HttpResponseRedirect('/') # if the basket contains collection only products, # force click and collect if basket.is_collection_only(): basket.set_click_and_collect(True) if request.method == 'POST': form = DeliveryAddressFrom(request.POST) else: billing = basket.billing_address if basket.billing_address else {} delivery = basket.delivery_address if basket.delivery_address else {} profile = None default = {} user = request.user if not user.is_anonymous(): try: profile = get_customer_model().objects.get(user=user) default = { 'title': profile.title, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, 'telephone': profile.telephone } if basket.has_billing_address(): default.update({ 'company': profile.company, 'address1': profile.address1, 'address2': profile.address2, 'address3': profile.address3, 'city': profile.city, 'country': profile.country, 'county': profile.county, 'postcode': profile.postcode }) except get_customer_model().DoesNotExist: pass else: default = { 'email': request.session.get(settings.GUEST_USER_SESSION_VAR), 'country': 'GB' } def _get(name, data, fallback=None): v = data.get(name) if v is None and fallback is not None: v = fallback.get(name) return v form = DeliveryAddressFrom( initial={ 'title': _get('title', billing, default), 'first_name': _get('first_name', billing, default), 'last_name': _get('last_name', billing, default), 'email': _get('email', billing, default), 'telephone': _get('telephone', billing, default), 'company': _get('company', billing, default), 'address1': _get('address1', billing, default), 'address2': _get('address2', billing, default), 'address3': _get('address3', billing, default), 'city': _get('city', billing, default), 'country': _get('country', billing, default), 'county': _get('county', billing, default), 'postcode': _get('postcode', billing, default), 'deliver_to': DeliveryAddressFrom.DELIVERY_COLLECTION if basket. is_click_and_collect( ) else DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS, 'free_name': _get('free_name', delivery), 'delivery_name': _get('name', delivery), 'delivery_company': _get('company', delivery), 'delivery_address1': _get('address1', delivery), 'delivery_address2': _get('address2', delivery), 'delivery_address3': _get('address3', delivery), 'delivery_city': _get('city', delivery), 'delivery_country': _get('country', delivery, default), 'delivery_county': _get('county', delivery), 'delivery_postcode': _get('postcode', delivery), 'finance_option': basket.finance_option, 'loan_deposit': basket.loan_deposit, 'newsletter': basket.newsletter, 'terms': basket.terms, 'special_req': basket.special_req, 'survey': basket.survey, 'signup': basket.signup != None, 'password': basket.signup.get('password') if basket.signup else None, 'password_confirm': basket.signup.get('password') if basket.signup else None, 'update_profile': basket.update_profile }) form.configure(request, basket) current_page = CurrentPage.DELIVERY_ADDRESS() if request.method == 'POST' and form.is_valid(): d = form.cleaned_data if 'email' in d: email = d.get('email') else: email = request.user.email # keep initial address information if we are not allowed to change the # billing address if not basket.can_edit_billing_address: for field in [ 'company', 'address1', 'address2', 'address3', 'city', 'country', 'county', 'postcode' ]: d[field] = basket.billing_address.get(field) # save billing address basket.set_billing_address(title=d.get('title'), first_name=d.get('first_name'), last_name=d.get('last_name'), email=email, telephone=d.get('telephone'), company=d.get('company'), address1=d.get('address1'), address2=d.get('address2'), address3=d.get('address3'), city=d.get('city'), country=d.get('country'), county=d.get('county'), postcode=d.get('postcode')) # get delivery method deliver_to = d.get('deliver_to', DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS) basket.set_click_and_collect( deliver_to == DeliveryAddressFrom.DELIVERY_COLLECTION or basket.is_collection_only()) basket.set_free_delivery_to(False) if deliver_to == DeliveryAddressFrom.FREE_DELIVERY_TO: location = basket.get_normalized_free_delivery_to_address() basket.set_delivery_address(name=d.get('delivery_free_name'), company=location.get('title'), address1=location.get('address1'), address2=location.get('address2'), address3=location.get('address3'), city=location.get('city'), country=location.get('country'), county=location.get('county'), postcode=location.get('postcode')) basket.set_free_delivery_to(True) elif deliver_to == DeliveryAddressFrom.DELIVERY_BILLING_ADDRESS: # deliver to my billing address basket.set_delivery_address( name='%s %s' % (d.get('first_name'), d.get('last_name')), company=d.get('company'), address1=d.get('address1'), address2=d.get('address2'), address3=d.get('address3'), city=d.get('city'), country=d.get('country'), county=d.get('county'), postcode=d.get('postcode')) elif deliver_to == DeliveryAddressFrom.DELIVERY_NEW_ADDRESS: # enter new delivery address basket.set_delivery_address(name=d.get('delivery_name'), company=d.get('delivery_company'), address1=d.get('delivery_address1'), address2=d.get('delivery_address2'), address3=d.get('delivery_address3'), city=d.get('delivery_city'), country=d.get('delivery_country'), county=d.get('delivery_county'), postcode=d.get('delivery_postcode')) # create a new record for the customer's profile if not request.user.is_anonymous(): n = DeliveryAddress.objects.filter( user=request.user, address1=d.get('delivery_address1'), address2=d.get('delivery_address2'), address3=d.get('delivery_address3'), city=d.get('delivery_city'), country=d.get('delivery_country'), county=d.get('delivery_county'), postcode=d.get('delivery_postcode')).count() if n == 0: address = DeliveryAddress() address.user = request.user address.name = d.get('delivery_name') address.company = d.get('delivery_company') address.address1 = d.get('delivery_address1') address.address2 = d.get('delivery_address2') address.address3 = d.get('delivery_address3') address.city = d.get('delivery_city') address.country = d.get('delivery_country') address.county = d.get('delivery_county') address.postcode = d.get('delivery_postcode') address.save() else: if not basket.is_click_and_collect(): # delivery to one of my delivery addresses taken from my profile delivery_address = DeliveryAddress.objects.get( user=request.user, pk=deliver_to) basket.set_delivery_address(name=delivery_address.name, company=delivery_address.company, address1=delivery_address.address1, address2=delivery_address.address2, address3=delivery_address.address3, city=delivery_address.city, country=delivery_address.country, county=delivery_address.county, postcode=delivery_address.postcode) is_loan_available = settings.SHOP_LOAN_ENABLED and 'finance_option' in d and 'loan_deposit' in d if is_loan_available and deliver_to == DeliveryAddressFrom.DELIVERY_NEW_ADDRESS: # deliver to my billing address as it is required by law if finance option is chosen if d.get('finance_option'): basket.set_delivery_address( name='%s %s' % (d.get('first_name'), d.get('last_name')), company=d.get('company'), address1=d.get('address1'), address2=d.get('address2'), address3=d.get('address3'), city=d.get('city'), country=d.get('country'), county=d.get('county'), postcode=d.get('postcode')) # loan application if is_loan_available: basket.set_finance_option(d.get('finance_option')) basket.set_loan_deposit(d.get('loan_deposit')) else: basket.set_finance_option(None) basket.set_loan_deposit(None) # newsletter if request.settings.mailchimp_enabled and 'newsletter' in d and d.get( 'newsletter'): basket.newsletter = True # terms and conditions if request.settings.has_terms and 'terms' in d and d.get('terms'): basket.terms = True # special requiremenets basket.special_req = d.get('special_req') # survey basket.survey = d.get('survey') if 'survey' in d else None # signup? if d.get('signup', False) == True: basket.set_signup(email=d.get('email'), first_name=d.get('first_name'), last_name=d.get('last_name'), password=d.get('password')) else: basket.clear_signup() # default delivery address? if 'update_profile' in d and d.get('update_profile'): basket.update_profile = True # next... next = next_checkout_step(request, basket, current_page) basket.save() return next # generate list of available delivery addresses from customer's profile if request.user.is_anonymous(): delivery_addresses = [] else: delivery_addresses = [{ 'id': i, 'iso': addr.country.iso } for i, addr in enumerate(request.user.delivery_addresses.all(), start=3)] return { 'basket': basket, 'form': form, 'delivery_addresses': to_json(delivery_addresses) }
def get_customer_model(self): """ Return the model for a shop customer. """ return get_customer_model()
def account_signup(self, request): email = request.session.get(settings.SIGNUP_EMAIL_SESSION_VAR, None) if email == '': raise Http404('Missing email address.') checkout = request.GET.get('checkout', False) == '1' form_class = self.get_account_signup_form() if request.method == 'POST': form = form_class(request.POST, initial={'checkout': checkout}) else: form = form_class(initial={ 'email': email, 'checkout': checkout }) form.configure(request) if request.method == 'POST': captcha = validate_captcha(request) if not captcha: messages.add_message(request, messages.ERROR, 'Please tick the checkbox at the bottom of the form to prevent SPAM.' ) if form.is_valid() and captcha: d = form.cleaned_data # create user account md5 = hashlib.md5() md5.update(d['email']) user = User.objects.create( username = md5.hexdigest()[:30], first_name = d['first_name'], last_name = d['last_name'], email = d['email'] ) # replace username with user id, set password and add user to list of customers user.username = unicode(user.id) user.set_password(d['password']) user.save() # create customer newsletter = 0 if request.settings.mailchimp_enabled: if d['newsletter']: person_name = (d['first_name'],d['last_name']) merge_vars = {'FNAME': " ".join(person_name)} ms = MailSnake(request.settings.mailchimp_api) try: ms.listSubscribe(id=request.settings.mailchimp_list_id, email_address=d['email'], merge_vars=merge_vars) except: pass newsletter = d['newsletter'] customer = get_customer_model().objects.create( user=user, first_name = d['first_name'], last_name = d['last_name'], email=d['email'], title=d['title'], address1='', city='', county='', postcode='', country=d['country'], telephone='', newsletter=newsletter ) # log customer in login_user_without_password(request, user) # go to dashboard or deliver page messages.success(request, 'Thank you for signing up with us.') if d['checkout']: response = HttpResponseRedirect(reverse('shop.order.delivery')) else: response = HttpResponseRedirect(reverse('shop.account.index')) response.set_cookie('cubaneShopLogin', '1') return response return { 'account_section': True, 'is_signup_page': True, 'form': form }
class CustomerView(ModelView): template_path = 'cubane/ishop/merchant/customers/' namespace = 'cubane.ishop.customers' model = get_customer_model() patterns = [ view_url(r'change-password/$', view='change_password', name='change_password'), ] listing_actions = [('[Change Password]', 'change_password', 'single')] shortcut_actions = [ 'change_password', ] def __init__(self, *args, **kwargs): if not settings.SHOP_CHANGE_CUSTOMER_PASSWORD_ENABLED: self.shortcut_actions = [] self.listing_actions = [] super(CustomerView, self).__init__(*args, **kwargs) def _get_objects(self, request): return self.model.objects.all() @view(require_POST) @view(permission_required('delete')) def delete(self, request, pk=None): """ Delete existing model instance with given primary key pk or (if no primary key is given in the url) attempt to delete multiple entities that are given by ids post argument. """ # determine list of pks pks = [] if pk: pks = [pk] else: pks = request.POST.getlist('pks[]', []) if len(pks) == 0: pk = request.POST.get('pk') if pk: pks = [pk] # delete instance(s)... if len(pks) == 1: instance = self.get_object_or_404(request, pks[0]) label = instance.__unicode__() if not label: label = '<no label>' instance.delete() message = self._get_success_message(label, 'deleted') else: instances = self._get_objects(request).filter(pk__in=pks) for instance in instances: instance.delete() message = '%d %s deleted successfully.' % ( len(instances), self.model._meta.verbose_name_plural) # response if self._is_json(request): return to_json_response({'success': True, 'message': message}) else: messages.add_message(request, messages.SUCCESS, message) return self._redirect(request, 'index') def change_password(self, request): # feature enabled? if not settings.SHOP_CHANGE_CUSTOMER_PASSWORD_ENABLED: raise Http404('Feature is not enabled.') customer_id = request.GET.get('pk') try: customer = self.model.objects.get(pk=customer_id) user = customer.user except self.model.DoesNotExist: raise Http404('Unknown customer account id %s.' % customer_id) if request.method == 'POST': form = CustomerChangePasswordForm(request.POST) else: form = CustomerChangePasswordForm() if request.method == 'POST' and form.is_valid(): user.set_password(form.cleaned_data['password']) user.save() messages.add_message( request, messages.SUCCESS, 'Password changed for <em>%s</em>.' % customer.email) return self._redirect(request, 'index') return {'customer': customer, 'form': form} @view(csrf_exempt) def export(self, request): return _export(request)
class DeliveryAddressFrom(BaseForm): ADDRESS_FIELD_NAMES = [ 'company', 'address1', 'address2', 'address3', 'city', 'country', 'county', 'postcode' ] _customer_information = SectionField(label='Customer Information') title = forms.ChoiceField(required=True, choices=get_customer_model().TITLE_CHOICES) first_name = forms.CharField(label='First Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) last_name = forms.CharField(label='Last Name', max_length=30, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) email = forms.EmailField(max_length=255, required=True, widget=EmailInput) telephone = forms.CharField(max_length=40, required=True, widget=PhoneInput) postcode_lookup = PostcodeLookupField(label='Find Address', address1='id_address1', address2='id_address2', address3='id_address3', address4=None, locality=None, city='id_city', county='id_county', postcode='id_postcode', custom_css='text') _billing_address = SectionField(label='Billing Address') company = forms.CharField(label='Company', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address1 = forms.CharField(label='Address 1', max_length=255, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address2 = forms.CharField(label='Address 2', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) address3 = forms.CharField(label='Address 3', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) city = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) country = forms.ModelChoiceField(required=True, empty_label=None, initial='GB', queryset=Country.objects.all()) county = forms.CharField(max_length=255, required=True, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) postcode = forms.CharField(max_length=10, required=True, widget=forms.TextInput(attrs={ 'size': '10', 'class': 'text' })) update_profile = forms.BooleanField( required=False, initial=True, help_text= 'Make this billing address my permanent address to be used for the next checkout.' ) delivery_postcode_lookup = PostcodeLookupField( label='Find Address', address1='id_delivery_address1', address2='id_delivery_address2', address3='id_delivery_address3', address4=None, locality=None, city='id_delivery_city', county='id_delivery_county', postcode='id_delivery_postcode', custom_css='text') _delivery_address = SectionField(label='Delivery Address') FREE_DELIVERY_TO = 'free_delivery_to' DELIVERY_BILLING_ADDRESS = 'billing_address' DELIVERY_NEW_ADDRESS = 'new_address' DELIVERY_COLLECTION = 'click_and_collect' DELIVERY_CHOICES = ((DELIVERY_COLLECTION, 'Click and Collect'), (DELIVERY_BILLING_ADDRESS, 'Deliver to my billing address'), (DELIVERY_NEW_ADDRESS, 'Enter new delivery address')) DELIVERY_CHOICES_RESTRICTED = ( (DELIVERY_COLLECTION, 'Click and Collect'), (DELIVERY_BILLING_ADDRESS, 'Deliver to my billing address'), ) deliver_to = forms.ChoiceField(required=True, choices=DELIVERY_CHOICES, widget=forms.RadioSelect()) delivery_free_name = forms.CharField(label='Name', max_length='255', required=False) delivery_name = forms.CharField(label='Name', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_company = forms.CharField(label='Company', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_address1 = forms.CharField(label='Address 1', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_address2 = forms.CharField(label='Address 2', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_address3 = forms.CharField(label='Address 3', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_city = forms.CharField(label='City', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_country = forms.ModelChoiceField(label='Country', required=False, empty_label=None, initial='GB', queryset=Country.objects.all()) delivery_county = forms.CharField(label='County', max_length=255, required=False, widget=forms.TextInput(attrs={ 'size': '40', 'class': 'text' })) delivery_postcode = forms.CharField(label='Postcode', max_length=10, required=False, widget=forms.TextInput(attrs={ 'size': '10', 'class': 'text' })) _discount = SectionField(label='Discount') signup = forms.BooleanField( required=False, initial=False, help_text='Save this information to make checkout quicker next time.') password = forms.CharField( label='Password', min_length=6, max_length=255, required=False, help_text='Your password must be at least 6 characters in length.', widget=forms.PasswordInput(render_value=True)) password_confirm = forms.CharField( label='Password (Confirm)', min_length=6, max_length=255, required=False, help_text='Confirm your new password.', widget=forms.PasswordInput(render_value=True)) newsletter = forms.BooleanField( label='Newsletter', required=False, initial=False, help_text='Yes, subscribe me to the newsletter.') delivery_code = forms.CharField(label='Delivery Code', required=False, max_length=32) special_req = forms.CharField( label='Special Requirements', required=False, max_length=500, widget=forms.Textarea(attrs={ 'cols': '40', 'rows': '4' }), help_text='For example: Special Delivery Requirements.') survey = forms.ChoiceField(required=False, choices=[], help_text='Where did you hear about us?') finance_option = forms.ModelChoiceField( label='Finance Option', queryset=None, required=False, help_text='Choose the finance option that best suits your requirements.' ) loan_deposit = forms.IntegerField(label='Deposit', required=False, widget=RangeInput(attrs={ 'step': '1', 'min': '10', 'max': '50' })) terms = forms.BooleanField(label='Accept Terms', required=True, initial=False) def configure(self, request, basket): self._request = request self._basket = basket fields_list = [ 'email', 'signup', 'password', 'password_confirm', 'survey' ] if request.settings.has_survey: self.fields['survey'].choices = [('', '-------')] + [ (o, o) for o in request.settings.get_survey_options() ] else: del self.fields['survey'] if not request.settings.mailchimp_enabled: del self.fields['newsletter'] # finance option self.fields[ 'finance_option'].queryset = basket.get_finance_options_queryset() # terms and condition if not request.settings.has_terms: del self.fields['terms'] else: self.fields['terms'].help_text = mark_safe( 'I have read and agree to the <a href="' + request.settings.get_terms() + '" target="_blank">terms and conditions</a>.') # collect additional delivery address options from customer's profile # (only available if we are allowed to edit the delivery address) if basket.can_edit_delivery_address and not request.user.is_anonymous( ): addresses = [(x.id, unicode(x)) for x in request.user.delivery_addresses.all()] self.fields['deliver_to'].choices += addresses if not request.user.is_anonymous(): # authenticated user with a valid profile do not need to fill out # all the information but we pre fill out the majority of the # fields... self.fields['first_name'].initial = request.user.first_name self.fields['last_name'].initial = request.user.last_name try: p = get_customer_model().objects.get(user=request.user) self.fields['title'].initial = p.title self.fields['address1'].initial = p.address1 self.fields['address2'].initial = p.address2 self.fields['address3'].initial = p.address3 self.fields['city'].initial = p.city self.fields['county'].initial = p.county self.fields['postcode'].initial = p.postcode self.fields['country'].initial = p.country self.fields['telephone'].initial = p.telephone if p.newsletter: if 'newsletter' in self.fields: del self.fields['newsletter'] if '_newsletter' in self.fields: del self.fields['_newsletter'] for field in fields_list: if field in self.fields: del self.fields[field] except get_customer_model().DoesNotExist: pass else: # guests need to fill out the entire form, copy only the email self.fields['email'].initial = request.session.get( settings.GUEST_USER_SESSION_VAR, '') del self.fields['update_profile'] # billing address changable? if not basket.can_edit_billing_address: for field in self.ADDRESS_FIELD_NAMES: del self.fields[field] # delivery address changeable? if not basket.can_edit_delivery_address: self.fields[ 'deliver_to'].choices = self.DELIVERY_CHOICES_RESTRICTED for field in self.ADDRESS_FIELD_NAMES: del self.fields['delivery_%s' % field] # free delivery to if basket.can_have_free_delivery_to(): self.fields['deliver_to'].choices = [ (DeliveryAddressFrom.FREE_DELIVERY_TO, 'Free delivery to %s' % basket.get_free_delivery_to()) ] + self.fields['deliver_to'].choices else: del self.fields['delivery_code'] # special requirements if not request.settings.special_requirements: del self.fields['special_req'] def clean_email(self): """ Make sure that the email is not taken if the user checked signup. """ signup = self.cleaned_data.get('signup', False) email = self.cleaned_data.get('email', None) if signup == True: if get_customer_model().objects.filter(email=email).count() > 0: raise forms.ValidationError( 'Email address already used. Please provide a different email address for signing up for a new account.' ) return email def clean_password(self): """ Password is required if signup is checked """ signup = self.cleaned_data.get('signup', False) password = self.cleaned_data.get('password', None) if signup == True: if not password: raise forms.ValidationError( 'Password is required in order to signup for a new account.' ) return password def clean_password_confirm(self): """ Password confirm is required and must match password if signup is checked. """ signup = self.cleaned_data.get('signup', False) password = self.cleaned_data.get('password', None) password_confirm = self.cleaned_data.get('password_confirm', None) if signup == True: if not password_confirm: raise forms.ValidationError( 'Password confirmation is required in order to signup for a new account.' ) if password != password_confirm: raise forms.ValidationError( 'Password confirmation is required to match password.') return password_confirm def clean_deliver_to(self): deliver_to = self.cleaned_data.get('deliver_to') if deliver_to: if self._basket.is_collection_only( ) and deliver_to != DeliveryAddressFrom.DELIVERY_COLLECTION: raise forms.ValidationError( 'At least one product cannot be delivered and must be collected from store. Please select Click and Collect.' ) return deliver_to def clean(self): d = super(DeliveryAddressFrom, self).clean() # deliver to deliver_to = d.get('deliver_to') if deliver_to: if deliver_to == DeliveryAddressFrom.DELIVERY_NEW_ADDRESS: fields = [ 'delivery_name', 'delivery_address1', 'delivery_city', 'delivery_county', 'delivery_country', 'delivery_postcode' ] for field in fields: if not d.get(field): self._errors[field] = self.error_class([ 'This field is required for the delivery address.' ]) # finance option is required if we ticked finance option loan = d.get('loan') finance_option = d.get('finance_option') if self._basket.can_have_free_delivery_to(): delivery_code = d.get('delivery_code') if deliver_to == DeliveryAddressFrom.FREE_DELIVERY_TO: if delivery_code != self._basket.get_free_delivery_to( ).delivery_code: self._errors['delivery_code'] = self.error_class([ 'Unfortunately we are unable to recognise your free delivery code. Please try again.' ]) if not d.get('delivery_free_name'): self._errors['delivery_free_name'] = self.error_class( ['This field is required for the free delivery.']) if loan and not finance_option: self.form_error('finance_option', 'This field is required.') if loan and not loan_deposit: self.form_error('loan_deposit', 'This field is required.') # clean address return clean_address(self, d) def get_address(self): """ Return the address information as provided from this form. """ d = self.cleaned_data return { 'title': d.get('title'), 'first_name': d.get('first_name'), 'last_name': d.get('last_name'), 'name': d.get('delivery_name') if d.get('delivery_name') else d.get('delivery_free_name'), 'address1': d.get('address1'), 'address2': d.get('address2'), 'address3': d.get('address3'), 'city': d.get('city'), 'county': d.get('county'), 'state': d.get('county') if d.get('country').iso == 'US' else '', 'postcode': d.get('postcode'), 'country': d.get('country'), 'country-iso': d.get('country').iso }