This commit is contained in:
j3d1 2023-12-18 01:06:16 +01:00
parent b8c3bcfa3b
commit b00976e0fa
6 changed files with 72 additions and 4 deletions

26
TODO.md
View file

@ -71,8 +71,30 @@
* [ ] concept: purge old tickets * [ ] concept: purge old tickets
* [ ] concept: purge old items * [ ] concept: purge old items
* [ ] concept: auto email stale after x days * [ ] concept: auto email stale after x days
* [ ] frontend: reply email field multiline
* [ ] concept: customisable autoreply (message, title) + ticket id
* [ ] frontend: show from address in issueThread or internal user
* [ ] manual ticket creation
* [ ] hide citation for incoming mails
* [ ] frontend: different icons for send and received mails
* [ ] frontend: change ticket status
* new mail -> new,
* op reply ->
* waiting for detail
* waiting for address / shipment information
* customer reply -> open
* needs physical confirmation
* needs to be shipped
* dhl mail -> closed: shipped
* closed: not found
* closed: not our problem
* closed: timeout (no reply)
* closed: duplicate
* closed: spam
* [ ] concept: split ticket for multiple items
* [ ] mail signature
* [ ] guru api integration
## Priority: TODO ## Priority: TODO
* send mails from web frontend * manual ticket creation
* login / user management

View file

@ -7,10 +7,12 @@ from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from core.settings import MAIL_DOMAIN from core.settings import MAIL_DOMAIN
from mail.models import Email from mail.models import Email
from mail.protocol import send_smtp, make_reply, collect_references from mail.protocol import send_smtp, make_reply, collect_references
from notify_sessions.models import SystemEvent
from tickets.models import IssueThread from tickets.models import IssueThread
@ -80,9 +82,34 @@ def reply(request, pk):
return Response({'status': 'ok'}, status=status.HTTP_201_CREATED) return Response({'status': 'ok'}, status=status.HTTP_201_CREATED)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
@permission_required('tickets.add_issuethread_manual', raise_exception=True)
def manual_ticket(request):
issue = IssueThread.objects.create(
name=request.data['name'],
manually_created=True,
)
email = Email.objects.create(
issue_thread=issue,
sender=request.data['sender'],
recipient=request.data['recipient'],
subject=request.data['name'],
body=request.data['body'],
)
systemevent = SystemEvent.objects.create(type='email received', reference=email.id)
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'general', {"type": "generic.event", "name": "send_message_to_frontend", "event_id": systemevent.id,
"message": "email received"}
)
return Response({'status': 'ok'}, status=status.HTTP_201_CREATED)
router = routers.SimpleRouter() router = routers.SimpleRouter()
router.register(r'tickets', IssueViewSet, basename='issues') router.register(r'tickets', IssueViewSet, basename='issues')
urlpatterns = router.urls + [ urlpatterns = router.urls + [
path('tickets/<int:pk>/reply/', reply, name='reply'), path('tickets/<int:pk>/reply/', reply, name='reply'),
path('tickets/manual', manual_ticket, name='manual_ticket'),
] ]

View file

@ -0,0 +1,18 @@
# Generated by Django 4.2.7 on 2023-12-17 23:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tickets', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='issuethread',
name='manually_created',
field=models.BooleanField(default=False),
),
]

View file

@ -10,6 +10,7 @@ class IssueThread(SoftDeleteModel):
state = models.CharField(max_length=255, default='new') state = models.CharField(max_length=255, default='new')
assigned_to = models.CharField(max_length=255, null=True) assigned_to = models.CharField(max_length=255, null=True)
last_activity = models.DateTimeField(auto_now=True) last_activity = models.DateTimeField(auto_now=True)
manually_created = models.BooleanField(default=False)
class Meta: class Meta:
permissions = [ permissions = [

View file

@ -1,5 +1,5 @@
<template> <template>
<table class="table table-striped table-dark"> <table class="table table-striped table-dark" style="table-layout: fixed">
<thead> <thead>
<tr> <tr>
<th scope="col"></th> <th scope="col"></th>

View file

@ -1,5 +1,5 @@
<template> <template>
<table class="table table-striped table-dark"> <table class="table table-striped table-dark" style="table-layout: fixed">
<thead> <thead>
<tr> <tr>
<th scope="col"></th> <th scope="col"></th>