add /shipping_vouchers endpoint
This commit is contained in:
parent
2f354130da
commit
f11758607e
6 changed files with 123 additions and 5 deletions
|
@ -1,6 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from tickets.models import IssueThread, Comment, StateChange
|
||||
from tickets.models import IssueThread, Comment, StateChange, Assignment, ShippingVoucher
|
||||
|
||||
|
||||
class IssueThreadAdmin(admin.ModelAdmin):
|
||||
|
@ -15,6 +15,16 @@ class StateChangeAdmin(admin.ModelAdmin):
|
|||
pass
|
||||
|
||||
|
||||
class AssignmentAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class ShippingVouchersAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
admin.site.register(IssueThread, IssueThreadAdmin)
|
||||
admin.site.register(Comment, CommentAdmin)
|
||||
admin.site.register(StateChange, StateChangeAdmin)
|
||||
admin.site.register(Assignment, AssignmentAdmin)
|
||||
admin.site.register(ShippingVoucher, ShippingVouchersAdmin)
|
||||
|
|
|
@ -13,8 +13,8 @@ from core.settings import MAIL_DOMAIN
|
|||
from mail.models import Email
|
||||
from mail.protocol import send_smtp, make_reply, collect_references
|
||||
from notify_sessions.models import SystemEvent
|
||||
from tickets.models import IssueThread, Comment, STATE_CHOICES
|
||||
from tickets.serializers import IssueSerializer, CommentSerializer
|
||||
from tickets.models import IssueThread, Comment, STATE_CHOICES, ShippingVoucher
|
||||
from tickets.serializers import IssueSerializer, CommentSerializer, ShippingVoucherSerializer
|
||||
|
||||
|
||||
class IssueViewSet(viewsets.ModelViewSet):
|
||||
|
@ -22,6 +22,11 @@ class IssueViewSet(viewsets.ModelViewSet):
|
|||
queryset = IssueThread.objects.all()
|
||||
|
||||
|
||||
class ShippingVoucherViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = ShippingVoucherSerializer
|
||||
queryset = ShippingVoucher.objects.all()
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@permission_required('tickets.add_issuethread', raise_exception=True)
|
||||
|
@ -113,6 +118,7 @@ def add_comment(request, pk):
|
|||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r'tickets', IssueViewSet, basename='issues')
|
||||
router.register(r'shipping_vouchers', ShippingVoucherViewSet, basename='shipping_vouchers')
|
||||
|
||||
urlpatterns = ([
|
||||
re_path(r'^tickets/(?P<pk>\d+)/reply/$', reply, name='reply'),
|
||||
|
|
25
core/tickets/migrations/0009_shippingvoucher.py
Normal file
25
core/tickets/migrations/0009_shippingvoucher.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 4.2.7 on 2024-06-23 00:47
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0008_alter_issuethread_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ShippingVoucher',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('voucher', models.CharField(max_length=255)),
|
||||
('type', models.CharField(max_length=255)),
|
||||
('timestamp', models.DateTimeField(auto_now_add=True)),
|
||||
('used_at', models.DateTimeField(null=True)),
|
||||
('issue_thread', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shipping_vouchers', to='tickets.issuethread')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django_softdelete.models import SoftDeleteModel
|
||||
|
||||
from authentication.models import ExtendedUser
|
||||
|
@ -116,3 +117,20 @@ class Assignment(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return str(self.issue_thread) + ' assigned to ' + self.assigned_to.username
|
||||
|
||||
|
||||
class ShippingVoucher(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
issue_thread = models.ForeignKey(IssueThread, on_delete=models.CASCADE, related_name='shipping_vouchers', null=True)
|
||||
voucher = models.CharField(max_length=255)
|
||||
type = models.CharField(max_length=255)
|
||||
timestamp = models.DateTimeField(auto_now_add=True)
|
||||
used_at = models.DateTimeField(null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.voucher + ' (' + self.type + ')'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.used_at is None and self.issue_thread is not None:
|
||||
self.used_at = timezone.now()
|
||||
super().save(*args, **kwargs)
|
||||
|
|
|
@ -2,7 +2,7 @@ from rest_framework import serializers
|
|||
|
||||
from authentication.models import ExtendedUser
|
||||
from mail.api_v2 import AttachmentSerializer
|
||||
from tickets.models import IssueThread, Comment, STATE_CHOICES
|
||||
from tickets.models import IssueThread, Comment, STATE_CHOICES, ShippingVoucher
|
||||
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer):
|
||||
|
@ -28,6 +28,13 @@ class StateSerializer(serializers.Serializer):
|
|||
return obj['value']
|
||||
|
||||
|
||||
class ShippingVoucherSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ShippingVoucher
|
||||
fields = ('id', 'voucher', 'type', 'timestamp', 'issue_thread', 'used_at')
|
||||
read_only_fields = ('id', 'timestamp', 'used_at')
|
||||
|
||||
|
||||
class IssueSerializer(serializers.ModelSerializer):
|
||||
timeline = serializers.SerializerMethodField()
|
||||
last_activity = serializers.SerializerMethodField()
|
||||
|
@ -60,7 +67,10 @@ class IssueSerializer(serializers.ModelSerializer):
|
|||
if self.state_changes.count() > 0 else None
|
||||
last_comment = self.comments.order_by('-timestamp').first().timestamp if self.comments.count() > 0 else None
|
||||
last_mail = self.emails.order_by('-timestamp').first().timestamp if self.emails.count() > 0 else None
|
||||
args = [x for x in [last_state_change, last_comment, last_mail] if x is not None]
|
||||
last_assignment = self.assignments.order_by('-timestamp').first().timestamp if \
|
||||
self.assignments.count() > 0 else None
|
||||
args = [x for x in [last_state_change, last_comment, last_mail, last_assignment] if
|
||||
x is not None]
|
||||
return max(args)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
@ -100,6 +110,14 @@ class IssueSerializer(serializers.ModelSerializer):
|
|||
'timestamp': assignment.timestamp,
|
||||
'assigned_to': assignment.assigned_to.username,
|
||||
})
|
||||
for shipping_voucher in obj.shipping_vouchers.all():
|
||||
timeline.append({
|
||||
'type': 'shipping_voucher',
|
||||
'id': shipping_voucher.id,
|
||||
'timestamp': shipping_voucher.used_at,
|
||||
'voucher': shipping_voucher.voucher,
|
||||
'voucher_type': shipping_voucher.type,
|
||||
})
|
||||
return sorted(timeline, key=lambda x: x['timestamp'])
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
41
core/tickets/tests/v2/test_shipping_vouchers.py
Normal file
41
core/tickets/tests/v2/test_shipping_vouchers.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
from django.test import TestCase, Client
|
||||
|
||||
from authentication.models import ExtendedUser
|
||||
from mail.models import Email, EmailAttachment
|
||||
from tickets.models import IssueThread, StateChange, Comment, ShippingVoucher
|
||||
from django.contrib.auth.models import Permission
|
||||
from knox.models import AuthToken
|
||||
|
||||
|
||||
class ShippingVoucherApiTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.token = AuthToken.objects.create(user=self.user)
|
||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||
|
||||
def test_issues_empty(self):
|
||||
response = self.client.get('/api/2/shipping_vouchers/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), [])
|
||||
|
||||
def test_issues_list(self):
|
||||
ShippingVoucher.objects.create(voucher='1234', type='2kg-eu')
|
||||
response = self.client.get('/api/2/shipping_vouchers/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json()[0]['voucher'], '1234')
|
||||
self.assertEqual(response.json()[0]['used_at'], None)
|
||||
self.assertEqual(response.json()[0]['issue_thread'], None)
|
||||
self.assertEqual(response.json()[0]['type'], '2kg-eu')
|
||||
|
||||
def test_issues_create(self):
|
||||
response = self.client.post('/api/2/shipping_vouchers/', {'voucher': '1234', 'type': '2kg-eu'})
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(response.json()['voucher'], '1234')
|
||||
self.assertEqual(response.json()['used_at'], None)
|
||||
self.assertEqual(response.json()['issue_thread'], None)
|
Loading…
Reference in a new issue