| 65 | |
| 66 | |
| 67 | class Organisation(LifecycleModelMixin, SoftDeleteExportableModel): # type: ignore[misc] |
| 68 | name = models.CharField(max_length=2000) |
| 69 | has_requested_features = models.BooleanField(default=False) |
| 70 | webhook_notification_email = models.EmailField(null=True, blank=True) |
| 71 | created_date = models.DateTimeField("DateCreated", auto_now_add=True) |
| 72 | alerted_over_plan_limit = models.BooleanField(default=False) |
| 73 | stop_serving_flags = models.BooleanField( |
| 74 | default=False, |
| 75 | help_text="Enable this to cease serving flags for this organisation.", |
| 76 | ) |
| 77 | restrict_project_create_to_admin = models.BooleanField(default=False) |
| 78 | persist_trait_data = models.BooleanField( |
| 79 | default=settings.DEFAULT_ORG_STORE_TRAITS_VALUE, |
| 80 | help_text="Disable this if you don't want Flagsmith " |
| 81 | "to store trait data for this org's identities.", |
| 82 | ) |
| 83 | block_access_to_admin = models.BooleanField( |
| 84 | default=False, |
| 85 | help_text="Enable this to block all the access to admin " |
| 86 | "interface for the organisation", |
| 87 | ) |
| 88 | feature_analytics = models.BooleanField( |
| 89 | default=False, help_text="Record feature analytics in InfluxDB" |
| 90 | ) |
| 91 | force_2fa = models.BooleanField(default=False) |
| 92 | |
| 93 | class Meta: |
| 94 | ordering = ["id"] |
| 95 | |
| 96 | def __str__(self): # type: ignore[no-untyped-def] |
| 97 | return "Org %s (#%s)" % (self.name, self.id) |
| 98 | |
| 99 | # noinspection PyTypeChecker |
| 100 | def get_unique_slug(self): # type: ignore[no-untyped-def] |
| 101 | return str(self.id) + "-" + self.name |
| 102 | |
| 103 | @property |
| 104 | def num_seats(self) -> int: |
| 105 | return self.users.count() |
| 106 | |
| 107 | def has_paid_subscription(self) -> bool: |
| 108 | # Includes subscriptions that are canceled. |
| 109 | # See is_paid for active paid subscriptions only. |
| 110 | return hasattr(self, "subscription") and bool(self.subscription.subscription_id) |
| 111 | |
| 112 | def has_subscription_information_cache(self) -> bool: |
| 113 | return hasattr(self, "subscription_information_cache") and bool( |
| 114 | self.subscription_information_cache |
| 115 | ) |
| 116 | |
| 117 | @property |
| 118 | def is_paid(self): # type: ignore[no-untyped-def] |
| 119 | return ( |
| 120 | self.has_paid_subscription() and self.subscription.cancellation_date is None |
| 121 | ) |
| 122 | |
| 123 | def has_enterprise_subscription(self) -> bool: |
| 124 | return self.is_paid and self.subscription.is_enterprise |
no outgoing calls
searching dependent graphs…