Source code for shuup.core.utils.forms
# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from collections import OrderedDict
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.tokens import default_token_generator
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from shuup.core.models import Contact, ImmutableAddress, MutableAddress
from shuup.core.shop_provider import get_shop
from shuup.core.utils.users import send_user_reset_password_email
from shuup.utils.iterables import first
[docs]class MutableAddressForm(forms.ModelForm):
[docs] class Meta:
model = MutableAddress
fields = (
"name",
"name_ext",
"phone",
"email",
"street",
"street2",
"postal_code",
"city",
"region",
"region_code",
"country",
)
labels = {"region_code": _("Region")}
def __init__(self, **kwargs):
super(MutableAddressForm, self).__init__(**kwargs)
if not kwargs.get("instance"):
# Set default country
self.fields["country"].initial = settings.SHUUP_ADDRESS_HOME_COUNTRY
field_properties = settings.SHUUP_ADDRESS_FIELD_PROPERTIES
for field, properties in field_properties.items():
for prop in properties:
setattr(self.fields[field], prop, properties[prop])
[docs] def save(self, commit=True):
if self.instance.pk:
if isinstance(self.instance, ImmutableAddress) or _is_assigned_multiple_times(self.instance):
self.instance.pk = None # Force resave
return super(MutableAddressForm, self).save(commit)
def _is_assigned_multiple_times(address):
contacts_assigned_to_count = Contact.objects.filter(
Q(default_billing_address_id=address.id) | Q(default_shipping_address_id=address.id)
).count()
if contacts_assigned_to_count != 1:
return bool(contacts_assigned_to_count)
contact_assigned_to = Contact.objects.filter(
Q(default_billing_address_id=address.id) | Q(default_shipping_address_id=address.id)
).first()
return bool(contact_assigned_to.default_billing_address_id == contact_assigned_to.default_shipping_address_id)
[docs]class FormInfoMap(OrderedDict):
def __init__(self, form_classes):
form_infos = (FormInfo(formcls) for formcls in form_classes)
super(FormInfoMap, self).__init__((form_info.choice_value, form_info) for form_info in form_infos)
[docs] def get_by_object(self, obj):
return first(form_info for form_info in self.values() if isinstance(obj, form_info.model))
[docs]class FormInfo(object):
def __init__(self, form_class):
self.form_class = form_class
self.model = form_class._meta.model
model_meta = self.model._meta
self.choice_value = model_meta.app_label + "." + model_meta.model_name
self.choice_text = model_meta.verbose_name.capitalize()
[docs]class RecoverPasswordForm(forms.Form):
username = forms.CharField(label=_("Username"), max_length=254, required=False)
email = forms.EmailField(label=_("Email"), max_length=254, required=False)
token_generator = default_token_generator
subject_template_name = "shuup/user/recover_password_mail_subject.jinja"
email_template_name = "shuup/user/recover_password_mail_content.jinja"
from_email = None
recover_password_confirm_view_url_name = "shuup:recover_password_confirm"
[docs] def clean(self):
data = self.cleaned_data
username = data.get("username")
email = data.get("email")
if username and email:
msg = _("Please provide either username or email, not both.")
self.add_error("username", msg)
self.add_error("email", msg)
if not (username or email):
msg = _("Please provide either username or email.")
self.add_error("username", msg)
self.add_error("email", msg)
return data
[docs] def save(self, request):
self.request = request
user_model = get_user_model()
username = self.cleaned_data["username"]
email = self.cleaned_data["email"]
username_filter = {"{0}__iexact".format(user_model.USERNAME_FIELD): username}
active_users = user_model.objects.filter(Q(**username_filter) | Q(email__iexact=email), Q(is_active=True))
for user in active_users:
self.process_user(user, request)
[docs] def process_user(self, user_to_recover, request):
if (
not user_to_recover.has_usable_password()
or not hasattr(user_to_recover, "email")
or not user_to_recover.email
):
return False
send_user_reset_password_email(
user=user_to_recover,
shop=get_shop(request),
reset_domain_url=request.build_absolute_uri("/"),
reset_url_name=self.recover_password_confirm_view_url_name,
token_generator=self.token_generator,
subject_template_name=self.subject_template_name,
email_template_name=self.email_template_name,
from_email=self.from_email,
)
return True