You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.7 KiB
Python

from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.template.loader import get_template
from django.core.mail import send_mail
ROOT_URL = settings.ROOT_URL
SITE_NAME = settings.TICKETS_SITE_NAME
CATEGORY_CHOICES = (
('support', _("Support")),
('security', _("Security")),
('billing', _("Account / Billing")),
)
if hasattr(settings, 'TICKETS_CATEGORIES'):
CATEGORY_CHOICES = settings.TICKETS_CATEGORIES
def notify(subject, template, recipient_list, params):
ctx = dict(site_name=SITE_NAME, **params)
text = get_template(template).render(ctx)
for a in recipient_list:
send_mail(subject, text, settings.DEFAULT_FROM_EMAIL, [a], fail_silently=True)
class Ticket(models.Model):
class Meta:
ordering = ('-created',)
permissions = (
('view_any_ticket', _("Can view any ticket")),
('reply_any_ticket', _("Can reply to any ticket")),
('view_private_message', _("Can view private messages on tickets")),
('post_private_message', _("Can post private messages on tickets")),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
on_delete=models.SET_NULL)
category = models.CharField(max_length=16, choices=CATEGORY_CHOICES)
subject = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
is_open = models.BooleanField(default=True)
closed = models.DateTimeField(blank=True, null=True)
@property
def status_text(self):
if self.closed:
return _("Closed")
last_msg = self.message_set.last()
if last_msg and last_msg.user == self.user:
return _("Waiting for staff")
else:
return _("Open")
def get_contacts(self):
contacts = TicketNotifyAddress.objects.filter(category=self.category)
return [c.address for c in contacts]
def notify_new(self, first_message):
url = ROOT_URL + reverse('tickets:view', args=(self.id,))
subject = _("Ticket:") + " " + self.subject
ctx = dict(ticket=self, message=first_message, url=url)
notify(subject, 'tickets/mail_support_new.txt', self.get_contacts(), ctx)
def notify_reply(self, message):
url = ROOT_URL + reverse('tickets:view', args=(self.id,))
subject = _("Ticket:") + " " + self.subject
ctx = dict(ticket=self, message=message, url=url)
if message.user == self.user:
notify(subject, 'tickets/mail_support_reply.txt', self.get_contacts(), ctx)
if self.user and self.user.email:
if message.staff_only and not self.user.has_perm('tickets.view_private_message'):
return
notify(subject, 'tickets/mail_user_reply.txt', [self.user.email], ctx)
def __str__(self):
return self.subject
def get_absolute_url(self):
return reverse('tickets:view', args=(self.id,))
class TicketNotifyAddress(models.Model):
category = models.CharField(max_length=16, choices=CATEGORY_CHOICES)
address = models.EmailField()
class TicketMessage(models.Model):
ticket = models.ForeignKey(Ticket, related_name='message_set',
on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
on_delete=models.SET_NULL)
remote_addr = models.GenericIPAddressField(blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
message = models.TextField()
staff_only = models.BooleanField(default=False)
class Meta:
ordering = ('created',)