Remove address model and unnecessary apps

This commit is contained in:
Nathan Chapman 2023-07-14 22:59:03 -06:00
parent de329a5340
commit faf9b5b734
23 changed files with 1195 additions and 1449 deletions

View File

@ -2,7 +2,7 @@ from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .models import Address, User
from .models import User
from .forms import AccountCreateForm, AccountUpdateForm
class UserAdmin(UserAdmin):
@ -12,5 +12,4 @@ class UserAdmin(UserAdmin):
list_display = ['email', 'username',]
admin.site.register(Address)
admin.site.register(User, UserAdmin)

View File

@ -9,3 +9,4 @@ class AccountsConfig(AppConfig):
from .signals import (
user_saved
)

View File

@ -2,21 +2,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from allauth.account.forms import SignupForm
from captcha.fields import CaptchaField
from .models import Address, User
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = (
'first_name',
'last_name',
'street_address_1',
'street_address_2',
'city',
'state',
'postal_code',
)
from .models import User
class AccountCreateForm(UserCreationForm):
@ -32,23 +18,26 @@ class AccountUpdateForm(UserChangeForm):
'first_name',
'last_name',
'email',
'default_shipping_address',
'addresses',
'shipping_street_address_1',
'shipping_street_address_2',
'shipping_city',
'shipping_state',
'shipping_postal_code',
)
class CustomerUpdateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['default_shipping_address'].queryset = kwargs['instance'].addresses
class Meta:
model = User
fields = (
'first_name',
'last_name',
'email',
'default_shipping_address',
'shipping_street_address_1',
'shipping_street_address_2',
'shipping_city',
'shipping_state',
'shipping_postal_code',
)
@ -62,3 +51,4 @@ class UserSignupForm(SignupForm):
widget=forms.TextInput(attrs={'placeholder': 'Last name'})
)
captcha = CaptchaField()

View File

@ -0,0 +1,29 @@
# Generated by Django 4.1.6 on 2023-07-15 03:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0008_remove_order_billing_address_and_more'),
('accounts', '0004_transfer_address_data_to_user_model'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='addresses',
),
migrations.RemoveField(
model_name='user',
name='default_billing_address',
),
migrations.RemoveField(
model_name='user',
name='default_shipping_address',
),
migrations.DeleteModel(
name='Address',
),
]

View File

@ -5,75 +5,7 @@ from django.contrib.auth.models import AbstractUser
from localflavor.us.us_states import USPS_CHOICES
class Address(models.Model):
first_name = models.CharField(max_length=256, blank=True)
last_name = models.CharField(max_length=256, blank=True)
street_address_1 = models.CharField(max_length=256, blank=True)
street_address_2 = models.CharField(max_length=256, blank=True)
city = models.CharField(max_length=256, blank=True)
state = models.CharField(
max_length=2,
choices=USPS_CHOICES,
blank=True
)
postal_code = models.CharField(max_length=20, blank=True)
def as_stripe_dict(self):
return {
'name': f'{self.first_name} {self.last_name}',
'address': {
'line1': self.street_address_1,
'line2': self.street_address_2,
'city': self.city,
'state': self.state,
'postal_code': self.postal_code
}
}
def __str__(self):
return f"""
{self.first_name} {self.last_name}
{self.street_address_1}
{self.street_address_2}
{self.city}, {self.state}, {self.postal_code}
"""
def __iter__(self):
yield ('address_line_1', self.street_address_1),
yield ('address_line_2', self.street_address_2),
yield ('admin_area_2', self.city),
yield ('admin_area_1', self.state),
yield ('postal_code', self.postal_code),
yield ('country_code', 'US')
class Meta:
constraints = [
models.UniqueConstraint(
name='accounts_address_all_key',
fields=[
'first_name',
'last_name',
'street_address_1',
'street_address_2',
'city',
'state',
'postal_code'
],
violation_error_message='Duplicate: Address already exists.'
)
]
class User(AbstractUser):
addresses = models.ManyToManyField(
Address, blank=True, related_name="user_addresses"
)
default_shipping_address = models.ForeignKey(
Address, related_name="+", null=True, blank=True, on_delete=models.SET_NULL
)
default_billing_address = models.ForeignKey(
Address, related_name="+", null=True, blank=True, on_delete=models.SET_NULL
)
stripe_id = models.CharField(max_length=255, blank=True)
# Shipping address
@ -87,6 +19,16 @@ class User(AbstractUser):
)
shipping_postal_code = models.CharField(max_length=20, blank=True)
@property
def has_shipping_address(self):
if (self.shipping_street_address_1 != ''
and self.shipping_street_address_2 != ''
and self.shipping_city != ''
and self.shipping_state != ''
and self.shipping_postal_code != ''):
return True
return False
def get_or_create_stripe_id(self):
if not self.stripe_id:
response = stripe.Customer.create(

View File

@ -5,7 +5,7 @@ from django.dispatch import receiver
from django.db import models
from django.conf import settings
from .models import Address, User
from .models import User
logger = logging.getLogger(__name__)
stripe.api_key = settings.STRIPE_API_KEY
@ -16,3 +16,4 @@ def user_saved(sender, instance, created, **kwargs):
logger.info('User was saved')
if created or not instance.stripe_id:
instance.get_or_create_stripe_id()

View File

@ -1,26 +1,9 @@
from allauth.account.models import EmailAddress
from .models import Address, User
from .tasks import send_account_created_email
from .models import User
def get_or_create_customer(request, shipping_address):
address, a_created = Address.objects.get_or_create(
first_name=shipping_address['first_name'],
last_name=shipping_address['last_name'],
street_address_1=shipping_address['street_address_1'],
street_address_2=shipping_address['street_address_2'],
city=shipping_address['city'],
state=shipping_address['state'],
postal_code=shipping_address['postal_code']
)
if request.user.is_authenticated:
user = request.user
user.addresses.add(address)
if not user.default_shipping_address:
user.default_shipping_address = address
user.save()
else:
user, u_created = User.objects.get_or_create(
email=shipping_address['email'].lower(),
@ -29,27 +12,17 @@ def get_or_create_customer(request, shipping_address):
'is_staff': False,
'is_active': True,
'is_superuser': False,
'first_name': address.first_name,
'last_name': address.last_name,
'default_shipping_address': address,
'first_name': shipping_address['first_name'],
'last_name': shipping_address['last_name'],
'shipping_street_address_1': shipping_address['street_address_1'],
'shipping_street_address_2': shipping_address['street_address_2'],
'shipping_city': shipping_address['city'],
'shipping_state': shipping_address['state'],
'shipping_postal_code': shipping_address['postal_code']
}
)
if u_created:
password = User.objects.make_random_password()
user.set_password(password)
user.addresses.add(address)
user.make_random_password()
user.save()
EmailAddress.objects.create(
user=user, email=user.email, primary=True, verified=False
)
u = {
'full_name': user.get_full_name(),
'email': user.email,
'password': password
}
send_account_created_email.delay(u)
return user, address
return user

View File

@ -0,0 +1,33 @@
# Generated by Django 4.1.6 on 2023-07-15 03:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0005_transfer_address_data_to_order_and_subscription_models'),
]
operations = [
migrations.AddField(
model_name='order',
name='shipping_first_name',
field=models.CharField(blank=True, max_length=256),
),
migrations.AddField(
model_name='order',
name='shipping_last_name',
field=models.CharField(blank=True, max_length=256),
),
migrations.AddField(
model_name='subscription',
name='shipping_first_name',
field=models.CharField(blank=True, max_length=256),
),
migrations.AddField(
model_name='subscription',
name='shipping_last_name',
field=models.CharField(blank=True, max_length=256),
),
]

View File

@ -0,0 +1,35 @@
# Generated by Django 4.1.6 on 2023-07-15 03:20
from django.db import migrations
def copy_address_to_order(apps, schema_editor):
Order = apps.get_model("core", "Order")
for order in Order.objects.all():
if order.shipping_address:
order.shipping_first_name = order.shipping_address.first_name
order.shipping_last_name = order.shipping_address.last_name
order.save()
def copy_address_to_subscription(apps, schema_editor):
Subscription = apps.get_model("core", "Subscription")
for subscription in Subscription.objects.all():
if subscription.shipping_address:
subscription.shipping_first_name = subscription.shipping_address.first_name
subscription.shipping_last_name = subscription.shipping_address.last_name
subscription.save()
class Migration(migrations.Migration):
dependencies = [
('core', '0006_order_shipping_first_name_order_shipping_last_name_and_more'),
]
operations = [
migrations.RunPython(copy_address_to_order),
migrations.RunPython(copy_address_to_subscription)
]

View File

@ -0,0 +1,25 @@
# Generated by Django 4.1.6 on 2023-07-15 03:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0007_transfer_address_first_and_last_names_to_order_and_subscriptions'),
]
operations = [
migrations.RemoveField(
model_name='order',
name='billing_address',
),
migrations.RemoveField(
model_name='order',
name='shipping_address',
),
migrations.RemoveField(
model_name='subscription',
name='shipping_address',
),
]

View File

@ -18,7 +18,7 @@ from django.forms.models import model_to_dict
from django_measurement.models import MeasurementField
from localflavor.us.us_states import USPS_CHOICES
from accounts.models import User, Address
from accounts.models import User
from . import (
DiscountValueType,
@ -338,14 +338,9 @@ class Order(models.Model):
default=OrderStatus.UNFULFILLED,
choices=OrderStatus.CHOICES
)
billing_address = models.ForeignKey(
Address,
related_name="+",
editable=False,
null=True,
on_delete=models.SET_NULL
)
# Shipping address
shipping_first_name = models.CharField(max_length=256, blank=True)
shipping_last_name = models.CharField(max_length=256, blank=True)
shipping_street_address_1 = models.CharField(max_length=256, blank=True)
shipping_street_address_2 = models.CharField(max_length=256, blank=True)
shipping_city = models.CharField(max_length=256, blank=True)
@ -355,13 +350,6 @@ class Order(models.Model):
blank=True
)
shipping_postal_code = models.CharField(max_length=20, blank=True)
shipping_address = models.ForeignKey(
Address,
related_name="+",
editable=False,
null=True,
on_delete=models.SET_NULL
)
coupon = models.ForeignKey(
Coupon,
related_name='orders',
@ -556,6 +544,8 @@ class Subscription(models.Model):
null=True
)
# Shipping address
shipping_first_name = models.CharField(max_length=256, blank=True)
shipping_last_name = models.CharField(max_length=256, blank=True)
shipping_street_address_1 = models.CharField(max_length=256, blank=True)
shipping_street_address_2 = models.CharField(max_length=256, blank=True)
shipping_city = models.CharField(max_length=256, blank=True)
@ -565,13 +555,6 @@ class Subscription(models.Model):
blank=True
)
shipping_postal_code = models.CharField(max_length=20, blank=True)
shipping_address = models.ForeignKey(
Address,
related_name='+',
editable=False,
null=True,
on_delete=models.SET_NULL
)
items = ArrayField(
models.JSONField(blank=True, null=True),
default=list

View File

@ -53,13 +53,13 @@ def transaction_created(sender, instance, created, **kwargs):
'shipping_total': str(instance.order.shipping_total),
'total_amount': str(instance.order.total_amount),
'shipping_address': {
'first_name': instance.order.shipping_address.first_name,
'last_name': instance.order.shipping_address.last_name,
'street_address_1': instance.order.shipping_address.street_address_1,
'street_address_2': instance.order.shipping_address.street_address_2,
'city': instance.order.shipping_address.city,
'state': instance.order.shipping_address.state,
'postal_code': instance.order.shipping_address.postal_code
'first_name': instance.order.shipping_first_name,
'last_name': instance.order.shipping_last_name,
'street_address_1': instance.order.shipping_street_address_1,
'street_address_2': instance.order.shipping_street_address_2,
'city': instance.order.shipping_city,
'state': instance.order.shipping_state,
'postal_code': instance.order.shipping_postal_code
},
'line_items': list(
format_order_lines(instance.order.lines.all())

View File

@ -26,18 +26,11 @@
<dt>Default shipping address</dt>
<dd>
{% include 'dashboard/partials/_address.html' with address=customer.default_shipping_address %}
</dd>
<dt>All addresses</dt>
<dd>
{% for address in customer.addresses.all %}
{% include 'dashboard/partials/_address.html' with address=address %}
{% endfor %}
{% include 'dashboard/partials/_address.html' with address=customer %}
</dd>
</dl>
</section>
<section class="panel">
<header class="panel-header">
<h4>Orders</h4>

View File

@ -133,7 +133,7 @@
<div class="panel-section panel-shipping">
<div>
<strong>Shipping address</strong>
{% include 'dashboard/partials/_address.html' with address=order.shipping_address %}
{% include 'dashboard/partials/_address.html' with address=order %}
</div>
<table>
<thead>

View File

@ -17,7 +17,7 @@
</header>
<div class="panel-section">
<strong>Shipping address</strong>
{% include 'dashboard/partials/_address.html' with address=order.shipping_address %}
{% include 'dashboard/partials/_address.html' with address=order %}
</div>
<form method="POST">
{% csrf_token %}

View File

@ -1,9 +1,7 @@
<address>
{{address.first_name}}
{{address.last_name}}<br>
{{address.street_address_1}}<br>
{% if address.street_address_2 %}
{{address.street_address_2}}<br>
{{address.shipping_street_address_1}}<br>
{% if address.shipping_street_address_2 %}
{{address.shipping_street_address_2}}<br>
{% endif %}
{{address.city}}, {{address.state}}, {{address.postal_code}}
{{address.shipping_city}}, {{address.shipping_state}}, {{address.shipping_postal_code}}
</address>

View File

@ -31,7 +31,6 @@ from django.db.models.functions import Coalesce
from accounts.models import User
from accounts.utils import get_or_create_customer
from accounts.forms import AddressForm
from core.models import (
ProductCategory,
Product,
@ -259,8 +258,6 @@ class OrderDetailView(LoginRequiredMixin, DetailView):
self.kwargs.get(self.pk_url_kwarg)
).select_related(
'customer',
'billing_address',
'shipping_address'
).prefetch_related(
'lines__variant__product__productphoto_set'
)
@ -717,9 +714,11 @@ class CustomerUpdateView(
'first_name',
'last_name',
'email',
'is_staff',
'addresses',
'default_shipping_address'
'shipping_street_address_1',
'shipping_street_address_2',
'shipping_city',
'shipping_state',
'shipping_postal_code',
)
def get_success_url(self):

2109
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -72,10 +72,7 @@ INSTALLED_APPS = [
# 3rd Party
'django_filters',
'storages',
'localflavor',
'django_celery_beat',
'django_celery_results',
'anymail',
'compressor',
'allauth',

View File

@ -11,12 +11,9 @@ django = "^4.1.5"
celery = {extras = ["redis"], version = "^5.2.7"}
django-allauth = "^0.52.0"
django-anymail = {extras = ["mailgun"], version = "^9.0"}
django-celery-beat = "^2.4.0"
django-celery-results = "^2.4.0"
django-compressor = "^4.1"
django-filter = "^22.1"
django-measurement = "^3.2.4"
django-storages = "^1.13.2"
django-templated-email = "^3.0.1"
paypal-checkout-serversdk = "^1.0.1"
pillow = "^9.4.0"

View File

@ -18,45 +18,17 @@
<a href="{% url 'account_email' %}">Manage</a>
</div>
<div>
<strong>Default shipping address</strong>
{% with shipping_address=customer.default_shipping_address %}
<address>
{{shipping_address.first_name}}
{{shipping_address.last_name}}<br>
{{shipping_address.street_address_1}}<br>
{% if shipping_address.street_address_2 %}
{{shipping_address.street_address_2}}<br>
{% endif %}
{{shipping_address.city}}, {{shipping_address.state}}, {{shipping_address.postal_code}}
</address>
{% endwith %}
<strong>Shipping address</strong>
<address>
{{customer.shipping_street_address_1}}<br>
{% if shipping_street_address_2 %}
{{customer.shipping_street_address_2}}<br>
{% endif %}
{{customer.shipping_city}}, {{customer.shipping_state}}, {{customer.shipping_postal_code}}
</address>
</div>
</div>
</section>
<section>
<h4>Your addresses</h4>
<p>
<a href="{% url 'storefront:customer-address-create' user.pk %}" class="btn">+ New address</a>
</p>
<div>
{% for address in customer.addresses.all %}
<p>
<address>
{{address.first_name}}
{{address.last_name}}<br>
{{address.street_address_1}}<br>
{% if address.street_address_2 %}
{{address.street_address_2}}<br>
{% endif %}
{{address.city}}, {{address.state}}, {{address.postal_code}}
</address>
<a href="{% url 'storefront:address-update' customer.pk address.pk %}">Edit</a>
</p>
{% empty %}
<p>No other addresses.</p>
{% endfor %}
</div>
</section>
{% if customer.subscriptions.count > 0 %}
<section>
<h3>Your subscriptions</h3>

View File

@ -89,26 +89,11 @@ urlpatterns = [
views.CustomerUpdateView.as_view(),
name='customer-update',
),
# path(
# 'delete/',
# views.CustomerDeleteView.as_view(),
# name='customer-delete'
# ),
path(
'orders/<int:order_pk>/',
views.OrderDetailView.as_view(),
name='order-detail',
),
path(
'addresses/new/',
views.CustomerAddressCreateView.as_view(),
name='customer-address-create',
),
path(
'addresses/<int:address_pk>/update/',
views.CustomerAddressUpdateView.as_view(),
name='address-update',
)
])),
path(

View File

@ -34,11 +34,9 @@ from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
from moneyed import Money, USD
from accounts.models import User, Address
from accounts.models import User
from accounts.utils import get_or_create_customer
from accounts.forms import (
AddressForm as AccountAddressForm, CustomerUpdateForm
)
from accounts.forms import CustomerUpdateForm
from core.models import (
ProductCategory, Product, ProductVariant, ProductOption,
Order, Transaction, OrderLine, Coupon, ShippingRate,
@ -252,16 +250,15 @@ class CheckoutAddressView(FormView):
def get_initial(self):
user = self.request.user
initial = None
if user.is_authenticated and user.default_shipping_address:
address = user.default_shipping_address
if user.is_authenticated:
initial = {
'full_name': address.first_name + ' ' + address.last_name,
'full_name': user.first_name + ' ' + user.last_name,
'email': user.email,
'street_address_1': address.street_address_1,
'street_address_2': address.street_address_2,
'city': address.city,
'state': address.state,
'postal_code': address.postal_code
'street_address_1': user.shipping_street_address_1,
'street_address_2': user.shipping_street_address_2,
'city': user.shipping_city,
'state': user.shipping_state,
'postal_code': user.shipping_postal_code
}
elif self.request.session.get('shipping_address'):
address = self.request.session.get('shipping_address')
@ -413,7 +410,14 @@ class OrderCreateView(CreateView):
shipping_container = cart.get_shipping_container()
form.instance.shipping_total = cart.get_shipping_price(shipping_container)
shipping_address = self.request.session.get('shipping_address')
form.instance.customer, form.instance.shipping_address = get_or_create_customer(self.request, shipping_address)
form.instance.shipping_first_name = shipping_address['first_name']
form.instance.shipping_last_name = shipping_address['last_name']
form.instance.shipping_street_address_1 = shipping_address['street_address_1']
form.instance.shipping_street_address_2 = shipping_address['street_address_2']
form.instance.shipping_city = shipping_address['city']
form.instance.shipping_state = shipping_address['state']
form.instance.shipping_postal_code = shipping_address['postal_code']
form.instance.customer = get_or_create_customer(self.request, shipping_address)
form.instance.status = OrderStatus.DRAFT
self.object = form.save()
bulk_list = cart.build_bulk_list(self.object)
@ -443,7 +447,14 @@ class FreeOrderCreateView(CreateView):
shipping_container = cart.get_shipping_container()
form.instance.shipping_total = cart.get_shipping_price(shipping_container)
shipping_address = self.request.session.get('shipping_address')
form.instance.customer, form.instance.shipping_address = get_or_create_customer(self.request, shipping_address)
form.instance.shipping_first_name = shipping_address['first_name']
form.instance.shipping_last_name = shipping_address['last_name']
form.instance.shipping_street_address_1 = shipping_address['street_address_1']
form.instance.shipping_street_address_2 = shipping_address['street_address_2']
form.instance.shipping_city = shipping_address['city']
form.instance.shipping_state = shipping_address['state']
form.instance.shipping_postal_code = shipping_address['postal_code']
form.instance.customer = get_or_create_customer(self.request, shipping_address)
form.instance.status = OrderStatus.UNFULFILLED
self.object = form.save()
bulk_list = cart.build_bulk_list(self.object)
@ -562,58 +573,6 @@ class OrderDetailView(UserPassesTestMixin, LoginRequiredMixin, DetailView):
return context
class CustomerAddressCreateView(
UserPassesTestMixin, LoginRequiredMixin, CreateView
):
model = Address
template_name = 'storefront/address_create_form.html'
form_class = AccountAddressForm
permission_denied_message = 'Not authorized.'
raise_exception = True
def test_func(self):
return self.request.user.pk == self.kwargs['pk']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['customer'] = User.objects.get(pk=self.kwargs['pk'])
return context
def form_valid(self, form):
customer = User.objects.get(pk=self.kwargs['pk'])
self.object = form.save()
customer.addresses.add(self.object)
return super().form_valid(form)
def get_success_url(self):
return reverse(
'storefront:customer-detail', kwargs={'pk': self.kwargs['pk']}
)
class CustomerAddressUpdateView(
UserPassesTestMixin, LoginRequiredMixin, UpdateView
):
model = Address
pk_url_kwarg = 'address_pk'
template_name = 'storefront/address_form.html'
form_class = AccountAddressForm
permission_denied_message = 'Not authorized.'
raise_exception = True
def test_func(self):
return self.request.user.pk == self.kwargs['pk']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['customer'] = User.objects.get(pk=self.kwargs['pk'])
return context
def get_success_url(self):
return reverse('storefront:customer-detail', kwargs={'pk': self.kwargs['pk']})
class AboutView(TemplateView):
template_name = 'storefront/about.html'
@ -754,7 +713,7 @@ class SubscriptionCreateView(SuccessMessageMixin, CreateView):
).get('recurring')
shipping_cost = get_shipping_cost(
self.object.total_weight,
self.object.shipping_address.postal_code
self.object.shipping_postal_code
) * 100
line_items.append({
'price_data': {
@ -789,7 +748,16 @@ class SubscriptionCreateView(SuccessMessageMixin, CreateView):
def form_valid(self, form):
shipping_address = self.request.session.get('shipping_address')
subscription = self.request.session.get('subscription')
form.instance.customer, form.instance.shipping_address = get_or_create_customer(self.request, shipping_address)
form.instance.shipping_first_name = shipping_address['first_name']
form.instance.shipping_last_name = shipping_address['last_name']
form.instance.shipping_street_address_1 = shipping_address['street_address_1']
form.instance.shipping_street_address_2 = shipping_address['street_address_2']
form.instance.shipping_city = shipping_address['city']
form.instance.shipping_state = shipping_address['state']
form.instance.shipping_postal_code = shipping_address['postal_code']
form.instance.customer = get_or_create_customer(
self.request, shipping_address
)
weight, unit = subscription['metadata']['total_weight'].split(':')
form.instance.total_weight = guess(
float(weight), unit, measures=[Weight]
@ -855,3 +823,4 @@ def stripe_webhook(request):
subscription.create_order(event.data.object)
return JsonResponse({'status': 'success'})