mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2024-12-24 15:48:49 +01:00
fix(kb): no db
This commit is contained in:
parent
909b7a5533
commit
347a70e497
@ -1,10 +1,13 @@
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from helpdesk.models import Queue, Ticket, FollowUp, PreSetReply, KBCategory
|
||||
from helpdesk.models import EscalationExclusion, EmailTemplate, KBItem
|
||||
from helpdesk.models import Queue, Ticket, FollowUp, PreSetReply
|
||||
from helpdesk.models import EscalationExclusion, EmailTemplate
|
||||
from helpdesk.models import TicketChange, KBIAttachment, FollowUpAttachment, IgnoreEmail
|
||||
from helpdesk.models import CustomField
|
||||
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
from helpdesk.models import KBCategory
|
||||
from helpdesk.models import KBItem
|
||||
|
||||
@admin.register(Queue)
|
||||
class QueueAdmin(admin.ModelAdmin):
|
||||
@ -68,13 +71,18 @@ class FollowUpAdmin(admin.ModelAdmin):
|
||||
ticket_get_ticket_for_url.short_description = _('Slug')
|
||||
|
||||
|
||||
@admin.register(KBItem)
|
||||
class KBItemAdmin(admin.ModelAdmin):
|
||||
list_display = ('category', 'title', 'last_updated', 'team', 'order', 'enabled')
|
||||
inlines = [KBIAttachmentInline]
|
||||
readonly_fields = ('voted_by', 'downvoted_by')
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
@admin.register(KBItem)
|
||||
class KBItemAdmin(admin.ModelAdmin):
|
||||
list_display = ('category', 'title', 'last_updated', 'team', 'order', 'enabled')
|
||||
inlines = [KBIAttachmentInline]
|
||||
readonly_fields = ('voted_by', 'downvoted_by')
|
||||
|
||||
list_display_links = ('title',)
|
||||
list_display_links = ('title',)
|
||||
|
||||
@admin.register(KBCategory)
|
||||
class KBCategoryAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'title', 'slug', 'public')
|
||||
|
||||
|
||||
@admin.register(CustomField)
|
||||
@ -93,10 +101,5 @@ class IgnoreEmailAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'queue_list', 'email_address', 'keep_in_mailbox')
|
||||
|
||||
|
||||
@admin.register(KBCategory)
|
||||
class KBCategoryAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'title', 'slug', 'public')
|
||||
|
||||
|
||||
admin.site.register(PreSetReply)
|
||||
admin.site.register(EscalationExclusion)
|
||||
|
@ -18,9 +18,13 @@ from django.utils import timezone
|
||||
|
||||
from helpdesk.lib import safe_template_context, process_attachments
|
||||
from helpdesk.models import (Ticket, Queue, FollowUp, IgnoreEmail, TicketCC,
|
||||
CustomField, TicketCustomFieldValue, TicketDependency, UserSettings, KBItem)
|
||||
CustomField, TicketCustomFieldValue, TicketDependency, UserSettings)
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
|
||||
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
from helpdesk.models import (KBItem)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
User = get_user_model()
|
||||
|
||||
@ -231,13 +235,14 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form):
|
||||
|
||||
def __init__(self, kbcategory=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if kbcategory:
|
||||
self.fields['kbitem'] = forms.ChoiceField(
|
||||
widget=forms.Select(attrs={'class': 'form-control'}),
|
||||
required=False,
|
||||
label=_('Knowledge Base Item'),
|
||||
choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk, enabled=True)],
|
||||
)
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
if kbcategory:
|
||||
self.fields['kbitem'] = forms.ChoiceField(
|
||||
widget=forms.Select(attrs={'class': 'form-control'}),
|
||||
required=False,
|
||||
label=_('Knowledge Base Item'),
|
||||
choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk, enabled=True)],
|
||||
)
|
||||
|
||||
def _add_form_custom_fields(self, staff_only_filter=None):
|
||||
if staff_only_filter is None:
|
||||
|
@ -1275,166 +1275,166 @@ class EmailTemplate(models.Model):
|
||||
verbose_name = _('e-mail template')
|
||||
verbose_name_plural = _('e-mail templates')
|
||||
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
class KBCategory(models.Model):
|
||||
"""
|
||||
Lets help users help themselves: the Knowledge Base is a categorised
|
||||
listing of questions & answers.
|
||||
"""
|
||||
|
||||
class KBCategory(models.Model):
|
||||
"""
|
||||
Lets help users help themselves: the Knowledge Base is a categorised
|
||||
listing of questions & answers.
|
||||
"""
|
||||
name = models.CharField(
|
||||
_('Name of the category'),
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
name = models.CharField(
|
||||
_('Name of the category'),
|
||||
max_length=100,
|
||||
)
|
||||
title = models.CharField(
|
||||
_('Title on knowledgebase page'),
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
title = models.CharField(
|
||||
_('Title on knowledgebase page'),
|
||||
max_length=100,
|
||||
)
|
||||
slug = models.SlugField(
|
||||
_('Slug'),
|
||||
)
|
||||
|
||||
slug = models.SlugField(
|
||||
_('Slug'),
|
||||
)
|
||||
description = models.TextField(
|
||||
_('Description'),
|
||||
)
|
||||
|
||||
description = models.TextField(
|
||||
_('Description'),
|
||||
)
|
||||
queue = models.ForeignKey(
|
||||
Queue,
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Default queue when creating a ticket after viewing this category.'),
|
||||
)
|
||||
|
||||
queue = models.ForeignKey(
|
||||
Queue,
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Default queue when creating a ticket after viewing this category.'),
|
||||
)
|
||||
public = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_("Is KBCategory publicly visible?")
|
||||
)
|
||||
|
||||
public = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_("Is KBCategory publicly visible?")
|
||||
)
|
||||
def __str__(self):
|
||||
return '%s' % self.name
|
||||
|
||||
def __str__(self):
|
||||
return '%s' % self.name
|
||||
class Meta:
|
||||
ordering = ('title',)
|
||||
verbose_name = _('Knowledge base category')
|
||||
verbose_name_plural = _('Knowledge base categories')
|
||||
|
||||
class Meta:
|
||||
ordering = ('title',)
|
||||
verbose_name = _('Knowledge base category')
|
||||
verbose_name_plural = _('Knowledge base categories')
|
||||
|
||||
def get_absolute_url(self):
|
||||
from django.urls import reverse
|
||||
return reverse('helpdesk:kb_category', kwargs={'slug': self.slug})
|
||||
def get_absolute_url(self):
|
||||
from django.urls import reverse
|
||||
return reverse('helpdesk:kb_category', kwargs={'slug': self.slug})
|
||||
|
||||
|
||||
class KBItem(models.Model):
|
||||
"""
|
||||
An item within the knowledgebase. Very straightforward question/answer
|
||||
style system.
|
||||
"""
|
||||
voted_by = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name='votes',
|
||||
)
|
||||
downvoted_by = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name='downvotes',
|
||||
)
|
||||
category = models.ForeignKey(
|
||||
KBCategory,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Category'),
|
||||
)
|
||||
class KBItem(models.Model):
|
||||
"""
|
||||
An item within the knowledgebase. Very straightforward question/answer
|
||||
style system.
|
||||
"""
|
||||
voted_by = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name='votes',
|
||||
)
|
||||
downvoted_by = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL,
|
||||
related_name='downvotes',
|
||||
)
|
||||
category = models.ForeignKey(
|
||||
KBCategory,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Category'),
|
||||
)
|
||||
|
||||
title = models.CharField(
|
||||
_('Title'),
|
||||
max_length=100,
|
||||
)
|
||||
title = models.CharField(
|
||||
_('Title'),
|
||||
max_length=100,
|
||||
)
|
||||
|
||||
question = models.TextField(
|
||||
_('Question'),
|
||||
)
|
||||
question = models.TextField(
|
||||
_('Question'),
|
||||
)
|
||||
|
||||
answer = models.TextField(
|
||||
_('Answer'),
|
||||
)
|
||||
answer = models.TextField(
|
||||
_('Answer'),
|
||||
)
|
||||
|
||||
votes = models.IntegerField(
|
||||
_('Votes'),
|
||||
help_text=_('Total number of votes cast for this item'),
|
||||
default=0,
|
||||
)
|
||||
votes = models.IntegerField(
|
||||
_('Votes'),
|
||||
help_text=_('Total number of votes cast for this item'),
|
||||
default=0,
|
||||
)
|
||||
|
||||
recommendations = models.IntegerField(
|
||||
_('Positive Votes'),
|
||||
help_text=_('Number of votes for this item which were POSITIVE.'),
|
||||
default=0,
|
||||
)
|
||||
recommendations = models.IntegerField(
|
||||
_('Positive Votes'),
|
||||
help_text=_('Number of votes for this item which were POSITIVE.'),
|
||||
default=0,
|
||||
)
|
||||
|
||||
last_updated = models.DateTimeField(
|
||||
_('Last Updated'),
|
||||
help_text=_('The date on which this question was most recently changed.'),
|
||||
blank=True,
|
||||
)
|
||||
last_updated = models.DateTimeField(
|
||||
_('Last Updated'),
|
||||
help_text=_('The date on which this question was most recently changed.'),
|
||||
blank=True,
|
||||
)
|
||||
|
||||
team = models.ForeignKey(
|
||||
helpdesk_settings.HELPDESK_TEAMS_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Team'),
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
team = models.ForeignKey(
|
||||
helpdesk_settings.HELPDESK_TEAMS_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_('Team'),
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
order = models.PositiveIntegerField(
|
||||
_('Order'),
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
order = models.PositiveIntegerField(
|
||||
_('Order'),
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
enabled = models.BooleanField(
|
||||
_('Enabled to display to users'),
|
||||
default=True,
|
||||
)
|
||||
enabled = models.BooleanField(
|
||||
_('Enabled to display to users'),
|
||||
default=True,
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.last_updated:
|
||||
self.last_updated = timezone.now()
|
||||
return super(KBItem, self).save(*args, **kwargs)
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.last_updated:
|
||||
self.last_updated = timezone.now()
|
||||
return super(KBItem, self).save(*args, **kwargs)
|
||||
|
||||
def get_team(self):
|
||||
return helpdesk_settings.HELPDESK_KBITEM_TEAM_GETTER(self)
|
||||
def get_team(self):
|
||||
return helpdesk_settings.HELPDESK_KBITEM_TEAM_GETTER(self)
|
||||
|
||||
def _score(self):
|
||||
""" Return a score out of 10 or Unrated if no votes """
|
||||
if self.votes > 0:
|
||||
return (self.recommendations / self.votes) * 10
|
||||
else:
|
||||
return _('Unrated')
|
||||
score = property(_score)
|
||||
def _score(self):
|
||||
""" Return a score out of 10 or Unrated if no votes """
|
||||
if self.votes > 0:
|
||||
return (self.recommendations / self.votes) * 10
|
||||
else:
|
||||
return _('Unrated')
|
||||
score = property(_score)
|
||||
|
||||
def __str__(self):
|
||||
return '%s: %s' % (self.category.title, self.title)
|
||||
def __str__(self):
|
||||
return '%s: %s' % (self.category.title, self.title)
|
||||
|
||||
class Meta:
|
||||
ordering = ('order', 'title',)
|
||||
verbose_name = _('Knowledge base item')
|
||||
verbose_name_plural = _('Knowledge base items')
|
||||
class Meta:
|
||||
ordering = ('order', 'title',)
|
||||
verbose_name = _('Knowledge base item')
|
||||
verbose_name_plural = _('Knowledge base items')
|
||||
|
||||
def get_absolute_url(self):
|
||||
from django.urls import reverse
|
||||
return str(reverse('helpdesk:kb_category', args=(self.category.slug,))) + "?kbitem=" + str(self.pk)
|
||||
def get_absolute_url(self):
|
||||
from django.urls import reverse
|
||||
return str(reverse('helpdesk:kb_category', args=(self.category.slug,))) + "?kbitem=" + str(self.pk)
|
||||
|
||||
def query_url(self):
|
||||
from django.urls import reverse
|
||||
return str(reverse('helpdesk:list')) + "?kbitem=" + str(self.pk)
|
||||
def query_url(self):
|
||||
from django.urls import reverse
|
||||
return str(reverse('helpdesk:list')) + "?kbitem=" + str(self.pk)
|
||||
|
||||
def num_open_tickets(self):
|
||||
return Ticket.objects.filter(kbitem=self, status__in=(1, 2)).count()
|
||||
def num_open_tickets(self):
|
||||
return Ticket.objects.filter(kbitem=self, status__in=(1, 2)).count()
|
||||
|
||||
def unassigned_tickets(self):
|
||||
return Ticket.objects.filter(kbitem=self, status__in=(1, 2), assigned_to__isnull=True)
|
||||
def unassigned_tickets(self):
|
||||
return Ticket.objects.filter(kbitem=self, status__in=(1, 2), assigned_to__isnull=True)
|
||||
|
||||
def get_markdown(self):
|
||||
return get_markdown(self.answer)
|
||||
def get_markdown(self):
|
||||
return get_markdown(self.answer)
|
||||
|
||||
|
||||
class SavedSearch(models.Model):
|
||||
|
@ -14,7 +14,13 @@ from django.views.generic import TemplateView
|
||||
|
||||
from helpdesk.decorators import helpdesk_staff_member_required, protect_view
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
from helpdesk.views import feeds, staff, public, kb, login
|
||||
from helpdesk.views import feeds, staff, public, login
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
|
||||
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
from helpdesk.views import kb
|
||||
|
||||
try:
|
||||
# TODO: why is it imported? due to some side-effect or by mistake?
|
||||
import helpdesk.tasks # NOQA
|
||||
|
@ -50,9 +50,12 @@ from helpdesk.lib import (
|
||||
)
|
||||
from helpdesk.models import (
|
||||
Ticket, Queue, FollowUp, TicketChange, PreSetReply, FollowUpAttachment, SavedSearch,
|
||||
IgnoreEmail, TicketCC, TicketDependency, UserSettings, KBItem, CustomField, TicketCustomFieldValue,
|
||||
IgnoreEmail, TicketCC, TicketDependency, UserSettings, CustomField, TicketCustomFieldValue,
|
||||
)
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||
from helpdesk.models import (KBItem)
|
||||
|
||||
import helpdesk.views.abstract_views as abstract_views
|
||||
from helpdesk.views.permissions import MustBeStaffMixin
|
||||
from ..lib import format_time_spent
|
||||
|
Loading…
Reference in New Issue
Block a user