def resubmitProposal(proposal, profile, program, timeline): """Resubmits (changes status from 'withdrawn' to 'pending') the specified proposal for the specified student and program. Args: proposal: proposal entity profile: Profile entity of the student to whom the proposal belongs. program: program entity timeline: timeline entity for the program Returns: True, if the proposal is effectively resubmitted (i.e. its status is pending) after this function; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % (timeline.key().name(), program.key().name())) if not canProposalBeResubmitted(proposal, profile, program, timeline): # check if the proposal is not already pending return proposal.status == proposal_model.STATUS_PENDING proposal.status = proposal_model.STATUS_PENDING profile.student_data.number_of_proposals += 1 # TODO(daniel): it should be persisted along with proposal proposal.put() profile.put() return True
def canSubmitProposal(profile, program, timeline): """Tells whether the specified student can submit a proposal for the specified program. Args: profile: Profile entity. program: program entity timeline: timeline entity for the program Returns: True if a new proposal may be submitted; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % (timeline.key().name(), program.key().name())) # check the student application period is open timeline_helper = request_data.TimelineHelper(timeline, None) if not timeline_helper.studentSignup(): return False # check if the student has not reached the limit of apps per program if profile.student_data.number_of_proposals >= program.apps_tasks_limit: return False return True
def canProposalBeResubmitted(proposal, profile, program, timeline): """Tells whether the specified proposal can be resubmitted by the specified student for the given program. Args: proposal: Proposal entity. profile: Profile entity. program: Program entity. timeline: Timeline entity for the program. Returns: True, if the proposal can be resubmitted; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % (timeline.key().name(), program.key().name())) if time_utils.isAfter(timeline.accepted_students_announced_deadline): # students have been accepted / rejected return False elif proposal.status != proposal_model.STATUS_WITHDRAWN: # only withdrawn proposals can be resubmitted return False elif profile.student_data.number_of_proposals >= program.apps_tasks_limit: # student has not reached the limit of proposals per program return False else: return True
def testTimelineNotForProgram(self): # seed a new program and a timeline for it properties = {"key_name": "test_keyname_one"} timeline_one = seeder_logic.seed(timeline_model.Timeline, properties) program_one = seeder_logic.seed(program_model.Program, properties) # seed another program and a timeline for it properties = {"key_name": "test_keyname_two"} timeline_two = seeder_logic.seed(timeline_model.Timeline, properties) program_two = seeder_logic.seed(program_model.Program, properties) result = timeline_logic.isTimelineForProgram(timeline_one.key(), program_two.key()) self.assertFalse(result) result = timeline_logic.isTimelineForProgram(timeline_two.key(), program_one.key()) self.assertFalse(result)
def resubmitProposal(proposal, profile, program, timeline): """Resubmits (changes status from 'withdrawn' to 'pending') the specified proposal for the specified student and program. Args: proposal: proposal entity profile: Profile entity of the student to whom the proposal belongs. program: program entity timeline: timeline entity for the program Returns: True, if the proposal is effectively resubmitted (i.e. its status is pending) after this function; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % ( timeline.key().name(), program.key().name())) if not canProposalBeResubmitted( proposal, profile, program, timeline): # check if the proposal is not already pending return proposal.status == proposal_model.STATUS_PENDING proposal.status = proposal_model.STATUS_PENDING profile.student_data.number_of_proposals += 1 # TODO(daniel): it should be persisted along with proposal proposal.put() profile.put() return True
def canProposalBeResubmitted(proposal, profile, program, timeline): """Tells whether the specified proposal can be resubmitted by the specified student for the given program. Args: proposal: Proposal entity. profile: Profile entity. program: Program entity. timeline: Timeline entity for the program. Returns: True, if the proposal can be resubmitted; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % ( timeline.key().name(), program.key().name())) if time_utils.isAfter(timeline.accepted_students_announced_deadline): # students have been accepted / rejected return False elif proposal.status != proposal_model.STATUS_WITHDRAWN: # only withdrawn proposals can be resubmitted return False elif profile.student_data.number_of_proposals >= program.apps_tasks_limit: # student has not reached the limit of proposals per program return False else: return True
def canSubmitProposal(profile, program, timeline): """Tells whether the specified student can submit a proposal for the specified program. Args: profile: Profile entity. program: program entity timeline: timeline entity for the program Returns: True if a new proposal may be submitted; False otherwise """ # check if given timeline corresponds to the given program if not timeline_logic.isTimelineForProgram(timeline.key(), program.key()): raise ValueError('The specified timeline (key_name: %s) is ' 'not related to program (key_name: %s).' % ( timeline.key().name(), program.key().name())) # check the student application period is open timeline_helper = request_data.TimelineHelper(timeline, None) if not timeline_helper.studentSignup(): return False # check if the student has not reached the limit of apps per program if profile.student_data.number_of_proposals >= program.apps_tasks_limit: return False return True
def testTimelineForProgram(self): # seed a new program and a timeline for it properties = {"key_name": "test_keyname"} timeline = seeder_logic.seed(timeline_model.Timeline, properties) program = seeder_logic.seed(program_model.Program, properties) result = timeline_logic.isTimelineForProgram(timeline.key(), program.key()) self.assertTrue(result)
def testTimelineNotForProgram(self): # seed a new program and a timeline for it properties = {'key_name': 'test_keyname_one'} timeline_one = seeder_logic.seed(timeline_model.Timeline, properties) program_one = seeder_logic.seed(program_model.Program, properties) # seed another program and a timeline for it properties = {'key_name': 'test_keyname_two'} timeline_two = seeder_logic.seed(timeline_model.Timeline, properties) program_two = seeder_logic.seed(program_model.Program, properties) result = timeline_logic.isTimelineForProgram(timeline_one.key(), program_two.key()) self.assertFalse(result) result = timeline_logic.isTimelineForProgram(timeline_two.key(), program_one.key()) self.assertFalse(result)
def testTimelineForProgram(self): # seed a new program and a timeline for it properties = {'key_name': 'test_keyname'} timeline = seeder_logic.seed(timeline_model.Timeline, properties) program = seeder_logic.seed(program_model.Program, properties) result = timeline_logic.isTimelineForProgram(timeline.key(), program.key()) self.assertTrue(result)