mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2025-06-22 18:41:44 +02:00
Merge pull request #1266 from django-helpdesk/django_5_ugrade
Django 5 upgrade
This commit is contained in:
commit
8ad622861a
2
.github/workflows/pythonpackage.yml
vendored
2
.github/workflows/pythonpackage.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
django-version: "4"
|
django-version: "4"
|
||||||
# Define the general matrix for Python with Django
|
# Define the general matrix for Python with Django
|
||||||
python-version: ["3.10", "3.11", "3.12"]
|
python-version: ["3.10", "3.11", "3.12"]
|
||||||
django-version: ["4"]
|
django-version: ["4", "5"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -211,7 +211,6 @@ TIME_ZONE = "UTC"
|
|||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
USE_L10N = True
|
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ class TicketAdmin(admin.ModelAdmin):
|
|||||||
list_filter = ("queue", "assigned_to", "status")
|
list_filter = ("queue", "assigned_to", "status")
|
||||||
search_fields = ("id", "title")
|
search_fields = ("id", "title")
|
||||||
|
|
||||||
|
@admin.display(description=_("Submitter E-Mail"))
|
||||||
def hidden_submitter_email(self, ticket):
|
def hidden_submitter_email(self, ticket):
|
||||||
if ticket.submitter_email:
|
if ticket.submitter_email:
|
||||||
username, domain = ticket.submitter_email.split("@")
|
username, domain = ticket.submitter_email.split("@")
|
||||||
@ -64,8 +65,6 @@ class TicketAdmin(admin.ModelAdmin):
|
|||||||
else:
|
else:
|
||||||
return ticket.submitter_email
|
return ticket.submitter_email
|
||||||
|
|
||||||
hidden_submitter_email.short_description = _("Submitter E-Mail")
|
|
||||||
|
|
||||||
def time_spent(self, ticket):
|
def time_spent(self, ticket):
|
||||||
return ticket.time_spent
|
return ticket.time_spent
|
||||||
|
|
||||||
@ -99,11 +98,10 @@ class FollowUpAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
list_filter = ("user", "date", "new_status")
|
list_filter = ("user", "date", "new_status")
|
||||||
|
|
||||||
|
@admin.display(description=_("Slug"))
|
||||||
def ticket_get_ticket_for_url(self, obj):
|
def ticket_get_ticket_for_url(self, obj):
|
||||||
return obj.ticket.ticket_for_url
|
return obj.ticket.ticket_for_url
|
||||||
|
|
||||||
ticket_get_ticket_for_url.short_description = _("Slug")
|
|
||||||
|
|
||||||
|
|
||||||
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
if helpdesk_settings.HELPDESK_KB_ENABLED:
|
||||||
|
|
||||||
|
@ -1274,10 +1274,7 @@ class FollowUpAttachment(Attachment):
|
|||||||
id_=self.followup.id,
|
id_=self.followup.id,
|
||||||
)
|
)
|
||||||
att_path = os.path.join(settings.MEDIA_ROOT, path)
|
att_path = os.path.join(settings.MEDIA_ROOT, path)
|
||||||
if (
|
if settings.STORAGES == "django.core.files.storage.FileSystemStorage":
|
||||||
settings.DEFAULT_FILE_STORAGE
|
|
||||||
== "django.core.files.storage.FileSystemStorage"
|
|
||||||
):
|
|
||||||
if not os.path.exists(att_path):
|
if not os.path.exists(att_path):
|
||||||
os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS)
|
os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS)
|
||||||
return os.path.join(path, filename)
|
return os.path.join(path, filename)
|
||||||
@ -1295,10 +1292,7 @@ class KBIAttachment(Attachment):
|
|||||||
category=self.kbitem.category, kbi=self.kbitem.id
|
category=self.kbitem.category, kbi=self.kbitem.id
|
||||||
)
|
)
|
||||||
att_path = os.path.join(settings.MEDIA_ROOT, path)
|
att_path = os.path.join(settings.MEDIA_ROOT, path)
|
||||||
if (
|
if settings.STORAGES == "django.core.files.storage.FileSystemStorage":
|
||||||
settings.DEFAULT_FILE_STORAGE
|
|
||||||
== "django.core.files.storage.FileSystemStorage"
|
|
||||||
):
|
|
||||||
if not os.path.exists(att_path):
|
if not os.path.exists(att_path):
|
||||||
os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS)
|
os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS)
|
||||||
return os.path.join(path, filename)
|
return os.path.join(path, filename)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import base64
|
import base64
|
||||||
from collections import OrderedDict
|
import datetime
|
||||||
from datetime import datetime
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
@ -15,10 +14,15 @@ from rest_framework.status import (
|
|||||||
HTTP_403_FORBIDDEN,
|
HTTP_403_FORBIDDEN,
|
||||||
)
|
)
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
from _datetime import timedelta
|
||||||
|
from helpdesk.lib import convert_value
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
frozen_date_time_str = (datetime.datetime.now() - timedelta(days=100)).isoformat()
|
||||||
|
|
||||||
|
|
||||||
class TicketTest(APITestCase):
|
class TicketTest(APITestCase):
|
||||||
due_date = datetime(2022, 4, 10, 15, 6)
|
due_date = timezone.now() - timedelta(days=20)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
@ -212,8 +216,12 @@ class TicketTest(APITestCase):
|
|||||||
self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
|
self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
|
||||||
self.assertFalse(Ticket.objects.exists())
|
self.assertFalse(Ticket.objects.exists())
|
||||||
|
|
||||||
@freeze_time("2022-06-30 23:09:44")
|
@freeze_time(frozen_date_time_str)
|
||||||
def test_create_api_ticket_with_custom_fields(self):
|
def test_create_api_ticket_with_custom_fields(self):
|
||||||
|
custom_date = "2022-04-11"
|
||||||
|
custom_time = "23:59:59"
|
||||||
|
custom_datetime = convert_value(datetime.datetime.now() - timedelta(days=30))
|
||||||
|
|
||||||
# Create custom fields
|
# Create custom fields
|
||||||
for field_type, field_display in CustomField.DATA_TYPE_CHOICES:
|
for field_type, field_display in CustomField.DATA_TYPE_CHOICES:
|
||||||
extra_data = {}
|
extra_data = {}
|
||||||
@ -273,9 +281,9 @@ class TicketTest(APITestCase):
|
|||||||
"custom_decimal": "42.987",
|
"custom_decimal": "42.987",
|
||||||
"custom_list": "Red",
|
"custom_list": "Red",
|
||||||
"custom_boolean": True,
|
"custom_boolean": True,
|
||||||
"custom_date": "2022-4-11",
|
"custom_date": custom_date,
|
||||||
"custom_time": "23:59:59",
|
"custom_time": custom_time,
|
||||||
"custom_datetime": "2022-4-10 18:27",
|
"custom_datetime": custom_datetime,
|
||||||
"custom_email": "email@test.com",
|
"custom_email": "email@test.com",
|
||||||
"custom_url": "http://django-helpdesk.readthedocs.org/",
|
"custom_url": "http://django-helpdesk.readthedocs.org/",
|
||||||
"custom_ipaddress": "127.0.0.1",
|
"custom_ipaddress": "127.0.0.1",
|
||||||
@ -284,7 +292,12 @@ class TicketTest(APITestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, HTTP_201_CREATED)
|
self.assertEqual(response.status_code, HTTP_201_CREATED)
|
||||||
# Check all fields with data returned from the response
|
# Check all fields with data returned from the response
|
||||||
self.assertEqual(
|
self.maxDiff = None
|
||||||
|
# The date string generated sometimes has a "Z" appended so until they why is figured out...
|
||||||
|
date_suffix_hack = (
|
||||||
|
"Z" if response.data["followup_set"][0]["date"].endswith("Z") else ""
|
||||||
|
)
|
||||||
|
self.assertDictEqual(
|
||||||
response.data,
|
response.data,
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@ -300,21 +313,19 @@ class TicketTest(APITestCase):
|
|||||||
"due_date": None,
|
"due_date": None,
|
||||||
"merged_to": None,
|
"merged_to": None,
|
||||||
"followup_set": [
|
"followup_set": [
|
||||||
OrderedDict(
|
{
|
||||||
[
|
"id": 1,
|
||||||
("id", 1),
|
"ticket": 1,
|
||||||
("ticket", 1),
|
"user": 1,
|
||||||
("user", 1),
|
"title": "Ticket Opened",
|
||||||
("title", "Ticket Opened"),
|
"comment": "Test description\nMulti lines",
|
||||||
("comment", "Test description\nMulti lines"),
|
"public": True,
|
||||||
("public", True),
|
"new_status": None,
|
||||||
("new_status", None),
|
"time_spent": None,
|
||||||
("time_spent", None),
|
"followupattachment_set": [],
|
||||||
("followupattachment_set", []),
|
"date": frozen_date_time_str + date_suffix_hack,
|
||||||
("date", "2022-06-30T23:09:44"),
|
"message_id": None,
|
||||||
("message_id", None),
|
}
|
||||||
]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
"custom_varchar": "test",
|
"custom_varchar": "test",
|
||||||
"custom_text": "multi\nline",
|
"custom_text": "multi\nline",
|
||||||
@ -322,9 +333,9 @@ class TicketTest(APITestCase):
|
|||||||
"custom_decimal": "42.987",
|
"custom_decimal": "42.987",
|
||||||
"custom_list": "Red",
|
"custom_list": "Red",
|
||||||
"custom_boolean": True,
|
"custom_boolean": True,
|
||||||
"custom_date": "2022-04-11",
|
"custom_date": custom_date,
|
||||||
"custom_time": "23:59:59",
|
"custom_time": custom_time,
|
||||||
"custom_datetime": "2022-04-10T18:27",
|
"custom_datetime": custom_datetime,
|
||||||
"custom_email": "email@test.com",
|
"custom_email": "email@test.com",
|
||||||
"custom_url": "http://django-helpdesk.readthedocs.org/",
|
"custom_url": "http://django-helpdesk.readthedocs.org/",
|
||||||
"custom_ipaddress": "127.0.0.1",
|
"custom_ipaddress": "127.0.0.1",
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
from datetime import datetime
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from helpdesk.models import Checklist, ChecklistTask, ChecklistTemplate, Queue, Ticket
|
from helpdesk.models import Checklist, ChecklistTask, ChecklistTemplate, Queue, Ticket
|
||||||
|
from _datetime import timedelta
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class TicketChecklistTestCase(TestCase):
|
class TicketChecklistTestCase(TestCase):
|
||||||
@ -167,7 +168,9 @@ class TicketChecklistTestCase(TestCase):
|
|||||||
def test_mark_task_as_undone(self):
|
def test_mark_task_as_undone(self):
|
||||||
checklist = self.ticket.checklists.create(name="Test checklist")
|
checklist = self.ticket.checklists.create(name="Test checklist")
|
||||||
task = checklist.tasks.create(
|
task = checklist.tasks.create(
|
||||||
description="Task", position=1, completion_date=datetime(2023, 5, 1)
|
description="Task",
|
||||||
|
position=1,
|
||||||
|
completion_date=timezone.now() - timedelta(days=10),
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(task.completion_date)
|
self.assertIsNotNone(task.completion_date)
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from django.urls import reverse
|
|||||||
from helpdesk.models import FollowUp, Queue, Ticket
|
from helpdesk.models import FollowUp, Queue, Ticket
|
||||||
from helpdesk import settings as helpdesk_settings
|
from helpdesk import settings as helpdesk_settings
|
||||||
import uuid
|
import uuid
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
@override_settings(USE_TZ=True)
|
@override_settings(USE_TZ=True)
|
||||||
@ -413,9 +414,7 @@ class TimeSpentAutoTestCase(TestCase):
|
|||||||
"queue": queues["new"],
|
"queue": queues["new"],
|
||||||
"assigned_to": self.user,
|
"assigned_to": self.user,
|
||||||
"status": Ticket.OPEN_STATUS,
|
"status": Ticket.OPEN_STATUS,
|
||||||
"created": datetime.strptime(
|
"created": timezone.now() - timedelta(days=10),
|
||||||
"2024-04-09T08:00:00+00:00", "%Y-%m-%dT%H:%M:%S%z"
|
|
||||||
),
|
|
||||||
"description": "Followup time spent auto exclude queues",
|
"description": "Followup time spent auto exclude queues",
|
||||||
}
|
}
|
||||||
ticket = Ticket.objects.create(**initial_data)
|
ticket = Ticket.objects.create(**initial_data)
|
||||||
|
@ -150,13 +150,13 @@ urlpatterns = [
|
|||||||
|
|
||||||
if helpdesk_settings.HELPDESK_ENABLE_DEPENDENCIES_ON_TICKET:
|
if helpdesk_settings.HELPDESK_ENABLE_DEPENDENCIES_ON_TICKET:
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
re_path(
|
path(
|
||||||
r"^tickets/(?P<ticket_id>[0-9]+)/dependency/add/$",
|
"tickets/<int:ticket_id>/dependency/add/",
|
||||||
staff.ticket_dependency_add,
|
staff.ticket_dependency_add,
|
||||||
name="ticket_dependency_add",
|
name="ticket_dependency_add",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^tickets/(?P<ticket_id>[0-9]+)/dependency/delete/(?P<dependency_id>[0-9]+)/$",
|
"tickets/<int:ticket_id>/dependency/delete/<int:dependency_id>/",
|
||||||
staff.ticket_dependency_del,
|
staff.ticket_dependency_del,
|
||||||
name="ticket_dependency_del",
|
name="ticket_dependency_del",
|
||||||
),
|
),
|
||||||
@ -221,7 +221,7 @@ router.register(
|
|||||||
r"followups-attachments", FollowUpAttachmentViewSet, basename="followupattachments"
|
r"followups-attachments", FollowUpAttachmentViewSet, basename="followupattachments"
|
||||||
)
|
)
|
||||||
router.register(r"users", CreateUserView, basename="user")
|
router.register(r"users", CreateUserView, basename="user")
|
||||||
urlpatterns += [re_path(r"^api/", include(router.urls))]
|
urlpatterns += [path("api/", include(router.urls))]
|
||||||
|
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
|
11
setup.py
11
setup.py
@ -134,15 +134,16 @@ setup(
|
|||||||
long_description_content_type="text/x-rst",
|
long_description_content_type="text/x-rst",
|
||||||
long_description=get_long_description(),
|
long_description=get_long_description(),
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 5 - Production/Stable",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.8",
|
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: 3.12",
|
||||||
"Framework :: Django",
|
"Framework :: Django",
|
||||||
"Framework :: Django :: 3.2",
|
|
||||||
"Framework :: Django :: 4.0",
|
"Framework :: Django :: 4.0",
|
||||||
|
"Framework :: Django :: 5.0",
|
||||||
"Environment :: Web Environment",
|
"Environment :: Web Environment",
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
"Intended Audience :: Customer Service",
|
"Intended Audience :: Customer Service",
|
||||||
@ -165,8 +166,8 @@ setup(
|
|||||||
],
|
],
|
||||||
author="Ross Poulton",
|
author="Ross Poulton",
|
||||||
author_email="ross@rossp.org",
|
author_email="ross@rossp.org",
|
||||||
maintainer="Garret Wassermann",
|
maintainer="Christopher Broderick",
|
||||||
maintainer_email="gwasser@gmail.com",
|
maintainer_email="uhurusurfa@gmail.com",
|
||||||
url="https://github.com/django-helpdesk/django-helpdesk",
|
url="https://github.com/django-helpdesk/django-helpdesk",
|
||||||
license="BSD",
|
license="BSD",
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
|
@ -217,7 +217,6 @@ TIME_ZONE = "UTC"
|
|||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
USE_L10N = True
|
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user