Compare commits

...

35 Commits

Author SHA1 Message Date
Jon
c6976d88fd chore(api): correct pylint errors
ref: #765
2025-05-19 20:32:43 +09:30
Jon
e7242cf095 chore(api): correct pylint error W0611:unused-import
ref: #765
2025-05-18 07:02:06 +09:30
Jon
ce5e1511ff chore(settings): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:55:52 +09:30
Jon
4851dd109e chore(project_management): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:51:50 +09:30
Jon
b7b4c714bd chore(itim): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:46:10 +09:30
Jon
7137db589b chore(itam): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:35:53 +09:30
Jon
7344b5d140 chore(human_resources): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:14:47 +09:30
Jon
c9a9419663 chore(devops): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:12:45 +09:30
Jon
883260c48d chore(core): correct pylint error W0611:unused-import
ref: #765
2025-05-18 06:07:36 +09:30
Jon
02f15ecbba chore(config_management): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:50:32 +09:30
Jon
67b9a5e70d chore(centurion_feature_flag): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:48:45 +09:30
Jon
69d915079b chore(base): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:47:15 +09:30
Jon
d5b3883195 chore(assistance): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:44:44 +09:30
Jon
af4abacd53 chore(api): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:42:23 +09:30
Jon
cbd931f31a chore(accounting): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:39:50 +09:30
Jon
b9ad6c884e chore(access): correct pylint error W0611:unused-import
ref: #765
2025-05-18 05:38:33 +09:30
Jon
88264f8f10 chore(core): remove old manual migration no longer required
ref: #765
2025-05-18 05:36:59 +09:30
Jon
af0d2043ac chore(access): planning work for centurion user model, audit history and tanancy model
ref: #765 #766
2025-05-18 04:36:52 +09:30
Jon
48977aa8e1 chore(core): skeleton test cases
ref: #765 #759
2025-05-18 04:32:06 +09:30
Jon
7d2f74ce00 chore(access): planning work for centurion user model
ref: #765 #766
2025-05-18 04:20:41 +09:30
Jon
65a3effd49 refactor(access): prefetch org with tenancy object
ref: #765
2025-05-18 04:16:50 +09:30
Jon
7dcdab2e8c feat(core): permissions getter for role model
ref: #765 #551
2025-05-18 04:08:47 +09:30
Jon
46ed30a07d chore(core): skeleton test cases
ref: #765 #759
2025-05-18 04:06:12 +09:30
Jon
820da54969 feat(core): Audit History Signal for Delete/Save
ref: #765 #759
2025-05-18 04:00:53 +09:30
Jon
ef82c40555 refactor(access): Rename History models
ref: #765 #759
2025-05-18 03:38:58 +09:30
Jon
41ec865618 refactor(settings): Rename History models
ref: #765 #759
2025-05-18 03:38:21 +09:30
Jon
98b392d4a2 refactor(project_management): Rename History models
ref: #765 #759
2025-05-18 03:06:43 +09:30
Jon
4b2e55187c refactor(devops): Rename History models
ref: #765 #759
2025-05-18 02:32:08 +09:30
Jon
0894e78f9d refactor(core): Rename History models
ref: #765 #759
2025-05-18 02:26:11 +09:30
Jon
a9e16404ad refactor(accounting): Rename History models
ref: #765 #759
2025-05-18 01:37:55 +09:30
Jon
eceb220597 refactor(assistance): Rename History models
ref: #765 #759
2025-05-18 01:23:59 +09:30
Jon
7786c3844a refactor(itim): Rename History models
ref: #765 #759
2025-05-18 01:09:06 +09:30
Jon
648a414f0e feat(core): Dynamic History model creation
ref: #765 #758 #759
2025-05-17 21:06:52 +09:30
Jon
5cc08e3e94 refactor(core): Relocate history model class
ref: #765 #759
2025-05-17 04:24:11 +09:30
Jon
603d7a4b7b refactor(base): rename app to centurion
ref: #764
2025-05-16 22:10:38 +09:30
500 changed files with 2291 additions and 1147 deletions

View File

@ -1,6 +1,5 @@
from django.db import models
from django.utils.timezone import now
from django.template.defaultfilters import slugify
class AutoCreatedField(models.DateTimeField):
"""

View File

@ -1,7 +1,7 @@
from django import forms
from django.db.models import Q
from app import settings
from django.conf import settings
from access.models.tenant import Tenant as Organization

View File

@ -7,7 +7,7 @@ from .team_users import TeamUsersForm, TeamUsers
from access.models.team import Team
from access.functions import permissions
from app import settings
from django.conf import settings
from core.forms.common import CommonModelForm

View File

@ -1,6 +1,6 @@
from django.db.models import Q
from app import settings
from django.conf import settings
from access.models.team_user import TeamUsers

View File

@ -1,10 +1,5 @@
import django
from django.contrib.auth.middleware import (
AuthenticationMiddleware,
SimpleLazyObject,
partial,
)
from django.contrib.auth.models import Group
from django.utils.deprecation import MiddlewareMixin

View File

@ -0,0 +1,30 @@
# Generated by Django 5.1.9 on 2025-05-17 17:50
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('access', '0010_company_alter_entity_entity_type_alter_person_dob_and_more'),
('core', '0026_rename_manufacturerhistory_manufactureraudithistory'),
]
operations = [
migrations.RenameModel(
old_name='EntityHistory',
new_name='EntityAuditHistory',
),
migrations.RenameModel(
old_name='OrganizationHistory',
new_name='OrganizationAuditHistory',
),
migrations.RenameModel(
old_name='RoleHistory',
new_name='RoleAuditHistory',
),
migrations.RenameModel(
old_name='TeamHistory',
new_name='TeamAuditHistory',
),
]

View File

@ -1,5 +1,5 @@
from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin
from django.contrib.auth.mixins import AccessMixin
from django.contrib.auth.models import Group
from django.core.exceptions import PermissionDenied
from django.utils.functional import cached_property

View File

@ -1,10 +1,8 @@
import django
from django.contrib.auth.models import Group
from django.db import models
from access.models.tenant import Tenant as Organization
from access.models.team import Team
User = django.contrib.auth.get_user_model()

View File

@ -1,8 +1,5 @@
import traceback
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import exceptions
from rest_framework.permissions import DjangoObjectPermissions
from access.models.tenancy import Tenant, TenancyObject

View File

@ -1,4 +1,4 @@
from . import contact
from . import company_base
from . import person
from . import role
from . import contact # pylint: disable=W0611:unused-import
from . import company_base # pylint: disable=W0611:unused-import
from . import person # pylint: disable=W0611:unused-import
from . import role # pylint: disable=W0611:unused-import

View File

@ -5,8 +5,6 @@ from rest_framework.reverse import reverse
from access.fields import AutoCreatedField, AutoLastModifiedField
from access.models.tenancy import TenancyObject
from core.lib.feature_not_used import FeatureNotUsed
class Entity(
@ -107,7 +105,6 @@ class Entity(
):
return related_object.name
break
return ''
@ -238,12 +235,12 @@ class Entity(
def save_history(self, before: dict, after: dict) -> bool:
from access.models.entity_history import EntityHistory
from access.models.entity_history import EntityAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = EntityHistory
history_model = EntityAuditHistory
)
return history

View File

@ -4,11 +4,9 @@ from access.models.entity import Entity
from core.models.model_history import ModelHistory
from devops.models.feature_flag import FeatureFlag
class EntityHistory(
class EntityAuditHistory(
ModelHistory
):

View File

@ -1 +1 @@
from .tenant import Tenant as Organization
from .tenant import Tenant as Organization # pylint: disable=W0611:unused-import

View File

@ -6,7 +6,7 @@ from access.models.tenant import Tenant
class OrganizationHistory(
class OrganizationAuditHistory(
ModelHistory
):

View File

@ -130,14 +130,45 @@ class Role(
]
_permissions: list[ Permission ] = None
_permissions_int: list[ int ] = None
def get_permissions(self, as_int_list = False ):
if self._permissions is None:
permissions = []
permissions_int = []
for permission in self.permissions:
if permission in _permissions:
continue
permissions += [ permission ]
permissions_int += [ permission.id ]
self._permissions = permissions
self._permissions_int = permissions_int
if as_int_list:
return self._permissions_int
return self._permissions_int
def save_history(self, before: dict, after: dict) -> bool:
from access.models.role_history import RoleHistory
from access.models.role_history import RoleAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = RoleHistory
history_model = RoleAuditHistory
)
return history

View File

@ -6,7 +6,7 @@ from access.models.role import Role
class RoleHistory(
class RoleAuditHistory(
ModelHistory
):

View File

@ -179,12 +179,12 @@ class Team(Group, TenancyObject):
def save_history(self, before: dict, after: dict) -> bool:
from access.models.team_history import TeamHistory
from access.models.team_history import TeamAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = TeamHistory
history_model = TeamAuditHistory
)

View File

@ -6,7 +6,7 @@ from access.models.team import Team
class TeamHistory(
class TeamAuditHistory(
ModelHistory
):

View File

@ -1,4 +1,3 @@
import django
import logging
from django.db import models
@ -52,6 +51,10 @@ class TenancyManager(models.Manager):
user_organizations: list(str()) = []
has_tenant_field = False
if hasattr(self.model, 'organization'):
has_tenant_field = True
if request:
@ -70,19 +73,20 @@ class TenancyManager(models.Manager):
if team.organization.id not in user_organizations:
if not user_organizations:
# if not user_organizations:
self.user_organizations = []
# self.user_organizations = []
user_organizations += [ team.organization.id ]
# if len(user_organizations) > 0 and not user.is_superuser and self.model.is_global is not None:
if len(user_organizations) > 0 and not user.is_superuser:
if getattr(self.model, 'is_global', False) is True:
return super().get_queryset().filter(
if has_tenant_field:
return super().get_queryset().select_related('organization').filter(
models.Q(organization__in=user_organizations)
|
models.Q(is_global = True)
@ -92,9 +96,30 @@ class TenancyManager(models.Manager):
return super().get_queryset().filter(
models.Q(organization__in=user_organizations)
|
models.Q(is_global = True)
)
return super().get_queryset()
else:
if has_tenant_field:
return super().get_queryset().select_related('organization').filter(
models.Q(organization__in=user_organizations)
)
else:
return super().get_queryset().filter(
models.Q(organization__in=user_organizations)
)
if has_tenant_field:
return super().get_queryset().select_related('organization')
else:
return super().get_queryset().select_related('organization')
@ -286,7 +311,7 @@ class TenancyObject(SaveHistory):
if(
not getattr(self, 'organization', None)
and self._meta.model_name !='appsettingshistory' # App Settings for
and self._meta.model_name !='appsettingsaudithistory' # App Settings for
):
raise centurion_exceptions.ValidationError(

View File

@ -0,0 +1,247 @@
# import django
import logging
from django.core.exceptions import (
ValidationError,
)
from django.db import models
# from rest_framework.reverse import reverse
from access.models.tenant import Tenant
# from core import exceptions as centurion_exceptions
# from core.mixin.history_save import SaveHistory
class TenancyManager(
models.Manager
):
"""Multi-Tennant Object Manager
This manager specifically caters for the multi-tenancy features of Centurion ERP.
"""
def get_queryset(self):
""" Fetch the data
When the model contains the user data, the query is filtered to their
and the globally defined Tenancy only.
Returns:
(queryset): **super user**: return unfiltered data.
(queryset): **not super user**: return data from the stored unique organizations.
"""
# user = None # When CenturionUser in use
# if hasattr(self.model, 'context'):
# user = self.model.context['user']
# if user:
# tencies = user.get_tenancies(int_list = True)
# if len(tenancies) > 0 and not request.user.is_superuser:
# if hasattr(self.model, 'organization'):
# return super().get_queryset().select_related('organization').filter(
# models.Q(organization__in = tenancies)
# )
# return super().get_queryset().select_related('organization').filter(
# models.Q(organization__in = tenancies)
# )
request = None
if hasattr(self.model, 'context'):
request = self.model.context['request']
if request is not None:
tenancies: list(str()) = []
if request.app_settings.global_organization:
tenancies += [ request.app_settings.global_organization.id ]
if request.user.is_authenticated:
for team in request.tenancy._user_teams:
if team.organization.id in tenancies:
continue
tenancies += [ team.organization.id ]
if len(tenancies) > 0 and not request.user.is_superuser:
if hasattr(self.model, 'organization'):
return super().get_queryset().select_related('organization').filter(
models.Q(organization__in = tenancies)
)
return super().get_queryset().select_related('organization').filter(
models.Q(organization__in = tenancies)
)
return super().get_queryset().select_related('organization')
class TenancyObjectOld:
kb_model_name: str = None
"""Model name to use for KB article linking
This value is derived from `<model>._meta.model_name`. This value should
only be used when there is model inheritence.
"""
_log: logging.Logger = None
def get_log(self):
if self._log is None:
self._log = logging.getLogger('centurion.' + self._meta.app_label)
return self._log
page_layout: list = None
note_basename: str = None
"""URL BaseName for the notes endpoint.
Don't specify the `app_namespace`, use property `app_namespace` above.
"""
def get_page_layout(self):
""" FEtch the page layout"""
return self.page_layout
def get_app_namespace(self) -> str:
"""Fetch the Application namespace if specified.
Returns:
str: Application namespace suffixed with colin `:`
None: No application namespace found.
"""
app_namespace = ''
if self.app_namespace:
app_namespace = self.app_namespace + ':'
return str(app_namespace)
def get_url_kwargs_notes(self) -> dict:
"""Fetch the URL kwargs for model notes
Returns:
dict: notes kwargs required for generating the URL with `reverse`
"""
return {
'model_id': self.id
}
class TenancyAbstractModel(
# TenancyObjectOld,
# models.Model,
):
""" Tenancy Model Abstract class.
This class is for inclusion within **every** model within Centurion ERP.
Provides the required fields, functions and methods for multi tennant objects.
Unless otherwise stated, **no** object within this class may be overridden.
Raises:
ValidationError: User failed to supply organization
"""
objects = TenancyManager()
""" Multi-Tenanant Objects """
class Meta:
abstract = True
def validatate_organization_exists(self):
"""Ensure that the user did provide an organization
Raises:
ValidationError: User failed to supply organization.
"""
if not self:
raise ValidationError(
code = 'required',
message = 'You must provide an organization'
)
id = models.AutoField(
blank=False,
help_text = 'ID of the item',
primary_key=True,
unique=True,
verbose_name = 'ID'
)
organization = models.ForeignKey(
Tenant,
blank = False,
help_text = 'Tenant this belongs to',
null = False,
on_delete = models.CASCADE,
related_name = '+',
validators = [
validatate_organization_exists
],
verbose_name = 'Tenant'
)
is_global = models.BooleanField(
blank = False,
default = False,
help_text = 'Is this a global object?',
null = False,
verbose_name = 'Global Object'
)
model_notes = models.TextField(
blank = True,
default = None, # ToDo: Remove this field
help_text = 'Tid bits of information',
null = True,
verbose_name = 'Notes',
)
def get_tenant(self) -> Tenant:
""" Return the models Tenancy
This model can be safely over-ridden as long as it returns the models
tenancy
"""
return self.organization

View File

@ -145,12 +145,12 @@ class Tenant(SaveHistory):
def save_history(self, before: dict, after: dict) -> bool:
from access.models.organization_history import OrganizationHistory
from access.models.organization_history import OrganizationAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = OrganizationHistory
history_model = OrganizationAuditHistory
)

View File

@ -0,0 +1,195 @@
from django.contrib.auth.models import Permission, User
from django.core.exceptions import PermissionDenied
from access.models.tenant import Tenant
class CenturionUser(
User,
):
"""Centurion User
A Multi-Tenant User wirh permission Checking.
ToDo:
- Add to Roles user field `related_name = roles`
- Add to Roles group field `related_name = roles`
# - have group lookup prefetch related roles__permissions
- have user lookup prefetch related roles__permissions and groups__roles__permissions
Args:
User (Model): Django Base User
"""
_tenancies: list[Tenant] = None
_tenancies_int: list[int] = None
_permissions: list[Permission] = None
_permissions_by_tenancy: dict[ str, list[ Permission ] ] = None
"""Permissions by Tenancy
`{ 'tenancy_{id}': [ Permission ] }`
"""
# EMAIL_FIELD = 'email' # Update contact email field name so it's different to the user model.
# REQUIRED_FIELDS = [
# EMAIL_FIELD,
# 'f_name',
# 'l_name',
# ]
class Meta:
abstract = False
proxy = True # User will be linked to Employee/Customer entity via related_name from the entity.
# ToDo: refactory Employee/Customer to inherit from a new model. entity_user
verbose_name = 'Centurion User'
verbose_name_plural = 'Centurion Users'
def get_full_name(self) -> str:
return f'{self.entity_user.f_name} {self.entity_user.l_name}'
def get_group_permissions(self, tenancy: bool = True) -> dict[ str, list[ Permission ] ] | list[ Permission ]:
""" Get the Users Permissions
Args:
tenancy (bool, optional): Return permission in list. Defaults to True.
Returns:
dict[ str, list[ Permission ] ]: Permissions listed by tenancy
list[ Permission ]: All Permissions
"""
for group in self.groups:
for role in group.roles:
pass
# role.get_permissions()
def get_permissions(self, tenancy: bool = True) -> dict[ str, list[ Permission ] ] | list[ Permission ]:
""" Get the Users Permissions
Args:
tenancy (bool, optional): Return permission in list. Defaults to True.
Returns:
dict[ str, list[ Permission ] ]: Permissions listed by tenancy
list[ Permission ]: All Permissions
"""
# also get group permissions. self.get_group_permissions()
for role in self.roles:
pass
# role.get_permissions()
# also populate `self._tenancies` and `self._tenancies_int`
def get_short_name() -> str:
return self.entity_user.f_name
def get_tenancies(self, int_list = False) -> list[ Tenant ] | list[ int ]:
"""Get the Tenancies the user is in.
Args:
int_list (bool, optional): Return Tenancy list as int values. Defaults to False.
Returns:
list[ Tenant ] | list[ int ]: All Tenancies the user is in.
"""
if self._tenancies is None:
if self._permissions is None:
self.get_permissions
tenancies: list = []
tenancies_int: list = []
for role in self.roles:
if role.organization in tenancies:
continue
tenancies += [ role.organization ]
tenancies_int += [ role.organization.id ]
self._tenancies = tenancies
self._tenancies_int = tenancies_int
if as_int_list:
return self._tenancies_int
return self._tenancies
def has_module_perms(self, app_label): # is this needed?
# if has app_label in perms
raise PermissionDenied
def has_perm(self, permission: Permission, obj = None, tenancy: Tenant = None) -> bool:
if(
obj is None
and tenancy is None
):
raise ValueError('Both obj and tenancy cant be None')
if tenancy is None:
tenancy = obj.organization
# if self.has_tenancy_permission(perm, tenancy):
# for tenancy, permissions in self.get_permissions().items()
if tenancy is None:
raise ValueError('tenancy cant be None')
permissions = self.get_permissions()
if f'tenancy_{tenancy.id}' not in permissions:
raise PermissionDenied
for tenancy, permissions in self.get_permissions().items():
if(
tenancy == f'tenancy_{tenancy.id}'
and perm in permissions
):
return True
raise PermissionDenied
def has_perms(self, permission_list: list[ Permission ], obj = None, tenancy: Tenant = None):
for perm in perm_list:
self.has_perm( perm, obj )
return True

View File

@ -4,7 +4,7 @@ from rest_framework import serializers
from access.models.tenant import Tenant
from app.serializers.user import UserBaseSerializer
from centurion.serializers.user import UserBaseSerializer
from core import fields as centurion_field

View File

@ -1,13 +1,6 @@
from rest_framework import serializers
from access.models.organization_notes import OrganizationNotes
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from core.serializers.model_notes import (
ModelNotes,
ModelNoteBaseSerializer,
ModelNoteModelSerializer,
ModelNoteViewSerializer

View File

@ -9,7 +9,7 @@ from access.serializers.organization import TenantBaseSerializer
from api.serializers import common
from app.serializers.permission import PermissionBaseSerializer
from centurion.serializers.permission import PermissionBaseSerializer

View File

@ -1,13 +1,6 @@
from rest_framework import serializers
from access.models.role_notes import RoleNotes
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from core.serializers.model_notes import (
ModelNotes,
ModelNoteBaseSerializer,
ModelNoteModelSerializer,
ModelNoteViewSerializer

View File

@ -1,13 +1,6 @@
from rest_framework import serializers
from access.models.team_notes import TeamNotes
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from core.serializers.model_notes import (
ModelNotes,
ModelNoteBaseSerializer,
ModelNoteModelSerializer,
ModelNoteViewSerializer

View File

@ -1,12 +1,10 @@
from rest_framework.reverse import reverse
from rest_framework import serializers
from access.models.team_user import TeamUsers
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from centurion.serializers.user import UserBaseSerializer

View File

@ -9,7 +9,7 @@ from api.serializers import common
from access.functions.permissions import permission_queryset
from access.serializers.organization import TenantBaseSerializer
from app.serializers.permission import Permission, PermissionBaseSerializer
from centurion.serializers.permission import PermissionBaseSerializer
from core import fields as centurion_field

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from access.models.entity_history import Entity, EntityHistory
from access.models.entity_history import Entity, EntityAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -12,7 +12,7 @@ class HistoryTestCases(
field_name = 'model_notes'
history_model = EntityHistory
history_model = EntityAuditHistory
kwargs_create_obj: dict = {}
@ -43,7 +43,7 @@ class HistoryTestCases(
class EntityHistoryInheritedCases(
class EntityAuditHistoryInheritedCases(
HistoryTestCases,
):
@ -70,7 +70,7 @@ class EntityHistoryInheritedCases(
class EntityHistoryTest(
class EntityAuditHistoryTest(
HistoryTestCases,
TestCase,
):

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from access.models.organization_history import Tenant as Organization, OrganizationHistory
from access.models.organization_history import Tenant as Organization, OrganizationAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -13,7 +13,7 @@ class History(
model = Organization
history_model = OrganizationHistory
history_model = OrganizationAuditHistory
@classmethod

View File

@ -2,13 +2,13 @@ from django.test import TestCase
from access.models.person import Person
from access.tests.functional.entity.test_functional_entity_history import (
EntityHistoryInheritedCases
EntityAuditHistoryInheritedCases
)
class PersonTestCases(
EntityHistoryInheritedCases,
EntityAuditHistoryInheritedCases,
):
field_name = 'model_notes'

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from access.models.role_history import Role, RoleHistory
from access.models.role_history import Role, RoleAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -10,7 +10,7 @@ class HistoryTestCases(
HistoryEntriesCommon,
):
history_model = RoleHistory
history_model = RoleAuditHistory
kwargs_create_obj: dict = {}
@ -41,7 +41,7 @@ class HistoryTestCases(
class RoleHistoryTest(
class RoleAuditHistoryTest(
HistoryTestCases,
TestCase,
):

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from access.models.team_history import Team, TeamHistory
from access.models.team_history import Team, TeamAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -13,7 +13,7 @@ class History(
model = Team
history_model = TeamHistory
history_model = TeamAuditHistory
@classmethod

View File

@ -1,7 +1,7 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from access.models.entity_history import Entity, EntityHistory
from access.models.entity_history import Entity, EntityAuditHistory
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
@ -20,7 +20,7 @@ class ModelHistoryAPITestCases(
kwargs_create_audit_object: dict = {}
model = EntityHistory
model = EntityAuditHistory
@classmethod
def setUpTestData(self):

View File

@ -4,7 +4,7 @@ from django.db import models
from access.models.entity import Entity
from app.tests.unit.test_unit_models import (
from centurion.tests.unit.test_unit_models import (
PyTestTenancyObjectInheritedCases,
)

View File

@ -15,7 +15,7 @@ from access.models.team import Team
from access.models.team_user import TeamUsers
from access.tests.abstract.model_permissions_organization_manager import OrganizationManagerModelPermissionChange, OrganizationManagerModelPermissionView
from app.tests.abstract.model_permissions import ModelPermissionsView, ModelPermissionsChange
from centurion.tests.abstract.model_permissions import ModelPermissionsView, ModelPermissionsChange
User = django.contrib.auth.get_user_model()

View File

@ -4,7 +4,7 @@ import requests
from django.test import TestCase
from app.tests.abstract.models import ModelDisplay, ModelIndex
from centurion.tests.abstract.models import ModelDisplay, ModelIndex

View File

@ -3,7 +3,7 @@ from django.test import TestCase
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
from access.models.organization_history import Tenant as Organization, OrganizationHistory
from access.models.organization_history import Tenant as Organization, OrganizationAuditHistory
@ -14,7 +14,7 @@ class ModelHistoryAPI(
audit_model = Organization
model = OrganizationHistory
model = OrganizationAuditHistory
@classmethod
def setUpTestData(self):

View File

@ -1,7 +1,7 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from access.models.role_history import Role, RoleHistory
from access.models.role_history import Role, RoleAuditHistory
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
@ -51,7 +51,7 @@ class ModelHistoryAPITestCases(
class RoleHistoryAPITest(
class RoleAuditHistoryAPITest(
ModelHistoryAPITestCases,
TestCase,
):
@ -60,7 +60,7 @@ class RoleHistoryAPITest(
kwargs_create_audit_object: dict = {}
model = RoleHistory
model = RoleAuditHistory
@classmethod
def setUpTestData(self):

View File

@ -2,7 +2,7 @@ from django.test import TestCase
from access.models.role import Role
from app.tests.unit.test_unit_models import (
from centurion.tests.unit.test_unit_models import (
TenancyObjectInheritedCases
)

View File

@ -14,7 +14,7 @@ from access.models.team import Team
from access.models.team_user import TeamUsers
from access.tests.abstract.model_permissions_organization_manager import OrganizationManagerModelPermissions
from app.tests.abstract.model_permissions import ModelPermissions
from centurion.tests.abstract.model_permissions import ModelPermissions
User = django.contrib.auth.get_user_model()

View File

@ -4,7 +4,7 @@ import requests
from django.test import TestCase
from app.tests.abstract.models import ModelAdd, ModelDelete, ModelDisplay
from centurion.tests.abstract.models import ModelAdd, ModelDelete, ModelDisplay

View File

@ -3,7 +3,7 @@ from django.test import TestCase
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
from access.models.team_history import Team, TeamHistory
from access.models.team_history import Team, TeamAuditHistory
@ -14,7 +14,7 @@ class ModelHistoryAPI(
audit_model = Team
model = TeamHistory
model = TeamAuditHistory
@classmethod
def setUpTestData(self):

View File

@ -4,7 +4,7 @@ from django.test import TestCase
from access.models.team import Team
from app.tests.unit.test_unit_models import (
from centurion.tests.unit.test_unit_models import (
TenancyObjectInheritedCases
)

View File

@ -15,7 +15,7 @@ from access.models.team_user import TeamUsers
from access.tests.abstract.model_permissions_organization_manager import OrganizationManagerModelPermissionAdd, OrganizationManagerModelPermissionDelete
from app.tests.abstract.model_permissions import ModelPermissionsAdd, ModelPermissionsChange, ModelPermissionsDelete
from centurion.tests.abstract.model_permissions import ModelPermissionsAdd, ModelPermissionsChange, ModelPermissionsDelete
User = django.contrib.auth.get_user_model()

View File

@ -4,7 +4,7 @@ import requests
from django.test import TestCase
from app.tests.abstract.models import AddView, DeleteView
from centurion.tests.abstract.models import AddView, DeleteView

View File

@ -5,7 +5,7 @@ from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from app.tests.unit.test_unit_models import NonTenancyObjectInheritedCases
from centurion.tests.unit.test_unit_models import NonTenancyObjectInheritedCases
User = django.contrib.auth.get_user_model()

View File

@ -617,7 +617,7 @@ class TenancyObjectInheritedCases(
"""Test Cases for models that inherit from
**Note:** dont use these test cases use
`app.tests.unit.test_unit_models.TenancyObjectInheritedCases` instead
`centurion.tests.unit.test_unit_models.TenancyObjectInheritedCases` instead
access.models.tenancy.TenancyObject"""

View File

@ -1,6 +1,5 @@
from django.urls import path
from . import views
from .views import team, organization, user
app_name = "Access"

View File

@ -13,7 +13,7 @@ from drf_spectacular.utils import (
from rest_framework.reverse import reverse
# THis import only exists so that the migrations can be created
from access.models.entity_history import EntityHistory # pylint: disable=W0611:unused-import
from access.models.entity_history import EntityAuditHistory # pylint: disable=W0611:unused-import
from access.models.entity import (
Entity,
)

View File

@ -1,8 +1,8 @@
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse
# THis import only exists so that the migrations can be created
from access.models.organization_history import OrganizationHistory # pylint: disable=W0611:unused-import
from access.serializers.organization import (
from access.models.organization_history import OrganizationAuditHistory # pylint: disable=W0611:unused-import
from access.serializers.organization import ( # pylint: disable=W0611:unused-import
Tenant,
TenantModelSerializer,
TenantViewSerializer

View File

@ -1,7 +1,7 @@
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse
# THis import only exists so that the migrations can be created
from access.models.role_history import RoleHistory # pylint: disable=W0611:unused-import
from access.models.role_history import RoleAuditHistory # pylint: disable=W0611:unused-import
from access.serializers.role import (
Role,
ModelSerializer,

View File

@ -2,8 +2,8 @@ from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiPara
from access.models.tenant import Tenant as Organization
# THis import only exists so that the migrations can be created
from access.models.team_history import TeamHistory # pylint: disable=W0611:unused-import
from access.serializers.teams import (
from access.models.team_history import TeamAuditHistory # pylint: disable=W0611:unused-import
from access.serializers.teams import ( # pylint: disable=W0611:unused-import
Team,
TeamModelSerializer,
TeamViewSerializer

View File

@ -2,7 +2,7 @@ from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiPara
from access.models.team import Team
from access.serializers.team_user import (
from access.serializers.team_user import ( # pylint: disable=W0611:unused-import
TeamUsers,
TeamUserModelSerializer,
TeamUserViewSerializer

View File

@ -0,0 +1,18 @@
# Generated by Django 5.1.9 on 2025-05-17 13:24
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounting', '0001_initial'),
('core', '0025_alter_modelhistory_action_alter_modelhistory_after_and_more'),
]
operations = [
migrations.RenameModel(
old_name='AssetBaseHistory',
new_name='AssetBaseAuditHistory',
),
]

View File

@ -1 +1 @@
from .asset_base_history import AssetBaseHistory
from .asset_base_history import AssetBaseAuditHistory # pylint: disable=W0611:unused-import

View File

@ -6,8 +6,6 @@ from rest_framework.reverse import reverse
from access.fields import AutoCreatedField, AutoLastModifiedField
from access.models.tenancy import TenancyObject
from core.lib.feature_not_used import FeatureNotUsed
class AssetBase(
@ -257,7 +255,6 @@ class AssetBase(
):
return related_object.name
break
return ''
@ -356,12 +353,12 @@ class AssetBase(
def save_history(self, before: dict, after: dict) -> bool:
from accounting.models.asset_base_history import AssetBaseHistory
from accounting.models.asset_base_history import AssetBaseAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = AssetBaseHistory
history_model = AssetBaseAuditHistory
)

View File

@ -6,7 +6,7 @@ from core.models.model_history import ModelHistory
class AssetBaseHistory(
class AssetBaseAuditHistory(
ModelHistory
):

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from accounting.models.asset_base_history import AssetBase, AssetBaseHistory
from accounting.models.asset_base_history import AssetBase, AssetBaseAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -13,7 +13,7 @@ class History(
model = AssetBase
history_model = AssetBaseHistory
history_model = AssetBaseAuditHistory
@classmethod

View File

@ -4,7 +4,7 @@ from django.db import models
from accounting.models.asset_base import AssetBase
from app.tests.unit.test_unit_models import (
from centurion.tests.unit.test_unit_models import (
PyTestTenancyObjectInheritedCases,
)

View File

@ -3,7 +3,7 @@ from django import forms
from api.models.tokens import AuthToken
from app import settings
from django.conf import settings
from core.forms.common import CommonModelForm

View File

@ -1 +1 @@
from . import tokens
from . import tokens # pylint: disable=W0611:unused-import

View File

@ -35,7 +35,7 @@ class AuthToken(models.Model):
def validate_note_no_token(self, note, token, raise_exception = True) -> bool:
""" Ensure plaintext token cant be saved to notes field.
called from app.settings.views.user_settings.TokenAdd.form_valid()
called from centurion.settings.views.user_settings.TokenAdd.form_valid()
Args:
note (Field): _Note field_

View File

@ -3,11 +3,8 @@ import re
from django.conf import settings
from django.utils.encoding import force_str
from django.contrib.auth.models import ContentType, Permission
from rest_framework import serializers
from rest_framework_json_api.metadata import JSONAPIMetadata
from rest_framework.request import clone_request
from rest_framework.reverse import reverse
from rest_framework.utils.field_mapping import ClassLookupDict
@ -15,7 +12,7 @@ from rest_framework_json_api.utils import get_related_resource_type
from access.models.tenant import Tenant
from app.serializers.user import User, UserBaseSerializer
from centurion.serializers.user import User, UserBaseSerializer
from core import fields as centurion_field
from core.fields.badge import BadgeField

View File

@ -1,4 +1,4 @@
from rest_framework import serializers, request
from rest_framework import serializers
from rest_framework.reverse import reverse
from access.models.tenant import Tenant as Organization

View File

@ -4,8 +4,6 @@ from rest_framework.reverse import reverse
from access.serializers.organization import Tenant
from assistance.models.model_knowledge_base_article import all_models
from core import fields as centurion_field
from core.lib.feature_not_used import FeatureNotUsed
@ -65,7 +63,7 @@ class CommonModelSerializer(CommonBaseSerializer):
}
kb_model_name = self.Meta.model._meta.model_name
if getattr(item, 'kb_model_name'):
if getattr(item, 'kb_model_name', None):
kb_model_name = item.kb_model_name
@ -82,17 +80,22 @@ class CommonModelSerializer(CommonBaseSerializer):
if getattr(self.Meta.model, 'save_model_history', True):
history_app_label = self.Meta.model._meta.app_label
if getattr(item, 'history_app_label'):
if getattr(item, 'history_app_label', None):
history_app_label = item.history_app_label
history_model_name = self.Meta.model._meta.model_name
if getattr(item, 'history_model_name'):
if getattr(item, 'history_model_name', None):
history_model_name = item.history_model_name
if(
history_app_label is not None
and history_model_name is not None
):
get_url['history'] = reverse(
"v2:_api_v2_model_history-list",
request = self._context['view'].request,
@ -123,7 +126,7 @@ class CommonModelSerializer(CommonBaseSerializer):
note_basename = app_namespace + '_api_v2_' + str(item._meta.verbose_name).lower().replace(' ', '_') + '_note'
if getattr(item, 'note_basename'):
if getattr(item, 'note_basename', None):
note_basename = app_namespace + item.note_basename
@ -131,6 +134,8 @@ class CommonModelSerializer(CommonBaseSerializer):
note_basename = self.Meta.note_basename
if getattr(item, 'get_url_kwargs_notes', None):
get_url['notes'] = reverse(
"v2:" + note_basename + "-list",
request = self._context['view'].request,

View File

@ -3,8 +3,6 @@ from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty
from api.serializers.core.ticket_comment import TicketCommentSerializer
from core import exceptions as centurion_exception
from core.forms.validate_ticket import TicketValidation
from core.models.ticket.ticket import Ticket

View File

@ -1,11 +1,6 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty
from api.serializers.core.ticket_comment import TicketCommentSerializer
from core.forms.validate_ticket import TicketValidation
from core.models.ticket.ticket_category import TicketCategory

View File

@ -1,5 +1,3 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty

View File

@ -2,8 +2,6 @@ from django.urls import reverse
from rest_framework import serializers
from api.serializers.config import ParentGroupSerializer
from config_management.models.groups import ConfigGroups
from itam.models.device import Device

View File

@ -1,6 +1,3 @@
from django.urls import reverse
from itam.models.device import Device
from rest_framework import serializers

View File

@ -1,5 +1,3 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty

View File

@ -1,5 +1,3 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty

View File

@ -1,7 +1,6 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework.fields import empty
from project_management.models.projects import Project

View File

@ -8,7 +8,7 @@ from access.models.tenant import Tenant as Organization
from api.serializers.auth_token import AuthToken, AuthTokenModelSerializer
from app.tests.abstract.mock_view import MockView, User
from centurion.tests.abstract.mock_view import MockView, User
# from core.serializers.manufacturer import Manufacturer, ManufacturerModelSerializer

View File

@ -11,7 +11,7 @@ from rest_framework.relations import Hyperlink
from access.models.team import Team
from access.models.team_user import TeamUsers
from app.tests.common import DoesNotExist
from centurion.tests.common import DoesNotExist
User = django.contrib.auth.get_user_model()

View File

@ -10,7 +10,7 @@ from api.viewsets import (
index as v2
)
from app.viewsets.base import (
from centurion.viewsets.base import (
index as base_index_v2,
content_type as content_type_v2,
permisson as permission_v2,

View File

@ -12,7 +12,6 @@ from rest_framework.response import Response
from access.mixins.organization import OrganizationMixin
from access.mixins.permissions import OrganizationPermissionMixin
from api.auth import TokenScheme
from api.react_ui_metadata import ReactUIMetadata

View File

@ -3,7 +3,7 @@ from django import forms
from django.urls import reverse
from django.forms import ValidationError
from app import settings
from django.conf import settings
from assistance.models.knowledge_base import KnowledgeBase

View File

@ -0,0 +1,22 @@
# Generated by Django 5.1.9 on 2025-05-17 13:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assistance', '0006_alter_knowledgebase_organization_and_more'),
('core', '0025_alter_modelhistory_action_alter_modelhistory_after_and_more'),
]
operations = [
migrations.RenameModel(
old_name='KnowledgeBaseHistory',
new_name='KnowledgeBaseAuditHistory',
),
migrations.RenameModel(
old_name='KnowledgeBaseCategoryHistory',
new_name='KnowledgeBaseCategoryAuditHistory',
),
]

View File

@ -1,2 +1,2 @@
from .knowledge_base_history import KnowledgeBaseHistory # pylint: disable=W0611:unused-import
from .knowledge_base_category_history import KnowledgeBaseCategoryHistory # pylint: disable=W0611:unused-import
from .knowledge_base_history import KnowledgeBaseAuditHistory # pylint: disable=W0611:unused-import
from .knowledge_base_category_history import KnowledgeBaseCategoryAuditHistory # pylint: disable=W0611:unused-import

View File

@ -1,6 +1,5 @@
import django
from django.db import models
from django.forms import ValidationError
from access.fields import *
from access.models.team import Team
@ -113,12 +112,12 @@ class KnowledgeBaseCategory(TenancyObject):
def save_history(self, before: dict, after: dict) -> bool:
from assistance.models.knowledge_base_category_history import KnowledgeBaseCategoryHistory
from assistance.models.knowledge_base_category_history import KnowledgeBaseCategoryAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = KnowledgeBaseCategoryHistory,
history_model = KnowledgeBaseCategoryAuditHistory,
)
@ -334,12 +333,12 @@ class KnowledgeBase(TenancyObject):
def save_history(self, before: dict, after: dict) -> bool:
from assistance.models.knowledge_base_history import KnowledgeBaseHistory
from assistance.models.knowledge_base_history import KnowledgeBaseAuditHistory
history = super().save_history(
before = before,
after = after,
history_model = KnowledgeBaseHistory,
history_model = KnowledgeBaseAuditHistory,
)

View File

@ -6,7 +6,7 @@ from assistance.models.knowledge_base import KnowledgeBaseCategory
class KnowledgeBaseCategoryHistory(
class KnowledgeBaseCategoryAuditHistory(
ModelHistory
):

View File

@ -6,7 +6,7 @@ from assistance.models.knowledge_base import KnowledgeBase
class KnowledgeBaseHistory(
class KnowledgeBaseAuditHistory(
ModelHistory
):

View File

@ -2,9 +2,6 @@ import importlib
from django.apps import apps
from django.db import models
from django.forms import ValidationError
from rest_framework.reverse import reverse
from access.fields import *
from access.models.tenancy import TenancyObject

View File

@ -6,7 +6,7 @@ from rest_framework.exceptions import ValidationError
from access.serializers.organization import TenantBaseSerializer
from access.serializers.teams import TeamBaseSerializer
from app.serializers.user import UserBaseSerializer
from centurion.serializers.user import UserBaseSerializer
from api.serializers import common

View File

@ -1,13 +1,13 @@
from rest_framework.reverse import reverse
from rest_framework import serializers
from rest_framework.exceptions import ParseError, ValidationError
from rest_framework.exceptions import ValidationError
from access.serializers.organization import TenantBaseSerializer
from access.serializers.teams import TeamBaseSerializer
from app.serializers.user import UserBaseSerializer
from centurion.serializers.user import UserBaseSerializer
from api.serializers import common

View File

@ -1,13 +1,6 @@
from rest_framework import serializers
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from assistance.models.knowledge_base_category_notes import KnowledgeCategoryBaseNotes
from core.serializers.model_notes import (
ModelNotes,
ModelNoteBaseSerializer,
ModelNoteModelSerializer,
ModelNoteViewSerializer

View File

@ -1,13 +1,6 @@
from rest_framework import serializers
from assistance.models.knowledge_base_notes import KnowledgeBaseNotes
from api.serializers import common
from app.serializers.user import UserBaseSerializer
from core.serializers.model_notes import (
ModelNotes,
ModelNoteBaseSerializer,
ModelNoteModelSerializer,
ModelNoteViewSerializer

View File

@ -1,7 +1,4 @@
from django.apps import apps
from rest_framework import serializers
from rest_framework.reverse import reverse
from access.serializers.organization import TenantBaseSerializer

View File

@ -1,7 +1,5 @@
from rest_framework import serializers
from app.serializers.user import UserBaseSerializer
from core.models.ticket.ticket_category import TicketCategory
from core.serializers.ticket_depreciated import (
Ticket,

View File

@ -2,7 +2,7 @@ import django
from django.test import TestCase
from assistance.models.knowledge_base_history import KnowledgeBase, KnowledgeBaseHistory
from assistance.models.knowledge_base_history import KnowledgeBase, KnowledgeBaseAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -17,7 +17,7 @@ class History(
model = KnowledgeBase
history_model = KnowledgeBaseHistory
history_model = KnowledgeBaseAuditHistory
@classmethod

View File

@ -9,7 +9,7 @@ from rest_framework.exceptions import ValidationError
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from app.tests.abstract.mock_view import MockView
from centurion.tests.abstract.mock_view import MockView
from assistance.models.knowledge_base import KnowledgeBase
from assistance.serializers.knowledge_base import KnowledgeBaseModelSerializer

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from assistance.models.knowledge_base_category_history import KnowledgeBaseCategory, KnowledgeBaseCategoryHistory
from assistance.models.knowledge_base_category_history import KnowledgeBaseCategory, KnowledgeBaseCategoryAuditHistory
from core.tests.abstract.test_functional_history import HistoryEntriesCommon
@ -13,7 +13,7 @@ class History(
model = KnowledgeBaseCategory
history_model = KnowledgeBaseCategoryHistory
history_model = KnowledgeBaseCategoryAuditHistory
@classmethod

View File

@ -9,7 +9,7 @@ from rest_framework.exceptions import ValidationError
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from app.tests.abstract.mock_view import MockView
from centurion.tests.abstract.mock_view import MockView
from assistance.serializers.knowledge_base_category import KnowledgeBaseCategory, KnowledgeBaseCategoryModelSerializer

View File

@ -14,7 +14,7 @@ from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from app.tests.abstract.model_permissions import ModelPermissions
from centurion.tests.abstract.model_permissions import ModelPermissions
from assistance.models.knowledge_base import KnowledgeBase

View File

@ -4,7 +4,7 @@ import requests
from django.test import TestCase
from app.tests.abstract.models import PrimaryModel
from centurion.tests.abstract.models import PrimaryModel

View File

@ -3,7 +3,7 @@ from django.test import TestCase
from core.tests.abstract.test_unit_model_history_api_v2 import PrimaryModelHistoryAPI
from assistance.models.knowledge_base_history import KnowledgeBase, KnowledgeBaseHistory
from assistance.models.knowledge_base_history import KnowledgeBase, KnowledgeBaseAuditHistory
@ -14,7 +14,7 @@ class ModelHistoryAPI(
audit_model = KnowledgeBase
model = KnowledgeBaseHistory
model = KnowledgeBaseAuditHistory
@classmethod
def setUpTestData(self):

View File

@ -1,6 +1,6 @@
from django.test import TestCase
from app.tests.unit.test_unit_models import (
from centurion.tests.unit.test_unit_models import (
TenancyObjectInheritedCases
)

Some files were not shown because too many files have changed in this diff Show More