浏览代码

Merge pull request #2825 from SrdjanCosicPrica/Enh-Track-order-status-change

Enhancement #2737 Track order status changes
master
Samir Shah 7 年前
父节点
当前提交
ad0d81dbbc
没有帐户链接到提交者的电子邮件

+ 1
- 1
src/oscar/apps/dashboard/orders/views.py 查看文件

@@ -50,7 +50,7 @@ def queryset_orders_for_user(user):
50 50
         'billing_address', 'billing_address__country',
51 51
         'shipping_address', 'shipping_address__country',
52 52
         'user'
53
-    ).prefetch_related('lines')
53
+    ).prefetch_related('lines', 'status_changes')
54 54
     if user.is_staff:
55 55
         return queryset
56 56
     else:

+ 30
- 0
src/oscar/apps/order/abstract_models.py 查看文件

@@ -149,8 +149,14 @@ class AbstractOrder(models.Model):
149 149
                                   new_status=new_status,
150 150
                                   )
151 151
 
152
+        self._create_order_status_change(old_status, new_status)
153
+
152 154
     set_status.alters_data = True
153 155
 
156
+    def _create_order_status_change(self, old_status, new_status):
157
+        # Not setting the status on the order as that should be handled before
158
+        self.status_changes.create(old_status=old_status, new_status=new_status)
159
+
154 160
     @property
155 161
     def is_anonymous(self):
156 162
         # It's possible for an order to be placed by a customer who then
@@ -430,6 +436,30 @@ class AbstractOrderNote(models.Model):
430 436
         return delta.seconds < self.editable_lifetime
431 437
 
432 438
 
439
+class AbstractOrderStatusChange(models.Model):
440
+    order = models.ForeignKey(
441
+        'order.Order',
442
+        on_delete=models.CASCADE,
443
+        related_name='status_changes',
444
+        verbose_name=_('Order Status Changes')
445
+    )
446
+    old_status = models.CharField(_('Old Status'), max_length=100, blank=True)
447
+    new_status = models.CharField(_('New Status'), max_length=100, blank=True)
448
+    date_created = models.DateTimeField(_('Date Created'), auto_now_add=True)
449
+
450
+    class Meta:
451
+        abstract = True
452
+        app_label = 'order'
453
+        verbose_name = _('Order Status Change')
454
+        verbose_name_plural = _('Order Status Changes')
455
+        ordering = ['-date_created']
456
+
457
+    def __str__(self):
458
+        return _('{order} has changed status from {old_status} to {new_status}').format(
459
+            order=self.order, old_status=self.old_status, new_status=self.new_status
460
+        )
461
+
462
+
433 463
 class AbstractCommunicationEvent(models.Model):
434 464
     """
435 465
     An order-level event involving a communication to the customer, such

+ 2
- 0
src/oscar/apps/order/admin.py 查看文件

@@ -4,6 +4,7 @@ from oscar.core.loading import get_model
4 4
 
5 5
 Order = get_model('order', 'Order')
6 6
 OrderNote = get_model('order', 'OrderNote')
7
+OrderStatusChange = get_model('order', 'OrderStatusChange')
7 8
 CommunicationEvent = get_model('order', 'CommunicationEvent')
8 9
 BillingAddress = get_model('order', 'BillingAddress')
9 10
 ShippingAddress = get_model('order', 'ShippingAddress')
@@ -68,6 +69,7 @@ class OrderDiscountAdmin(admin.ModelAdmin):
68 69
 
69 70
 admin.site.register(Order, OrderAdmin)
70 71
 admin.site.register(OrderNote)
72
+admin.site.register(OrderStatusChange)
71 73
 admin.site.register(ShippingAddress)
72 74
 admin.site.register(Line, LineAdmin)
73 75
 admin.site.register(LinePrice, LinePriceAdmin)

+ 30
- 0
src/oscar/apps/order/migrations/0006_orderstatuschange.py 查看文件

@@ -0,0 +1,30 @@
1
+# Generated by Django 2.1.1 on 2018-09-12 08:31
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('order', '0005_update_email_length'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='OrderStatusChange',
16
+            fields=[
17
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('old_status', models.CharField(blank=True, max_length=100, verbose_name='Old Status')),
19
+                ('new_status', models.CharField(blank=True, max_length=100, verbose_name='New Status')),
20
+                ('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date Created')),
21
+                ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_changes', to='order.Order', verbose_name='Order Status Changes')),
22
+            ],
23
+            options={
24
+                'verbose_name': 'Order Status Change',
25
+                'verbose_name_plural': 'Order Status Changes',
26
+                'ordering': ['-date_created'],
27
+                'abstract': False,
28
+            },
29
+        ),
30
+    ]

+ 7
- 0
src/oscar/apps/order/models.py 查看文件

@@ -20,6 +20,13 @@ if not is_model_registered('order', 'OrderNote'):
20 20
     __all__.append('OrderNote')
21 21
 
22 22
 
23
+if not is_model_registered('order', 'OrderStatusChange'):
24
+    class OrderStatusChange(AbstractOrderStatusChange):
25
+        pass
26
+
27
+    __all__.append('OrderStatusChange')
28
+
29
+
23 30
 if not is_model_registered('order', 'CommunicationEvent'):
24 31
     class CommunicationEvent(AbstractCommunicationEvent):
25 32
         pass

+ 34
- 0
src/oscar/templates/oscar/dashboard/orders/order_detail.html 查看文件

@@ -329,6 +329,40 @@
329 329
                     {% endblock %}
330 330
                 </form>
331 331
 
332
+                {% block order_status_changes %}
333
+                    <div class="table-header">
334
+                        <h3>{% trans "Status Changes" %}</h3>
335
+                    </div>
336
+                    {% with status_changes=order.status_changes.all %}
337
+                        <table class="table table-striped table-bordered table-hover">
338
+                            {% if status_changes %}
339
+                                <thead>
340
+                                    <tr>
341
+                                        <th>{% trans "From" %}</th>
342
+                                        <th>{% trans "To" %}</th>
343
+                                        <th>{% trans "Date" %}</th>
344
+                                    </tr>
345
+                                </thead>
346
+                                <tbody>
347
+                                    {% for status_change in status_changes %}
348
+                                        <tr>
349
+                                            <td>{{ status_change.old_status }}</td>
350
+                                            <td>{{ status_change.new_status }}</td>
351
+                                            <td>{{ status_change.date_created }}</td>
352
+                                        </tr>
353
+                                    {% endfor %}
354
+                                </tbody>
355
+                            {% else %}
356
+                                <tbody>
357
+                                    <tr>
358
+                                        <td>{% trans "No status changes." %}</td>
359
+                                    </tr>
360
+                                </tbody>
361
+                            {% endif %}
362
+                        </table>
363
+                    {% endwith %}
364
+                {% endblock %}
365
+
332 366
                 {% block shipping_events %}
333 367
                     <div class="table-header">
334 368
                         <h3>{% trans "Shipping Events" %}</h3>

+ 10
- 0
tests/integration/order/test_models.py 查看文件

@@ -83,6 +83,16 @@ class OrderStatusPipelineTests(TestCase):
83 83
             self.order.set_status('SHIPPED')
84 84
             self.assertEqual(receiver.call_count, 1)
85 85
 
86
+    def test_set_status_signal_creates_a_order_status_change_object(self):
87
+        self.order = create_order(status='PENDING')
88
+        self.order.set_status('SHIPPED')
89
+
90
+        order_status_change = self.order.status_changes.first()
91
+
92
+        self.assertEqual(self.order.status_changes.count(), 1)
93
+        self.assertEqual(order_status_change.old_status, 'PENDING')
94
+        self.assertEqual(order_status_change.new_status, 'SHIPPED')
95
+
86 96
 
87 97
 class OrderNoteTests(TestCase):
88 98
 

正在加载...
取消
保存