Coverage for core/models/organization.py: 100.00%

47 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-06-06 22:17 +0000

1import uuid 

2 

3from django.db import models, transaction 

4from django.forms.models import model_to_dict 

5from django.utils import timezone 

6 

7from phone_field import PhoneField 

8 

9from core.models import core as core_models 

10from core.models import user as core_user_models 

11from project.models import git_repository as git_repository_models 

12from project.models import project as project_models 

13 

14 

15class OrganizationData(core_models.CoreModel): 

16 """ 

17 Information about an Organization, both past and present. 

18 """ 

19 

20 class Meta: 

21 ordering = ['-created_on', 'name'] 

22 

23 name = models.CharField(max_length=255) 

24 description = models.TextField(max_length=255, blank=True, null=True, default="") 

25 responsible_party_email = models.EmailField(max_length=255) 

26 responsible_party_phone = PhoneField() 

27 address_line_1 = models.CharField(max_length=255) 

28 address_line_2 = models.CharField(max_length=255, blank=True, null=True, default="") 

29 postal_code = models.CharField(max_length=255) 

30 city = models.CharField(max_length=255) 

31 state = models.CharField(max_length=255) 

32 country = models.CharField(max_length=255) 

33 timezone = models.CharField(max_length=255, default=timezone.get_default_timezone_name()) 

34 

35 is_paid = models.BooleanField(default=False) 

36 renewal_date = models.DateField(blank=True, null=True) 

37 number_users_allowed = models.IntegerField(default=5) 

38 

39 

40class OrganizationActiveManager(models.Manager): 

41 """ 

42 Active Organizations are not deleted. 

43 """ 

44 

45 def get_queryset(self): 

46 return super().get_queryset().filter(deleted=None) 

47 

48 

49class Organization(core_models.CoreModel): 

50 """ 

51 An organization. The _real_ inforomation about an Organization is stored in `current` as OrganizationData. 

52 

53 Every time a user or a git repository or a project is added to an organization, a new OrganizationData object is created and the `current` field is updated to reflect the new data. 

54 """ 

55 

56 class Meta: 

57 ordering = ['current__name'] 

58 

59 active_objects = OrganizationActiveManager() 

60 

61 current = models.ForeignKey(OrganizationData, on_delete=models.CASCADE) 

62 

63 # TODO: Activity Tracking for tracking changes to these things 

64 members = models.ManyToManyField(core_user_models.CoreUser, related_name='organizationmembers_set') 

65 git_repositories = models.ManyToManyField(git_repository_models.GitRepository, related_name='organizationgitrepositories_set') 

66 projects = models.ManyToManyField(project_models.Project, related_name='organizationprojects_set') 

67 

68 def update_organization_data(self, user_id: uuid.UUID, new_organization_data: dict) -> 'Organization': 

69 """ 

70 Updates an organization's data. This is a helper function to illustrate the use of `current` retention since we do not delete data. 

71 

72 Args: 

73 user_id (uuid): The ID of the user updating the organization. 

74 organization_data (dictionary): The data to update in an organization. 

75 

76 Returns: 

77 Organization: The updated organization. 

78 """ 

79 

80 with transaction.atomic(): 

81 current_organization_data = model_to_dict(self.current) 

82 current_organization_data.update(new_organization_data) 

83 current_organization_data['created_by_id'] = user_id 

84 new_organization_data = OrganizationData.objects.create(**current_organization_data) 

85 new_organization_data.save() 

86 self.current = new_organization_data 

87 self.save() 

88 

89 return self 

90 

91 def __str__(self) -> str: 

92 return self.current.name