mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-19 05:25:42 +00:00
merge upstream
This commit is contained in:
@ -5,7 +5,7 @@ from django.contrib import admin
|
||||
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
|
||||
from .models import InvenTreeSetting, InvenTreeUserSetting
|
||||
import common.models
|
||||
|
||||
|
||||
class SettingsAdmin(ImportExportModelAdmin):
|
||||
@ -18,5 +18,11 @@ class UserSettingsAdmin(ImportExportModelAdmin):
|
||||
list_display = ('key', 'value', 'user', )
|
||||
|
||||
|
||||
admin.site.register(InvenTreeSetting, SettingsAdmin)
|
||||
admin.site.register(InvenTreeUserSetting, UserSettingsAdmin)
|
||||
class NotificationEntryAdmin(admin.ModelAdmin):
|
||||
|
||||
list_display = ('key', 'uid', 'updated', )
|
||||
|
||||
|
||||
admin.site.register(common.models.InvenTreeSetting, SettingsAdmin)
|
||||
admin.site.register(common.models.InvenTreeUserSetting, UserSettingsAdmin)
|
||||
admin.site.register(common.models.NotificationEntry, NotificationEntryAdmin)
|
||||
|
25
InvenTree/common/migrations/0012_notificationentry.py
Normal file
25
InvenTree/common/migrations/0012_notificationentry.py
Normal file
@ -0,0 +1,25 @@
|
||||
# Generated by Django 3.2.5 on 2021-11-03 13:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0011_auto_20210722_2114'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NotificationEntry',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('key', models.CharField(max_length=250)),
|
||||
('uid', models.IntegerField()),
|
||||
('updated', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('key', 'uid')},
|
||||
},
|
||||
),
|
||||
]
|
@ -9,6 +9,7 @@ from __future__ import unicode_literals
|
||||
import os
|
||||
import decimal
|
||||
import math
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.db import models, transaction
|
||||
from django.contrib.auth.models import User, Group
|
||||
@ -880,8 +881,14 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
|
||||
|
||||
GLOBAL_SETTINGS = {
|
||||
'HOMEPAGE_PART_STARRED': {
|
||||
'name': _('Show starred parts'),
|
||||
'description': _('Show starred parts on the homepage'),
|
||||
'name': _('Show subscribed parts'),
|
||||
'description': _('Show subscribed parts on the homepage'),
|
||||
'default': True,
|
||||
'validator': bool,
|
||||
},
|
||||
'HOMEPAGE_CATEGORY_STARRED': {
|
||||
'name': _('Show subscribed categories'),
|
||||
'description': _('Show subscribed part categories on the homepage'),
|
||||
'default': True,
|
||||
'validator': bool,
|
||||
},
|
||||
@ -1011,6 +1018,13 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
|
||||
'validator': bool,
|
||||
},
|
||||
|
||||
'SEARCH_HIDE_INACTIVE_PARTS': {
|
||||
'name': _("Hide Inactive Parts"),
|
||||
'description': _('Hide inactive parts in search preview window'),
|
||||
'default': False,
|
||||
'validator': bool,
|
||||
},
|
||||
|
||||
'PART_SHOW_QUANTITY_IN_FORMS': {
|
||||
'name': _('Show Quantity in Forms'),
|
||||
'description': _('Display available part quantity in some forms'),
|
||||
@ -1226,3 +1240,63 @@ class ColorTheme(models.Model):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class NotificationEntry(models.Model):
|
||||
"""
|
||||
A NotificationEntry records the last time a particular notifaction was sent out.
|
||||
|
||||
It is recorded to ensure that notifications are not sent out "too often" to users.
|
||||
|
||||
Attributes:
|
||||
- key: A text entry describing the notification e.g. 'part.notify_low_stock'
|
||||
- uid: An (optional) numerical ID for a particular instance
|
||||
- date: The last time this notification was sent
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
unique_together = [
|
||||
('key', 'uid'),
|
||||
]
|
||||
|
||||
key = models.CharField(
|
||||
max_length=250,
|
||||
blank=False,
|
||||
)
|
||||
|
||||
uid = models.IntegerField(
|
||||
)
|
||||
|
||||
updated = models.DateTimeField(
|
||||
auto_now=True,
|
||||
null=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def check_recent(cls, key: str, uid: int, delta: timedelta):
|
||||
"""
|
||||
Test if a particular notification has been sent in the specified time period
|
||||
"""
|
||||
|
||||
since = datetime.now().date() - delta
|
||||
|
||||
entries = cls.objects.filter(
|
||||
key=key,
|
||||
uid=uid,
|
||||
updated__gte=since
|
||||
)
|
||||
|
||||
return entries.exists()
|
||||
|
||||
@classmethod
|
||||
def notify(cls, key: str, uid: int):
|
||||
"""
|
||||
Notify the database that a particular notification has been sent out
|
||||
"""
|
||||
|
||||
entry, created = cls.objects.get_or_create(
|
||||
key=key,
|
||||
uid=uid
|
||||
)
|
||||
|
||||
entry.save()
|
||||
|
29
InvenTree/common/tasks.py
Normal file
29
InvenTree/common/tasks.py
Normal file
@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
from django.core.exceptions import AppRegistryNotReady
|
||||
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
def delete_old_notifications():
|
||||
"""
|
||||
Remove old notifications from the database.
|
||||
|
||||
Anything older than ~3 months is removed
|
||||
"""
|
||||
|
||||
try:
|
||||
from common.models import NotificationEntry
|
||||
except AppRegistryNotReady:
|
||||
logger.info("Could not perform 'delete_old_notifications' - App registry not ready")
|
||||
return
|
||||
|
||||
before = datetime.now() - timedelta(days=90)
|
||||
|
||||
# Delete notification records before the specified date
|
||||
NotificationEntry.objects.filter(updated__lte=before).delete()
|
@ -1,10 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from .models import InvenTreeSetting
|
||||
from .models import NotificationEntry
|
||||
|
||||
|
||||
class SettingsTest(TestCase):
|
||||
@ -85,3 +88,23 @@ class SettingsTest(TestCase):
|
||||
|
||||
if setting.default_value not in [True, False]:
|
||||
raise ValueError(f'Non-boolean default value specified for {key}')
|
||||
|
||||
|
||||
class NotificationTest(TestCase):
|
||||
|
||||
def test_check_notification_entries(self):
|
||||
|
||||
# Create some notification entries
|
||||
|
||||
self.assertEqual(NotificationEntry.objects.count(), 0)
|
||||
|
||||
NotificationEntry.notify('test.notification', 1)
|
||||
|
||||
self.assertEqual(NotificationEntry.objects.count(), 1)
|
||||
|
||||
delta = timedelta(days=1)
|
||||
|
||||
self.assertFalse(NotificationEntry.check_recent('test.notification', 2, delta))
|
||||
self.assertFalse(NotificationEntry.check_recent('test.notification2', 1, delta))
|
||||
|
||||
self.assertTrue(NotificationEntry.check_recent('test.notification', 1, delta))
|
||||
|
Reference in New Issue
Block a user