Browse Source

Added views to checkout.

You can now go through the entire checkout process although
the delivery method and payment options are simple redirects.
The order doesn't actually get placed either.  That's next on
the to-do list.
master
David Winterbottom 15 years ago
parent
commit
66e2edc162

+ 0
- 50
examples/defaultshop/selenium/save-delivery-address View File

@@ -51,56 +51,6 @@
51 51
 	<td>//input[@value='Save delivery address']</td>
52 52
 	<td></td>
53 53
 </tr>
54
-<tr>
55
-	<td>click</td>
56
-	<td>//div[@id='frame-140490395410768']/pre</td>
57
-	<td></td>
58
-</tr>
59
-<tr>
60
-	<td>click</td>
61
-	<td>//div[@id='frame-35413392']/pre[1]/img[2]</td>
62
-	<td></td>
63
-</tr>
64
-<tr>
65
-	<td>type</td>
66
-	<td>//input[@type='text']</td>
67
-	<td>dump()</td>
68
-</tr>
69
-<tr>
70
-	<td>type</td>
71
-	<td>//input[@type='text']</td>
72
-	<td>dump(addr)</td>
73
-</tr>
74
-<tr>
75
-	<td>clickAndWait</td>
76
-	<td>link=buy something</td>
77
-	<td></td>
78
-</tr>
79
-<tr>
80
-	<td>clickAndWait</td>
81
-	<td>link=Tetley's Fleece</td>
82
-	<td></td>
83
-</tr>
84
-<tr>
85
-	<td>select</td>
86
-	<td>id_product_id</td>
87
-	<td>label=Tetley's Fleece (CanBePersonalised: N, Gender: L, Size: 18) - £8.50</td>
88
-</tr>
89
-<tr>
90
-	<td>type</td>
91
-	<td>id_quantity</td>
92
-	<td>10</td>
93
-</tr>
94
-<tr>
95
-	<td>clickAndWait</td>
96
-	<td>//input[@value='Add to basket']</td>
97
-	<td></td>
98
-</tr>
99
-<tr>
100
-	<td>clickAndWait</td>
101
-	<td>link=Checkout</td>
102
-	<td></td>
103
-</tr>
104 54
 
105 55
 </tbody></table>
106 56
 </body>

+ 8
- 0
oscar/address/abstract_models.py View File

@@ -38,6 +38,14 @@ class AbstractAddress(models.Model):
38 38
     class Meta:
39 39
         abstract = True
40 40
         
41
+    def active_address_fields(self):
42
+        """
43
+        Returns the non-empty components of the adddress, but merging the
44
+        title, first_name and last_name into a single line.
45
+        """
46
+        return filter(lambda x: x, [self.get_salutation(), self.line1, self.line2, self.line3,
47
+                                    self.line4, self.postcode, self.country])
48
+        
41 49
     def get_salutation(self):
42 50
         """
43 51
         Returns the salutation

+ 2
- 0
oscar/checkout/forms.py View File

@@ -6,5 +6,7 @@ order_models = import_module('order.models', ['DeliveryAddress'])
6 6
 
7 7
 
8 8
 class DeliveryAddressForm(ModelForm):
9
+    
9 10
     class Meta:
10 11
         model = order_models.DeliveryAddress
12
+        exclude = ('user',)

+ 61
- 1
oscar/checkout/templates/checkout/preview.html View File

@@ -7,7 +7,67 @@
7 7
 
8 8
 {% block content %}
9 9
 
10
-Preview here
10
+<h3>Order contents</h3>
11
+<table>
12
+    <tr>
13
+        <th>Product</th>
14
+        <th>Availability</th>
15
+        <th>Quantity</th>
16
+        <th>Unit price excl tax</th>
17
+        <th>Unit price tax</th>
18
+        <th>Line price excl tax</th>
19
+        <th>Line price incl tax</th>
20
+    </tr>
21
+    {% for line in basket.lines.all %}
22
+    <tr>
23
+        <td><a href="{{ line.product.get_absolute_url }}">{{ line.description }}</a></td>
24
+        <td>{{ line.product.stockrecord.availability }}</td>
25
+        <td>{{ line.quantity }}</td>
26
+        <td>{{ line.unit_price_excl_tax|floatformat:2 }}</td>
27
+        <td>{{ line.unit_tax|floatformat:2 }}</td>
28
+        <td>{{ line.line_price_excl_tax|floatformat:2 }}</td>
29
+        <td>{{ line.line_price_incl_tax|floatformat:2 }}</td>
30
+    </tr>
31
+    {% endfor %}
32
+    <tr>
33
+        <td colspan="5">Total</td>
34
+        <td>{{ basket.total_excl_tax|floatformat:2 }}</td>
35
+        <td>{{ basket.total_incl_tax|floatformat:2 }}</td>
36
+    </tr>
37
+</table>
38
+
39
+<h3>Delivery</h3>
40
+<table>
41
+    <tr>
42
+        <th>Address</th>
43
+        <td>
44
+            {% for field in delivery_addr.active_address_fields %}
45
+            {{ field }}<br/>
46
+            {% endfor %}
47
+        </td>
48
+    </tr>
49
+    {% if delivery_addr.phone_number %}
50
+    <tr>
51
+        <th>Concact number</th>
52
+        <td>delivery_addr.phone_number</td>
53
+    </tr>
54
+    {% endif %}
55
+    {% if delivery_addr.notes %}
56
+    <tr>
57
+        <th>Delivery notes</th>
58
+        <td>delivery_addr.notes</td>
59
+    </tr>
60
+    {% endif %} 
61
+</table>
62
+
63
+<h3>Order total</h3>
64
+&pound;{{ order_total }}
65
+
66
+<form method="post" action="{% url oscar-checkout-submit %}" />
67
+    {% csrf_token %}
68
+    <input type="submit" value="Place order!" />
69
+</form>
70
+
11 71
 
12 72
 {% endblock content %}
13 73
 

+ 15
- 0
oscar/checkout/templates/checkout/thank_you.html View File

@@ -0,0 +1,15 @@
1
+{% extends "layout.html" %}
2
+
3
+{% block header %}
4
+<h2>Checkout / Thank you</h2>
5
+{% endblock header %}
6
+
7
+
8
+{% block content %}
9
+
10
+<h3>Thank you </h3>
11
+<p>Your order has been placed</p>
12
+
13
+
14
+{% endblock content %}
15
+

+ 2
- 0
oscar/checkout/urls.py View File

@@ -6,5 +6,7 @@ urlpatterns = patterns('oscar.checkout.views',
6 6
     url(r'delivery_method/$', 'delivery_method', name='oscar-checkout-delivery-method'),
7 7
     url(r'payment/$', 'payment', name='oscar-checkout-payment'),
8 8
     url(r'preview/$', 'preview', name='oscar-checkout-preview'),
9
+    url(r'submit/$', 'submit', name='oscar-checkout-submit'),
10
+    url(r'thank_you/$', 'thank_you', name='oscar-checkout-thank-you'),
9 11
 )
10 12
 

+ 51
- 2
oscar/checkout/views.py View File

@@ -7,8 +7,25 @@ from django.forms import ModelForm
7 7
 
8 8
 from oscar.services import import_module
9 9
 
10
-# Using dynamic app loading
10
+basket_factory = import_module('basket.factory', ['get_or_create_open_basket', 'get_open_basket', 
11
+                                                  'get_or_create_saved_basket', 'get_saved_basket'])
11 12
 checkout_forms = import_module('checkout.forms', ['DeliveryAddressForm'])
13
+order_models = import_module('order.models', ['DeliveryAddress'])
14
+
15
+class OrderTotalCalculator(object):
16
+    
17
+    def __init__(self, request):
18
+        # We store a reference to the request as the total may 
19
+        # depend on the user or the other checkout data in the session.
20
+        # Further, it is very likely that it will as delivery method
21
+        # always changes the order total.
22
+        self.request = request
23
+    
24
+    def order_total(self, basket):
25
+        # Default to returning the total including tax - use
26
+        # the request.user object if you want to not charge tax
27
+        # to particular customers.
28
+        return basket.total_incl_tax
12 29
 
13 30
 
14 31
 def index(request):
@@ -35,12 +52,44 @@ def delivery_address(request):
35 52
     
36 53
     
37 54
 def delivery_method(request):
55
+    """
56
+    Delivery methods are domain-specific and so need implementing in a 
57
+    subclass of this class.
58
+    """
38 59
     return HttpResponseRedirect(reverse('oscar-checkout-payment'))
39 60
 
40 61
 
41 62
 def payment(request):
63
+    """
64
+    Payment methods are domain-specific and so need implementing in a s
65
+    subclass of this class.
66
+    """
42 67
     return HttpResponseRedirect(reverse('oscar-checkout-preview'))
43 68
 
44 69
 
45 70
 def preview(request):
46
-    return render(request, 'checkout/preview.html', locals())
71
+    """
72
+    Show a preview of the order
73
+    """
74
+    basket = basket_factory.get_open_basket(request)
75
+    
76
+    # Load address data into a blank address model
77
+    addr_data = request.session.get('delivery_address')
78
+    delivery_addr = order_models.DeliveryAddress(**addr_data)
79
+    
80
+    # Calculate order total
81
+    calc = OrderTotalCalculator(request)
82
+    order_total = calc.order_total(basket)
83
+    
84
+    return render(request, 'checkout/preview.html', locals())
85
+
86
+
87
+def submit(request):
88
+    """
89
+    Do several things then redirect to the thank-you page
90
+    """
91
+    return HttpResponseRedirect(reverse('oscar-checkout-thank-you'))
92
+
93
+
94
+def thank_you(request):
95
+    return render(request, 'checkout/thank_you.html', locals())

+ 1
- 0
oscar/product/views.py View File

@@ -70,4 +70,5 @@ class ProductListView(ListView):
70 70
             context['summary'] = 'All products'
71 71
         else:
72 72
             context['summary'] = "Products matching '%s'" % q
73
+            context['search_term'] = q
73 74
         return context

+ 5
- 0
oscar/templates/layout.html View File

@@ -4,6 +4,11 @@
4 4
     <div id="container">
5 5
         <div id="header">
6 6
             <h1>Oscar // Flexible e-commerce for Django</h1>
7
+            <form method="get" action="{% url oscar-products %}">
8
+                <label id="search_input">Search all products:</label>
9
+                <input type="text" name="q" id="search_input" value="{{ search_term }}"/>
10
+                <input type="submit" value="Go!" /> 
11
+            </form>
7 12
             {% block header %}
8 13
             {% endblock %}
9 14
         </div>

Loading…
Cancel
Save