blob: 13137f42d330c141215c88bdec6c8674f850bb02 [file] [log] [blame]
# Copyright 2014 the Melange authors.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module contains the proposal related models."""
from google.appengine.ext import ndb
from google.appengine.ext.ndb import msgprop
from melange.appengine import db as melange_db
from protorpc import messages
class Visibility(messages.Enum):
"""Class that enumerates possible visibility types for proposals."""
#: Content of the proposal is visible to everyone.
#: Content of the proposal is visible to members of the organization
#: to which the proposal has been submitted.
#: Content of the proposal is visible to all registered students of the
#: current program.
class Status(messages.Enum):
"""Class that enumerates possible statuses of proposals."""
#: The proposal has been submitted to the program.
#: The proposal has been accepted into the program and has been turned
#: into a student project.
#: This proposal has been rejected.
# TODO(daniel): this status should be removed.
#: The proposal has been ignored by the organization.
#: Please DO NOT USE.
#: The proposal has been withdrawn by the student.
class Score(ndb.Model):
"""Model to store information on a single score for the proposal."""
#: Required field storing a reference to the profile who is an author
#: if the score.
author = ndb.KeyProperty(required=True)
#: Required field storing numeric value associated with the score, i.e.
#: number of points given to the proposal.
value = ndb.IntegerProperty(required=True)
class Proposal(ndb.Model):
"""Model that represents a proposal that is submitted to an organization
by a student participating in the program.
melange.models.profile.Profile (of the student who owns the proposal)
#: Required field indicating the title of the proposal.
title = ndb.StringProperty(required=True)
#: Required field storing a short description of the proposal.
abstract = ndb.TextProperty(required=True)
#: Required field storing actual content of the proposal.
content = ndb.TextProperty(required=True)
#: Optional field storing URL linking to additional resources
#: associated with the proposal.
additional_info = ndb.StringProperty(validator=melange_db.link_validator)
#: Required field determining who is eligible to see the proposal.
visibility = msgprop.EnumProperty(
Visibility, required=True, default=Visibility.ORG_MEMBER)
#: List of mentors associated with the proposal. They will be assigned as
#: mentors if the proposal is turned into a project.
mentors = ndb.KeyProperty(repeated=True)
#: Field determining whether the proposal has currently at least one
#: mentor assigned.
has_mentor = ndb.ComputedProperty(lambda self: bool(self.mentors))
#: List of organization members who are possible mentors for the proposal.
possible_mentors = ndb.KeyProperty(repeated=True)
#: List of scores that have been given to the proposal.
scores = ndb.StructuredProperty(Score, repeated=True)
#: Sum of all scores for this proposal
total_score = ndb.ComputedProperty(
lambda self: sum(score.value for score in self.scores))
#: Field telling whether the student is eligible to edit the proposal
#: after the proposal submission deadline.
is_editable_post_deadline = ndb.BooleanProperty(default=False)
#: Field telling whether the proposal should be accepted and turned
#: into a student project.
accept_as_project = ndb.BooleanProperty(default=False)
#: Field storing status of the proposal.
status = msgprop.EnumProperty(Status, required=True, default=Status.PENDING)
#: Field telling whether the proposal has been ignored by the organization.
is_ignored = ndb.BooleanProperty(default=False)
#: Field storing the organization to which the proposal has been submitted.
organization = ndb.KeyProperty(required=True)
#: Field storing the program for which the proposal has been submitted.
program = ndb.KeyProperty(required=True)
#: Field storing the date when the proposal was initially created.
created_on = ndb.DateTimeProperty(required=True, auto_now_add=True)
#: Field storing the date when the proposal was modified for the last time.
modified_on = ndb.DateTimeProperty(required=True, auto_now=True)
#: Values for additional fields (defined by the organization) for
#: this proposal.
extra_data = ndb.JsonProperty()
def count_scores(self):
"""Returns number of scores for this proposal."""
return len(self.scores)
def average_score(self):
"""Returns average score for this proposal. If no scores are currently
defined, None is returned
if not self.scores:
return None
return float(self.total_score) / float(len(self.scores))