Пример #1
0
class Survey(models.Model):
    """
    The Labour Manager may have their Workers fill in a Survey some time after signing up.
    The driving use case for these Surveys is to ask for shift wishes some time before the event.
    A Survey requires a Model and a Form. The Model is requested to return an instance via
    Model.for_signup(signup) and it is passed to the Form via
    initialize_form(Form, request, instance=instance, event=event).
    """

    event = models.ForeignKey('core.Event', on_delete=models.CASCADE)
    slug = models.CharField(**NONUNIQUE_SLUG_FIELD_PARAMS)
    title = models.CharField(
        max_length=255,
        verbose_name=_('Title'),
        help_text=_('Will be displayed at the top of the survey page.'),
    )
    description = models.TextField(
        verbose_name=_('Description'),
        help_text=_('Will be displayed at the top of the survey page.'),
    )

    active_from = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('Active from'),
    )

    active_until = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('Active until'),
    )

    form_class_path = models.CharField(
        max_length=255,
        verbose_name=_('Form path'),
        help_text=_(
            'A reference to the form that is used as the survey form.'),
    )

    form_class = code_property('form_class_path')

    override_does_not_apply_message = models.TextField(
        default='',
        verbose_name=_('Message when denied access'),
        help_text=_(
            "This message will be shown to the user when they attempt to access a query they don't"
            "have access to."),
    )

    def __str__(self):
        return self.title

    @property
    def is_active(self):
        return is_within_period(self.active_from, self.active_until)

    @property
    def does_not_apply_message(self):
        if self.override_does_not_apply_message:
            return self.override_does_not_apply_message
        else:
            return _('This survey does not apply to you.')

    def admin_is_active(self):
        return self.is_active

    admin_is_active.short_description = _('Active')
    admin_is_active.boolean = True

    class Meta:
        verbose_name = _('Survey')
        verbose_name_plural = _('Surveys')
        unique_together = [
            ('event', 'slug'),
        ]
Пример #2
0
class Subscription(models.Model):
    """
    Channels:

    * `email` - e-mail will be sent to `user`
    * `callback` - the callback specified in `callback_code` will be called (for testing mostly).
    """

    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    entry_type = models.CharField(max_length=255)
    channel = models.CharField(
        max_length=max(len(key) for (key, label) in CHANNEL_CHOICES),
        default='email',
        choices=CHANNEL_CHOICES,
    )
    active = models.BooleanField(default=True)

    event_filter = models.ForeignKey(
        'core.Event',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        verbose_name=_('Event filter'),
        help_text=
        _('When specified, only entries related to this event will match the subscription.'
          ),
    )
    event_survey_filter = models.ForeignKey(
        'surveys.EventSurvey',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        verbose_name=_('Event survey filter'),
        help_text=
        _('When specified, only entries related to this EventSurvey will match the subscription.'
          ),
    )
    job_category_filter = models.ForeignKey(
        'labour.JobCategory',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        verbose_name=_('Job category filter'),
        help_text=
        _('When specified, only entries related to this JobCategory will match the subscription.'
          ),
    )

    callback_code = models.CharField(
        max_length=255,
        blank=True,
        default='',
        verbose_name=_('Callback function'),
        help_text=
        _('Code path to a callback function. Only used when channel=callback. Eg. event_log.tests:test_callback.'
          ),
    )

    callback = code_property('callback_code')

    def send_update_for_entry(self, entry):
        assert self.active

        if 'background_tasks' in settings.INSTALLED_APPS:
            from ..tasks import subscription_send_update_for_entry
            subscription_send_update_for_entry.delay(self.id, entry.id)
        else:
            self._send_update_for_entry(entry)

    def _send_update_for_entry(self, entry):
        channels[self.channel].send_update_for_entry(self, entry)

    def clean(self):
        if self.callback_code and self.channel != 'callback':
            raise ValidationError(
                _('The callback field must only be used when the channel is "callback".'
                  ))

    @property
    def recipient_name_and_email(self):
        full_name = self.user.get_full_name()
        if full_name:
            return '{full_name} <{email}>'.format(
                full_name=full_name,
                email=self.user.email,
            )
        else:
            return self.user.email

    @classmethod
    def get_or_create_dummy(cls, entry_type=None, **kwargs):
        from .entry_type_metadata import EntryTypeMetadata
        from core.models import Person

        if entry_type is None:
            entry_type, unused = EntryTypeMetadata.get_or_create_dummy()
            entry_type = entry_type.name

        person, unused = Person.get_or_create_dummy()

        attrs = dict(
            entry_type=entry_type,
            user=person.user,
        )

        attrs.update(kwargs)

        return cls.objects.get_or_create(**attrs)

    class Meta:
        verbose_name = _('subscription')
        verbose_name_plural = _('subscriptions')
        index_together = [
            ('entry_type', 'active'),
        ]