Coverage for apps/organizations/models.py: 99%
93 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-10-09 09:43 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-10-09 09:43 -0600
1from ckeditor.fields import RichTextField
2from django.contrib.sites.models import Site
3from django.core.validators import RegexValidator
4from django.db import models
5from django.utils.html import mark_safe
6from mptt.models import MPTTModel, TreeForeignKey
7from polymorphic.models import PolymorphicModel
9from base.models import RandomSlugModel, TimeStampedModel
11HEX_COLOR_VALIDATOR = RegexValidator(regex="^#[a-fA-F0-9]+$", message="Enter a valid hex color value such as #808080")
14class Organization(RandomSlugModel, Site, MPTTModel):
15 """
16 Model for Organization with MPTT structure
17 """
19 parent = TreeForeignKey("self", on_delete=models.PROTECT, null=True, blank=True, related_name="children")
21 is_active = models.BooleanField(default=True)
23 logo = models.ForeignKey(
24 "organizations.OrganizationImage", on_delete=models.PROTECT, related_name="organizations", null=True, blank=True
25 )
26 primary_color = models.CharField(max_length=9, validators=[HEX_COLOR_VALIDATOR])
27 secondary_color = models.CharField(max_length=9, validators=[HEX_COLOR_VALIDATOR])
28 font = models.ForeignKey("catalogues.Font", on_delete=models.PROTECT, null=True)
29 template = models.ForeignKey("catalogues.Template", on_delete=models.PROTECT, null=True)
30 contact_address = models.EmailField()
31 terms_and_conditions = RichTextField(blank=True, null=True)
32 privacy_policy = RichTextField(blank=True, null=True)
33 cc_domain = models.URLField(default="https://cc1.myxr.com")
34 show_confetti = models.BooleanField(default=True)
36 class ButtonBorderRadius(models.IntegerChoices):
37 NONE = 0, "No"
38 SMALL = 1, "Small"
39 MEDIUM = 2, "Medium"
40 LARGE = 3, "Large"
42 button_border_radius = models.PositiveSmallIntegerField(
43 choices=ButtonBorderRadius.choices, default=ButtonBorderRadius.NONE
44 )
46 def __str__(self):
47 return self.name
49 class Meta:
50 ordering = ["name"]
53class OrganizationSocial(RandomSlugModel):
54 """
55 Model for Organization social networks
56 """
58 organization = models.ForeignKey("organizations.Organization", on_delete=models.CASCADE, related_name="socials")
60 link = models.URLField()
62 class Social(models.TextChoices):
63 FACEBOOK = "FB", "Facebook"
64 TWITTER = "TW", "Twitter"
65 INSTAGRAM = "IG", "Instagram"
67 social = models.CharField(max_length=2, choices=Social.choices)
69 def __str__(self):
70 return self.get_social_display()
72 class Meta:
73 ordering = ["organization"]
74 unique_together = ["organization", "social"]
77class OrganizationUpload(PolymorphicModel, RandomSlugModel, TimeStampedModel):
78 """
79 Base model for Organization upload
80 """
82 organization = models.ForeignKey("organizations.Organization", on_delete=models.CASCADE, related_name="uploads")
84 name = models.CharField(max_length=128, null=True)
86 class Meta:
87 ordering = ["organization", "name"]
90class OrganizationFile(OrganizationUpload):
91 """
92 Model for Organization file
93 """
95 file = models.FileField(upload_to="organization_files/")
97 class Meta:
98 ordering = ["organization", "-created_at"]
101class OrganizationImage(OrganizationUpload):
102 """
103 Model for Organization image
104 """
106 image = models.ImageField(upload_to="organization_files/")
108 class Meta:
109 ordering = ["organization", "-created_at"]
111 def img_preview(self):
112 return mark_safe(f'<img src="{self.image.url}" width="100"')
115class OrganizationCarousel(RandomSlugModel):
116 """
117 Model for Organization carousel images
118 """
120 organization = models.ForeignKey("organizations.Organization", on_delete=models.CASCADE, related_name="carousel")
121 image = models.ForeignKey("organizations.OrganizationImage", on_delete=models.PROTECT)
123 heading = models.CharField(max_length=128)
125 primary_button_cta = models.CharField(max_length=512, null=True, blank=True)
126 primary_button_text = models.CharField(max_length=32, null=True, blank=True)
127 secondary_button_cta = models.CharField(max_length=512, null=True, blank=True)
128 secondary_button_text = models.CharField(max_length=32, null=True, blank=True)
130 order = models.PositiveSmallIntegerField(default=0)
132 class Meta:
133 ordering = ["order"]
134 unique_together = ["organization", "image"]
137class OrganizationSiteLabel(RandomSlugModel):
138 """
139 Model for Organization site labels which will change text
140 """
142 organization = models.ForeignKey("organizations.Organization", related_name="site_labels", on_delete=models.CASCADE)
144 class Labels(models.TextChoices):
145 CAMPAIGNS = "CAMPAIGNS", "Campaigns"
146 REWARDS = "REWARDS", "Rewards"
147 FANS = "FANS", "Fans"
149 label = models.CharField(max_length=16, choices=Labels.choices)
150 singular = models.CharField(max_length=32)
151 plural = models.CharField(max_length=32)
153 class Meta:
154 ordering = ["organization", "label"]
155 unique_together = ["organization", "label"]
157 def __str__(self):
158 return f"{self.label}, {self.singular}, {self.plural}"
161class OrganizationCampaignLabel(RandomSlugModel):
162 """
163 Model for Organization site labels which will change text
164 """
166 organization = models.ForeignKey(
167 "organizations.Organization", related_name="campaign_labels", on_delete=models.CASCADE
168 )
170 class Labels(models.TextChoices):
171 VIDEO_CAMPAIGN = "VideoCampaign", "Video Campaign"
172 GEOLOCATION_CAMPAIGN = "GeolocationCampaign", "Geolocation Campaign"
173 SUBMIT_CAMPAIGN = "SubmitCampaign", "Submit Campaign"
174 QUIZZ_CAMPAIGN = "QuizzCampaign", "Quizz Campaign"
176 label = models.CharField(max_length=32, choices=Labels.choices)
177 singular = models.CharField(max_length=32)
178 plural = models.CharField(max_length=32)
180 class Meta:
181 ordering = ["organization", "label"]
182 unique_together = ["organization", "label"]
184 def __str__(self):
185 return f"{self.label}, {self.singular}, {self.plural}"