stash
This commit is contained in:
parent
b8c3bcfa3b
commit
b00976e0fa
6 changed files with 72 additions and 4 deletions
26
TODO.md
26
TODO.md
|
@ -71,8 +71,30 @@
|
|||
* [ ] concept: purge old tickets
|
||||
* [ ] concept: purge old items
|
||||
* [ ] 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
|
||||
|
||||
* send mails from web frontend
|
||||
* login / user management
|
||||
* manual ticket creation
|
||||
|
|
|
@ -7,10 +7,12 @@ from rest_framework.decorators import api_view, permission_classes
|
|||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from asgiref.sync import async_to_sync
|
||||
from channels.layers import get_channel_layer
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -80,9 +82,34 @@ def reply(request, pk):
|
|||
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.register(r'tickets', IssueViewSet, basename='issues')
|
||||
|
||||
urlpatterns = router.urls + [
|
||||
path('tickets/<int:pk>/reply/', reply, name='reply'),
|
||||
path('tickets/manual', manual_ticket, name='manual_ticket'),
|
||||
]
|
||||
|
|
18
core/tickets/migrations/0002_issuethread_manually_created.py
Normal file
18
core/tickets/migrations/0002_issuethread_manually_created.py
Normal 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),
|
||||
),
|
||||
]
|
|
@ -10,6 +10,7 @@ class IssueThread(SoftDeleteModel):
|
|||
state = models.CharField(max_length=255, default='new')
|
||||
assigned_to = models.CharField(max_length=255, null=True)
|
||||
last_activity = models.DateTimeField(auto_now=True)
|
||||
manually_created = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
permissions = [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<table class="table table-striped table-dark">
|
||||
<table class="table table-striped table-dark" style="table-layout: fixed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<table class="table table-striped table-dark">
|
||||
<table class="table table-striped table-dark" style="table-layout: fixed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
|
|
Loading…
Reference in a new issue