File diff 96596dc5ddb2 → 6d5c24e6354f
symposion/proposals/models.py
Show inline comments
...
 
@@ -21,20 +21,20 @@ from symposion.conference.models import Section
 
class ProposalSection(models.Model):
 
    """
 
    configuration of proposal submissions for a specific Section.
 
    
 

 
    a section is available for proposals iff:
 
      * it is after start (if there is one) and
 
      * it is before end (if there is one) and
 
      * closed is NULL or False
 
    """
 
    
 

 
    section = models.OneToOneField(Section)
 
    
 

 
    start = models.DateTimeField(null=True, blank=True)
 
    end = models.DateTimeField(null=True, blank=True)
 
    closed = models.NullBooleanField()
 
    published = models.NullBooleanField()
 
    
 

 
    @classmethod
 
    def available(cls):
 
        now = datetime.datetime.now()
...
 
@@ -43,7 +43,7 @@ class ProposalSection(models.Model):
 
            Q(end__gt=now) | Q(end=None),
 
            Q(closed=False) | Q(closed=None),
 
        )
 
    
 

 
    def is_available(self):
 
        if self.closed:
 
            return False
...
 
@@ -53,7 +53,7 @@ class ProposalSection(models.Model):
 
        if self.end and self.end < now:
 
            return False
 
        return True
 
    
 

 
    def __unicode__(self):
 
        return self.section.name
 

	
...
 
@@ -61,68 +61,77 @@ class ProposalSection(models.Model):
 
class ProposalKind(models.Model):
 
    """
 
    e.g. talk vs panel vs tutorial vs poster
 
    
 

 
    Note that if you have different deadlines, reviewers, etc. you'll want
 
    to distinguish the section as well as the kind.
 
    """
 
    
 

 
    section = models.ForeignKey(Section, related_name="proposal_kinds")
 
    
 

 
    name = models.CharField(_("Name"), max_length=100)
 
    slug = models.SlugField()
 
    
 

 
    def __unicode__(self):
 
        return self.name
 

	
 

	
 
class ProposalBase(models.Model):
 
    
 

 
    objects = InheritanceManager()
 
    
 

 
    kind = models.ForeignKey(ProposalKind)
 
    
 

 
    title = models.CharField(max_length=100)
 
    description = models.TextField(
 
        _("Brief Description"),
 
        max_length=400,  # @@@ need to enforce 400 in UI
 
        help_text="If your proposal is accepted this will be made public and printed in the program. Should be one paragraph, maximum 400 characters."
 
        help_text=_("If your proposal is accepted this will be made public and printed in the "
 
                    "program. Should be one paragraph, maximum 400 characters.")
 
    )
 
    abstract = MarkupField(
 
        _("Detailed Abstract"),
 
        help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit using <a href='http://daringfireball.net/projects/markdown/basics' target='_blank'>Markdown</a>.")
 
        help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit "
 
                    "using <a href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    additional_notes = MarkupField(
 
        blank=True,
 
        help_text=_("Anything else you'd like the program committee to know when making their selection: your past experience, etc. This is not made public. Edit using <a href='http://daringfireball.net/projects/markdown/basics' target='_blank'>Markdown</a>.")
 
        help_text=_("Anything else you'd like the program committee to know when making their "
 
                    "selection: your past experience, etc. This is not made public. Edit using "
 
                    "<a href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    submitted = models.DateTimeField(
 
        default=datetime.datetime.now,
 
        editable=False,
 
    )
 
    speaker = models.ForeignKey("speakers.Speaker", related_name="proposals")
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker", blank=True)
 
    additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker",
 
                                                 blank=True)
 
    cancelled = models.BooleanField(default=False)
 
    
 

 
    def can_edit(self):
 
        return True
 
    
 

 
    @property
 
    def section(self):
 
        return self.kind.section
 
    
 

 
    @property
 
    def speaker_email(self):
 
        return self.speaker.email
 
    
 

 
    @property
 
    def number(self):
 
        return str(self.pk).zfill(3)
 
    
 

 
    def speakers(self):
 
        yield self.speaker
 
        for speaker in self.additional_speakers.exclude(additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED):
 
        speakers = self.additional_speakers.exclude(
 
            additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED)
 
        for speaker in speakers:
 
            yield speaker
 
    
 

 
    def notification_email_context(self):
 
        return {
 
            "title": self.title,
...
 
@@ -135,21 +144,21 @@ reversion.register(ProposalBase)
 

	
 

	
 
class AdditionalSpeaker(models.Model):
 
    
 

 
    SPEAKING_STATUS_PENDING = 1
 
    SPEAKING_STATUS_ACCEPTED = 2
 
    SPEAKING_STATUS_DECLINED = 3
 
    
 

 
    SPEAKING_STATUS = [
 
        (SPEAKING_STATUS_PENDING, _("Pending")),
 
        (SPEAKING_STATUS_ACCEPTED, _("Accepted")),
 
        (SPEAKING_STATUS_DECLINED, _("Declined")),
 
    ]
 
    
 

 
    speaker = models.ForeignKey("speakers.Speaker")
 
    proposalbase = models.ForeignKey(ProposalBase)
 
    status = models.IntegerField(choices=SPEAKING_STATUS, default=SPEAKING_STATUS_PENDING)
 
    
 

 
    class Meta:
 
        db_table = "proposals_proposalbase_additional_speakers"
 
        unique_together = ("speaker", "proposalbase")
...
 
@@ -162,14 +171,15 @@ def uuid_filename(instance, filename):
 

	
 

	
 
class SupportingDocument(models.Model):
 
    
 

 
    proposal = models.ForeignKey(ProposalBase, related_name="supporting_documents")
 
    
 

 
    uploaded_by = models.ForeignKey(User)
 
    created_at = models.DateTimeField(default=datetime.datetime.now)
 
    
 

 
    file = models.FileField(upload_to=uuid_filename)
 
    description = models.CharField(max_length=140)
 

	
 
    def download_url(self):
 
        return reverse("proposal_document_download", args=[self.pk, os.path.basename(self.file.name).lower()])
 
        return reverse("proposal_document_download",
 
                       args=[self.pk, os.path.basename(self.file.name).lower()])