Repository: saleor/saleor

Issue:
Set address as default if no default selected
After checkout if the user does not have a default billing or shipping address (or her address book is empty) we should mark the addresses she used to checkout as defaults for billing and/or shipping according to checkout choices.



Discussion:

Resolving patch:
diff --git a/saleor/checkout/__init__.py b/saleor/checkout/__init__.py
--- a/saleor/checkout/__init__.py
+++ b/saleor/checkout/__init__.py
@@ -110,10 +110,11 @@ def __iter__(self):
 
     def create_order(self):
         order = Order()
+        if self.request.user.is_authenticated():
+            order.user = self.request.user
         for step in self.steps:
             step.add_to_order(order)
         if self.request.user.is_authenticated():
-            order.user = self.request.user
             order.anonymous_user_email = ''
         order.tracking_client_id = analytics.get_client_id(self.request)
         order.save()
diff --git a/saleor/checkout/steps.py b/saleor/checkout/steps.py
--- a/saleor/checkout/steps.py
+++ b/saleor/checkout/steps.py
@@ -13,7 +13,7 @@
 from ..core.utils import BaseStep
 from ..order.models import DigitalDeliveryGroup, ShippedDeliveryGroup
 from ..userprofile.forms import AddressForm
-from ..userprofile.models import Address
+from ..userprofile.models import Address, User
 
 
 class BaseCheckoutStep(BaseStep):
@@ -131,6 +131,8 @@ def save(self):
 
     def add_to_order(self, order):
         self.address.save()
+        if order.user:
+            User.objects.store_address(order.user, self.address, billing=True)
         order.anonymous_user_email = self.anonymous_user_email
         order.billing_address = self.address
         order.save()
@@ -189,6 +191,8 @@ def forms_are_valid(self):
 
     def add_to_order(self, order):
         self.address.save()
+        if order.user:
+            User.objects.store_address(order.user, self.address, shipping=True)
         delivery_method = self.group['delivery_method']
         group = ShippedDeliveryGroup.objects.create(
             order=order, address=self.address,
diff --git a/saleor/userprofile/models.py b/saleor/userprofile/models.py
--- a/saleor/userprofile/models.py
+++ b/saleor/userprofile/models.py
@@ -5,6 +5,7 @@
                                          is_password_usable)
 from django.contrib.auth.models import BaseUserManager
 from django.db import models
+from django.forms.models import model_to_dict
 from django.utils import timezone
 from django.utils.safestring import mark_safe
 from django.utils.translation import pgettext_lazy
@@ -13,6 +14,22 @@
 from ..core.countries import COUNTRY_CHOICES
 
 
+class AddressBookManager(models.Manager):
+
+    def store_address(self, user, address):
+        data = model_to_dict(address, exclude=['id'])
+        query = dict(('address__%s' % (key,), value)
+                     for key, value in data.items())
+        candidates = self.get_queryset().filter(user=user, **query)
+        candidates = candidates.select_for_update()
+        try:
+            entry = candidates[0]
+        except IndexError:
+            address = Address.objects.create(**data)
+            entry = AddressBook.objects.create(user=user, address=address)
+        return entry
+
+
 class AddressBook(models.Model):
 
     user = models.ForeignKey('User', related_name='address_book')
@@ -25,6 +42,8 @@ class AddressBook(models.Model):
             'Address book entry',
             'A short, descriptive name for this address'))
 
+    objects = AddressBookManager()
+
     class Meta:
         unique_together = ('user', 'alias')
 
@@ -115,6 +134,18 @@ def create_user(self, email, password=None, is_staff=False,
     def create_superuser(self, email, password=None, **extra_fields):
         return self.create_user(email, password, is_staff=True, **extra_fields)
 
+    def store_address(self, user, address, billing=False, shipping=False):
+        entry = AddressBook.objects.store_address(user, address)
+        changed = False
+        if billing and not user.default_billing_address_id:
+            user.default_billing_address = entry
+            changed = True
+        if shipping and not user.default_shipping_address_id:
+            user.default_shipping_address = entry
+            changed = True
+        if changed:
+            user.save()
+
 
 class User(models.Model):
     email = models.EmailField(unique=True)


Test patch: