Просмотр исходного кода

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 лет назад
Родитель
Сommit
66e2edc162

+ 0
- 50
examples/defaultshop/selenium/save-delivery-address Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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 Просмотреть файл

@@ -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>

Загрузка…
Отмена
Сохранить