models.py 8.42 KB
Newer Older
1
from django.core.exceptions import ValidationError
2
from django.core.validators import RegexValidator, URLValidator
Sébastiaan Versteeg's avatar
Sébastiaan Versteeg committed
3
from django.db import models
Thom Wiggers's avatar
Thom Wiggers committed
4
from django.urls import reverse
5
from django.utils.translation import ugettext, ugettext_lazy as _
6
from tinymce.models import HTMLField
7
8

from utils.translation import ModelTranslateMeta, MultilingualField
9

10
11

class Partner(models.Model):
12
13
    """Model describing partner."""

14
15
    is_active = models.BooleanField(default=False)
    is_main_partner = models.BooleanField(default=False)
16
    is_local_partner = models.BooleanField(default=False)
17
18
19
20
21
22
23
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    link = models.CharField(
        max_length=255,
        blank=True,
        validators=[URLValidator()]
    )
24
    company_profile = HTMLField(blank=True)
25
26
27
28
29
30
31
32
33
34
    logo = models.ImageField(upload_to='public/partners/logos/')
    site_header = models.ImageField(
        upload_to='public/partners/headers/',
        null=True,
        blank=True
    )

    address = models.CharField(max_length=100, validators=[
        RegexValidator(
            regex=(r'^([1-9][e][\s])*([ëéÉËa-zA-Z]'
35
36
                   r'+(([\.][\s])|([\s]))?)+[1-9][0-9]'
                   r'*(([-][1-9][0-9]*)|([\s]?[ëéÉËa-zA-Z]+))?$'),
37
            message=_('Enter a valid address'))
38
39
40
41
    ])
    zip_code = models.CharField(max_length=12, validators=[
        RegexValidator(
            regex=r'^[1-9][0-9]{3}[\s]?[A-Za-z]{2}$',
42
            message=_('Enter a valid zip code')
43
44
45
46
47
        )
    ])
    city = models.CharField(max_length=100)

    def save(self, *args, **kwargs):
48
        """Save a partner and set main/local partners."""
49
        if self.is_main_partner:
50
            self.is_local_partner = False
51
            self._reset_main_partner()
52
53
        if self.is_local_partner:
            self._reset_local_partner()
54
55
56
57

        super(Partner, self).save(*args, **kwargs)

    def _reset_main_partner(self):
58
59
60
61
62
63
        """
        Reset the main partner status.

        If this partner is not main partner,
        remove the main partner status from the main partner.
        """
64
65
66
67
68
69
70
71
        try:
            current_main_partner = Partner.objects.get(is_main_partner=True)
            if self != current_main_partner:
                current_main_partner.is_main_partner = False
                current_main_partner.save()
        except Partner.DoesNotExist:
            pass

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    def _reset_local_partner(self):
        """
        Reset the local partner status.

        If this partner is not local partner,
        remove the local partner status from the local partner.
        """
        try:
            current_local_partner = Partner.objects.get(is_local_partner=True)
            if self != current_local_partner:
                current_local_partner.is_local_partner = False
                current_local_partner.save()
        except Partner.DoesNotExist:
            pass

87
    def __str__(self):
88
        """Return the name of the partner."""
89
90
        return self.name

Thom Wiggers's avatar
Thom Wiggers committed
91
    def get_absolute_url(self):
92
        """Return the url of the partner page."""
93
        return reverse('partners:partner', args=(self.slug,))
Thom Wiggers's avatar
Thom Wiggers committed
94

95
    class Meta:
96
97
        """Meta class for partner model."""

98
        ordering = ('name',)
99

100
101

class PartnerImage(models.Model):
102
103
    """Model to save partner image."""

104
105
106
107
108
    partner = models.ForeignKey(
        Partner,
        on_delete=models.CASCADE,
        related_name="images"
    )
Luuk Scholten's avatar
Luuk Scholten committed
109
    image = models.ImageField(upload_to='public/partners/images/')
110
111

    def __str__(self):
112
        """Return string representation of partner name."""
113
        return ugettext('image of {}').format(self.partner.name)
114
115
116


class VacancyCategory(models.Model, metaclass=ModelTranslateMeta):
117
118
    """Model describing vacancy categories."""

119
120
121
122
    name = MultilingualField(models.CharField, max_length=30)
    slug = models.SlugField()

    def __str__(self):
123
        """Return the category name."""
124
125
126
        return self.name

    class Meta:
127
128
        """Meta class for vacancy category model."""

129
        verbose_name_plural = _('Vacancy Categories')
130
131
132


class Vacancy(models.Model):
133
134
    """Model describing vacancies."""

135
136
137
138
139
140
141
    title = models.CharField(
        _("title"),
        max_length=255
    )
    description = HTMLField(
        _("description")
    )
142
    link = models.CharField(
143
        _("link"),
144
145
146
147
148
149
150
        max_length=255,
        blank=True,
        validators=[URLValidator()]
    )

    partner = models.ForeignKey(
        Partner,
151
        verbose_name=_("partner"),
152
153
154
        on_delete=models.PROTECT,
        null=True,
        blank=True,
155
156
        help_text=_("When you use a partner, the company name and logo "
                    "below will not be used.")
157
158
    )

159
160
161
162
163
    company_name = models.CharField(
        _("company name"),
        max_length=255,
        blank=True
    )
164
    company_logo = models.ImageField(
165
        _("company logo"),
166
167
168
169
170
171
172
173
        upload_to='public/partners/vacancy-logos/',
        null=True,
        blank=True
    )

    categories = models.ManyToManyField(VacancyCategory, blank=True)

    def get_company_name(self):
174
        """Return company or partner name."""
175
176
177
178
179
        if self.partner:
            return self.partner.name
        return self.company_name

    def get_company_logo(self):
180
        """Return company or partner logo."""
181
182
183
184
185
        if self.partner:
            return self.partner.logo
        return self.company_logo

    def __str__(self):
186
        """Return vacancy partner or company and title."""
187
        return '{} — {}'.format(self.get_company_name(), self.title)
188

189
    def get_absolute_url(self):
190
        """Return partner or vacancy url."""
191
192
193
194
195
        url = reverse('partners:vacancies')
        if self.partner:
            url = reverse('partners:partner', args=(self.partner.slug,))
        return '{}#vacancy-{}'.format(url, self.pk)

Tom van Bussel's avatar
Tom van Bussel committed
196
    def clean(self):
197
        """Validate the vacancy."""
Tom van Bussel's avatar
Tom van Bussel committed
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
        super().clean()
        errors = {}

        msg = _('If no partner is used then both a company name and logo are '
                'required.')
        if not self.partner and self.company_name and not self.company_logo:
            errors.update({'company_logo': msg})
        if not self.partner and not self.company_name and self.company_logo:
            errors.update({'company_name': msg})

        msg = _('Either select a partner or provide a company name and logo.')
        if self.partner and (self.company_name or self.company_logo):
            errors.update({'partner': msg})
            if self.company_name:
                errors.update({'company_name': msg})
            if self.company_logo:
                errors.update({'company_logo': msg})
        if (not self.partner and not self.company_name and
                not self.company_logo):
            errors.update({
                'partner': msg,
                'company_name': msg,
                'company_logo': msg,
            })

        if errors:
            raise ValidationError(errors)

226
227
228
229
230
    class Meta:
        """Meta class for vacancy model."""

        verbose_name_plural = _('Vacancies')

231
232

class PartnerEvent(models.Model, metaclass=ModelTranslateMeta):
233
234
    """Model describing partner event."""

235
236
    partner = models.ForeignKey(
        Partner,
237
        verbose_name=_("partner"),
238
        on_delete=models.CASCADE,
239
240
241
        related_name="events",
        blank=True,
        null=True
242
243
    )

244
245
    other_partner = models.CharField(max_length=255, blank=True)

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    title = MultilingualField(
        models.CharField,
        _("title"),
        max_length=100
    )

    description = MultilingualField(
        models.TextField,
        _("description")
    )

    location = MultilingualField(
        models.CharField,
        _("location"),
        max_length=255,
    )

    start = models.DateTimeField(_("start time"))

    end = models.DateTimeField(_("end time"))

    url = models.URLField(_("website"))

    published = models.BooleanField(_("published"), default=False)

271
    def clean(self):
272
        """Validate the partner event."""
273
274
275
276
277
278
279
280
281
282
283
284
285
        super().clean()
        errors = {}
        if ((not self.partner and not self.other_partner) or
                (self.partner and self.other_partner)):
            errors.update(
                {'partner': _("Please select or enter "
                              "a partner for this event."),
                 'other_partner': _("Please select or enter "
                                    "a partner for this event.")})

        if errors:
            raise ValidationError(errors)

286
    def __str__(self):
287
        """Return the event title."""
288
        return self.title